diff --git a/.github/workflows/ghcr-publish.yml b/.github/workflows/ghcr-publish.yml new file mode 100644 index 0000000..0ff9210 --- /dev/null +++ b/.github/workflows/ghcr-publish.yml @@ -0,0 +1,76 @@ +name: GHCR Publish + +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. + +on: + workflow_dispatch: + push: + branches: [ "**" ] + # Publish semver tags as releases. + tags: [ 'v*' ] + #schedule: + # - cron: '30 15 * * *' + #pull_request: + # branches: [ main ] + +env: + # github.repository as / + IMAGE_NAME: ${{ github.repository }} + REGISTRY: "ghcr.io" + + +jobs: + build: + + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + # This is used to complete the identity challenge + # with sigstore/fulcio when running outside of PRs. + id-token: write + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Setup Docker buildx + uses: docker/setup-buildx-action@v2 + + # Login against a Docker registry except on PR + # https://github.com/docker/login-action + - name: Log into registry ${{ env.REGISTRY }} + if: github.event_name != 'pull_request' + uses: docker/login-action@v2 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + # Extract metadata (tags, labels) for Docker + # https://github.com/docker/metadata-action + - name: Extract Docker metadata + id: meta + uses: docker/metadata-action@v4 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + "type=raw,value={{date 'X'}}-{{tag}}{{branch}}-{{sha}}" + "type=raw,value=latest" + "type=ref,event=tag" + "type=semver,pattern=v{{major}}" + "type=ref,event=branch" + + # Build and push Docker image with Buildx (don't push on PR) + # https://github.com/docker/build-push-action + - name: Build and push Docker image + id: build-and-push + uses: docker/build-push-action@v3 + with: + context: "{{defaultContext}}" + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..75f5f0a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,13 @@ +FROM python:3 + +ENV TZ=America/Chicago +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone + +WORKDIR /srv +COPY cleanup/* /srv/ +COPY requirements.txt /srv +RUN python -m pip install -r /srv/requirements.txt +RUN ln -s /home/.netrc /root/.netrc +RUN ln -s /home/.atlassian-tools-config.ini /root/.atlassian-tools-config.ini + +CMD ["bash"] diff --git a/cleanup/bulk_delete_projects.py b/cleanup/bulk_delete_projects.py new file mode 100644 index 0000000..f30045e --- /dev/null +++ b/cleanup/bulk_delete_projects.py @@ -0,0 +1,76 @@ +# adapted from https://coderoman.com/2021/08/04/bulk-delete-projects-in-jira/ +import requests +import pprint +from requests.auth import HTTPBasicAuth +import configparser +import pathlib +import netrc + + +def getJson(url): + r = requests.request( + "GET", + url, + headers={"Accept": "application/json"}, + auth=auth + ) + return r.json() + +def deleteProject(id): + r = requests.request( + "DELETE", + domain + "/rest/api/3/project/" + id, + auth=auth + ) + return r.text + + +def get_all_projects(): + json = getJson( f'{baseurl}/project' ) + pprint.pprint( json ) + + +# get server from local cfg file +cfg_file = Path.home() / '.atlasstian-tools-config.ini' +config = configparser.ConfigParser() +config.read( cfg_file ) +server = config['server']['server'] + +# get credentials from local netrc +n = netrc.netrc() +( admin_user, account, admin_token ) = cfg.authenticators( server ) + +# create web parts +auth = HTTPBasicAuth(admin_user, admin_token) +baseurl = f'https://{server}/rest/api/3' + +project_query = "PROJECTS_I_WANT_TO_DELETE" + + + +# search_url = domain + "/rest/api/3/project/search?query=" + project_query +# json = getJson(search_url, auth) + +# projectIds = [] + +# # append results across all pages, while there's still a nextPage, to projectIds array +# while "nextPage" in json: +# nextUrl = json["nextPage"] +# for searchResult in json['values']: +# # optional safety check to make sure the right project is being added to the deletion array +# # if "PROJECT_NAME_I_INTEND_TO_DELETE" in searchResult["name"]: +# projectIds.append(searchResult['id']) +# print("Number of project IDs found matching the search query: " + str(len(projectIds))) +# json = getJson(nextUrl, auth) + +# # append a single page, or the last page of results, to projectIds array +# for searchResult in json['values']: +# # optional safety check to make sure the right project is being added to the deletion array +# # if "PROJECT_NAME_I_INTEND_TO_DELETE" in searchResult["name"]: +# projectIds.append(searchResult['id']) +# print("Number of project IDs found matching the search query: " + str(len(projectIds))) + +# # delete projects in projectIds array +# for index, id in enumerate(projectIds): +# print("Deleting project " + id + ". Projects remaining: " + str(len(projectIds)-index)) +# print(deleteProject(id, auth))