Skip to content

Release

Release #436

Workflow file for this run

name: Release
# Trunk-based continuous deployment
# Every push to main with feat:/fix:/perf: triggers a release
# Staging deploys immediately, Production requires approval
on:
workflow_run:
workflows: ["CI/CD"]
types: [completed]
branches: [main]
concurrency:
group: release-${{ github.ref }}
cancel-in-progress: false
permissions:
contents: write
issues: write
pull-requests: write
packages: write
jobs:
release:
if: ${{ github.event.workflow_run.conclusion == 'success' }}
runs-on: ubuntu-latest
outputs:
new_version: ${{ steps.release.outputs.new_release_version }}
released: ${{ steps.release.outputs.new_release_published }}
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
ref: ${{ github.event.workflow_run.head_sha }}
token: ${{ secrets.GH_PAT }}
persist-credentials: false
fetch-depth: 0
- name: Create Release
id: release
uses: cycjimmy/semantic-release-action@v4
with:
extra_plugins: |
@semantic-release/commit-analyzer
@semantic-release/release-notes-generator
@semantic-release/github
conventional-changelog-conventionalcommits
env:
GITHUB_TOKEN: ${{ secrets.GH_PAT }}
- name: Summary
if: steps.release.outputs.new_release_published == 'true'
run: |
echo "## 🚀 Released v${{ steps.release.outputs.new_release_version }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "- **Staging**: Deploying automatically" >> $GITHUB_STEP_SUMMARY
echo "- **Production**: Waiting for approval" >> $GITHUB_STEP_SUMMARY
# Retag Docker images with semantic version
tag-images:
needs: release
if: needs.release.outputs.released == 'true'
runs-on: ubuntu-latest
steps:
- name: Login to GitHub Container Registry
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Retag Images
run: |
VERSION="${{ needs.release.outputs.new_version }}"
SHA="${{ github.event.workflow_run.head_sha }}"
IMAGES=("webapp" "application-server" "intelligence-service" "webhook-ingest" "agent-claude-code" "agent-opencode")
for img in "${IMAGES[@]}"; do
FULL_IMAGE="ghcr.io/ls1intum/hephaestus/$img"
echo "Checking for $FULL_IMAGE:$SHA..."
# Retry up to 24 times (2 minutes) with 5s interval
RETRIES=24
COUNT=0
until docker buildx imagetools inspect "$FULL_IMAGE:$SHA" > /dev/null 2>&1; do
COUNT=$((COUNT+1))
if [ "$COUNT" -ge "$RETRIES" ]; then
echo "::error::Image $FULL_IMAGE:$SHA not found after $((RETRIES*5)) seconds"
exit 1
fi
echo "Image not found yet. Retrying in 5s... ($COUNT/$RETRIES)"
sleep 5
done
echo "Retagging $FULL_IMAGE:$SHA → $FULL_IMAGE:$VERSION"
docker buildx imagetools create -t "$FULL_IMAGE:$VERSION" "$FULL_IMAGE:$SHA"
done
# Deploy to staging automatically after images are tagged
deploy-staging:
needs: [release, tag-images]
if: needs.release.outputs.released == 'true'
uses: ./.github/workflows/deploy-staging.yml
with:
image-tag: ${{ needs.release.outputs.new_version }}
deploy-app: true
deploy-core: false
deploy-proxy: false
secrets: inherit
# Trigger production deployment (approval happens in deploy-prod.yml)
deploy-production:
needs: [release, deploy-staging]
if: needs.release.outputs.released == 'true'
runs-on: ubuntu-latest
steps:
- name: Trigger Production Deploy
uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7
with:
github-token: ${{ secrets.GH_PAT }}
script: |
await github.rest.actions.createWorkflowDispatch({
owner: context.repo.owner,
repo: context.repo.repo,
workflow_id: 'deploy-prod.yml',
ref: 'main',
inputs: {
'image-tag': '${{ needs.release.outputs.new_version }}',
'deploy-app': 'true',
'deploy-core': 'false',
'deploy-proxy': 'false'
}
});
console.log('✅ Production deployment triggered for v${{ needs.release.outputs.new_version }}');
- name: Summary
run: |
echo "## 🚀 Production Deployment Triggered" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Version **v${{ needs.release.outputs.new_version }}** deployment to production has been triggered." >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "⏳ Waiting for approval in the [Deploy to Production](https://github.com/${{ github.repository }}/actions/workflows/deploy-prod.yml) workflow." >> $GITHUB_STEP_SUMMARY