Publish New Release #3
Workflow file for this run
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Publish New Release | |
on: | |
workflow_dispatch: | |
# Ensure only one instance of either this or the deploy workflow is running at a time | |
# This ensures that we don't put production into an inconsistent state | |
concurrency: | |
group: 'prod-deployment' | |
jobs: | |
deploy: | |
runs-on: ubuntu-latest | |
permissions: | |
packages: write | |
contents: write # Write is required to create/update releases | |
steps: | |
- name: Ensure pre-requisites for deployment are met | |
id: validate_deployment | |
uses: actions/github-script@v7 | |
with: | |
github-token: ${{ secrets.GITHUB_TOKEN }} | |
script: | | |
const { owner, repo } = context.repo; | |
/* | |
* We should only need to load 1 release here, as pending should be at the top of the list. | |
* We're loading a few extras here in case we get into a weird state. | |
*/ | |
const PAGE_SIZE = 10; | |
const releases = await github.rest.repos.listReleases({ | |
owner, | |
repo, | |
per_page: PAGE_SIZE, | |
}); | |
const pendingReleases = releases.data.filter((release) => release.prerelease); | |
if (pendingReleases.length > 1) { | |
throw new Error( | |
`Found more than one pending release: ${pendingReleases | |
.map((release) => release.tag_name) | |
.join(", ")}` | |
); | |
} | |
const targetRelease = pendingReleases.find( | |
(release) => release.tag_name === "${{github.ref_name}}" | |
); | |
if (!targetRelease) { | |
throw new Error(`No pending release found for tag: ${{github.ref_name}}`); | |
} | |
console.log( | |
`Found pending release, proceeding with deployment: ${targetRelease.html_url}` | |
); | |
return targetRelease.id; | |
- name: Log in to the Container registry | |
uses: docker/login-action@v3 | |
with: | |
registry: ghcr.io | |
username: ${{ github.actor }} | |
password: ${{ secrets.GITHUB_TOKEN }} | |
- name: Deploy to Production | |
# To emulate deployments here we are simply shifting the latest tag to the appropriate docker image. | |
# In a real world scenario, you would replace this with your actual deployment steps. | |
run: | | |
docker pull ghcr.io/${{ github.repository }}:${{github.ref_name}} | |
docker tag ghcr.io/${{ github.repository }}:${{github.ref_name}} ghcr.io/${{ github.repository }}:latest | |
docker push ghcr.io/${{ github.repository }}:latest | |
- name: Mark release as deployed | |
uses: actions/github-script@v7 | |
with: | |
github-token: ${{ secrets.GITHUB_TOKEN }} | |
script: | | |
const { owner, repo } = context.repo; | |
await github.rest.repos.updateRelease({ | |
owner, | |
repo, | |
release_id: ${{ steps.validate_deployment.outputs.result }}, | |
prerelease: false, | |
make_latest: true | |
}); |