Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 0 additions & 33 deletions .github/workflows/publish-docker.yml

This file was deleted.

63 changes: 0 additions & 63 deletions .github/workflows/publish-pypi.yml

This file was deleted.

161 changes: 114 additions & 47 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -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
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