diff --git a/.github/workflows/publish-docker.yml b/.github/workflows/publish-docker.yml deleted file mode 100644 index 78e61b8..0000000 --- a/.github/workflows/publish-docker.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: Publish Docker image - -on: - workflow_run: - workflows: ["CI"] - types: - - completed - branches: - - main - release: - types: [published] - -jobs: - build-and-push: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - name: Login to DockerHub - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: Build and push Docker image - uses: docker/build-push-action@v5 - with: - context: . - push: true - tags: stackhawk/stackhawk-mcp:latest,stackhawk/stackhawk-mcp:${{ github.ref_name }} - platforms: linux/amd64,linux/arm64 \ No newline at end of file diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml deleted file mode 100644 index 150b132..0000000 --- a/.github/workflows/publish-pypi.yml +++ /dev/null @@ -1,63 +0,0 @@ -name: Publish Python 🐍 distribution 📦 to PyPI - -on: - workflow_run: - workflows: ["CI"] - types: - - completed - branches: - - main - release: - types: [published] - -permissions: - contents: write - id-token: write - -jobs: - build-and-publish: - runs-on: ubuntu-latest - environment: pypi - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: '3.11' - - name: Install build dependencies - run: | - python -m pip install --upgrade pip - pip install build bumpver - - name: Bump minor version with bumpver - if: github.ref == 'refs/heads/main' - run: bumpver update --minor --commit - - name: Get version from pyproject.toml - id: get_version - run: | - VERSION=$(grep '^version = ' pyproject.toml | head -1 | cut -d '"' -f2) - echo "version=$VERSION" >> $GITHUB_OUTPUT - - name: Set up git for pushing - if: github.ref == 'refs/heads/main' - run: | - git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git - - name: Create and push tag for new version - if: github.ref == 'refs/heads/main' - run: | - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - git tag v${{ steps.get_version.outputs.version }} - git push origin v${{ steps.get_version.outputs.version }} - - name: Push version bump commit - if: github.ref == 'refs/heads/main' - run: | - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - git push - - name: Build package - run: | - python -m build - - name: Publish to PyPI - uses: pypa/gh-action-pypi-publish@release/v1 - # No password needed! Uses OIDC trusted publisher \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 958ea8b..b507773 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,60 +1,127 @@ -name: Release Approval +name: Release on: - workflow_dispatch: - inputs: - tag: - description: 'Release tag (e.g., v0.1.0)' - required: true - release_title: - description: 'Release title' - required: false - release_notes: - description: 'Release notes (optional)' - required: false + release: + types: [published] + +permissions: + contents: write + id-token: write jobs: - approve-and-release: + approval: + name: Manual Approval runs-on: ubuntu-latest steps: + - name: Generate GitHub App token + id: generate_token + uses: tibdex/github-app-token@v2 + with: + app_id: ${{ secrets.HAWKY_APP_ID }} + private_key: ${{ secrets.HAWKY_APP_PRIVATE_KEY }} - name: Wait for manual approval uses: trstringer/manual-approval@v1 with: - secret: ${{ github.TOKEN }} + secret: ${{ steps.generate_token.outputs.token }} + issue-title: "Release Approval for ${{ github.ref_name }}" + issue-body: "Please approve this release to publish to PyPI and Docker." approvers: sgerlach,kcberg,danielhopkins,clamey,Bwvolleyball minimum-approvals: 1 + mode: issue fail-on-denial: true - - name: Check CI status for this commit - id: check_ci - uses: actions/github-script@v7 - with: - script: | - const commit = context.sha; - const { data: runs } = await github.rest.actions.listWorkflowRunsForRepo({ - owner: context.repo.owner, - repo: context.repo.repo, - branch: 'main', - event: 'push', - status: 'completed', - per_page: 10 - }); - const ciRun = runs.workflow_runs.find(run => run.name === 'CI' && run.head_sha === commit); - if (!ciRun) { - core.setFailed('No CI workflow run found for this commit.'); - } else if (ciRun.conclusion !== 'success') { - core.setFailed(`CI workflow did not succeed (status: ${ciRun.conclusion}). Release aborted.`); - } - - name: Create GitHub Release - if: steps.check_ci.outcome == 'success' - uses: softprops/action-gh-release@v1 - with: - tag_name: ${{ github.event.inputs.tag }} - name: ${{ github.event.inputs.release_title || github.event.inputs.tag }} - body: ${{ github.event.inputs.release_notes }} - draft: false - prerelease: false -permissions: - actions: read - issues: write - contents: write \ No newline at end of file + tag: + name: Confirm Tag Exists + runs-on: ubuntu-latest + needs: approval + steps: + - name: Generate GitHub App token + id: generate_token + uses: tibdex/github-app-token@v2 + with: + app_id: ${{ secrets.HAWKY_APP_ID }} + private_key: ${{ secrets.HAWKY_APP_PRIVATE_KEY }} + - name: Confirm release tag exists + run: | + echo "Release tag is ${{ github.ref }}" + + publish-pypi: + name: Publish to PyPI + runs-on: ubuntu-latest + environment: pypi + needs: tag + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ github.ref }} + fetch-depth: 0 + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.11' + - name: Install build dependencies + run: | + python -m pip install --upgrade pip + pip install build bumpver + - name: Generate GitHub App token + id: generate_token + uses: tibdex/github-app-token@v2 + with: + app_id: ${{ secrets.HAWKY_APP_ID }} + private_key: ${{ secrets.HAWKY_APP_PRIVATE_KEY }} + - name: Set up git for pushing + run: | + git remote set-url origin https://x-access-token:${{ steps.generate_token.outputs.token }}@github.com/${{ github.repository }}.git + - name: Set git user for HawkyMcBuilderFace bot + run: | + git config user.name "HawkyMcBuilderFace[bot]" + git config user.email "222944+HawkyMcBuilderFace[bot]@users.noreply.github.com" + - name: Set version from tag + run: | + TAG_NAME=${GITHUB_REF#refs/tags/v} + bumpver update --set-version $TAG_NAME --commit + - name: Build package + run: | + python -m build + - name: Publish to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + # No password needed! Uses OIDC trusted publisher + + publish-docker: + name: Publish Docker image + runs-on: ubuntu-latest + needs: tag + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ github.ref }} + fetch-depth: 0 + - name: Generate GitHub App token + id: generate_token + uses: tibdex/github-app-token@v2 + with: + app_id: ${{ secrets.HAWKY_APP_ID }} + private_key: ${{ secrets.HAWKY_APP_PRIVATE_KEY }} + - name: Set up git for pushing + run: | + git remote set-url origin https://x-access-token:${{ steps.generate_token.outputs.token }}@github.com/${{ github.repository }}.git + - name: Set git user for HawkyMcBuilderFace bot + run: | + git config user.name "HawkyMcBuilderFace[bot]" + git config user.email "222944+HawkyMcBuilderFace[bot]@users.noreply.github.com" + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Login to DockerHub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Build and push Docker image + uses: docker/build-push-action@v5 + with: + context: . + push: true + tags: stackhawk/stackhawk-mcp:latest,stackhawk/stackhawk-mcp:${{ github.ref_name }} + platforms: linux/amd64,linux/arm64 \ No newline at end of file