-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Extract upsert-pending-release into js file * Simplify main action to append prereleases * Attempt refactor to new flow * Fix concurrency comments
- Loading branch information
1 parent
3ef8ebe
commit 700c693
Showing
7 changed files
with
235 additions
and
213 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
name: Deploy Existing Release | ||
|
||
on: | ||
workflow_dispatch: | ||
|
||
# Ensure only one instance of either this 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: Perform pre-deployment checks | ||
uses: actions/github-script@v7 | ||
with: | ||
github-token: ${{ secrets.GITHUB_TOKEN }} | ||
script: | | ||
const script = require('./scripts/validate-prerelease.js'); | ||
const result = await script({github, context, core}, ${{github.ref_name}}); | ||
console.log('Validation complete'); | ||
console.log(result); | ||
return result; | ||
- 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: Update latest pointer | ||
uses: actions/github-script@v7 | ||
with: | ||
github-token: ${{ secrets.GITHUB_TOKEN }} | ||
script: | | ||
const script = require('./scripts/reconcile-release.js'); | ||
await script({github, context, core}, ${{ steps.validate_deployment.outputs.result.releaseId }}); |
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
This file was deleted.
Oops, something went wrong.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
module.exports = async ({ github, context }, tag) => { | ||
const { owner, repo } = context.repo; | ||
|
||
await github.rest.git.createRef({ | ||
owner, | ||
repo, | ||
ref: `refs/tags/${tag}`, | ||
sha: context.sha, | ||
}); | ||
|
||
const newRelease = await github.rest.repos.createRelease({ | ||
owner, | ||
repo, | ||
prerelease: true, | ||
tag_name: tag, | ||
name: tag, | ||
generate_release_notes: true, | ||
}); | ||
|
||
console.log(`Created prerelease: ${newRelease.data.html_url}`); | ||
}; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
/** The maximum number of release pages to search through to find prereleases to be cleaned up. */ | ||
const MAX_PAGE_SEARCH = 5; | ||
|
||
module.exports = async ({ github, context }, targetReleaseId) => { | ||
const { owner, repo } = context.repo; | ||
|
||
const targetRelease = await github.rest.repos.getRelease({ | ||
owner, | ||
repo, | ||
release_id: targetReleaseId, | ||
}); | ||
|
||
if (targetRelease.data.draft) { | ||
console.log("Target is a draft release, finding prereleases to bundle up"); | ||
|
||
// Collect all prereleases | ||
let prereleases = []; | ||
const releasesIterator = github.paginate.iterator( | ||
github.rest.repos.listReleases, | ||
{ | ||
owner, | ||
repo, | ||
} | ||
); | ||
while (!result.done && currentPage <= MAX_PAGE_SEARCH) { | ||
prereleases = prereleases.concat( | ||
result.value.data.filter((release) => release.prerelease) | ||
); | ||
result = await releasesIterator.next(); | ||
} | ||
|
||
// Determine which prereleases are older than the target release | ||
let newerPreleaseCount = 0; | ||
const olderPreleases = []; | ||
for (const prerelease of prereleases) { | ||
const diff = await github.rest.repos.compareCommitsWithBasehead({ | ||
owner, | ||
repo, | ||
basehead: `${prerelease.tag_name}...${targetRelease.data.tag_name}`, | ||
}); | ||
|
||
if (diff.data.ahead_by > 0) { | ||
console.log( | ||
`Prerelease ${prerelease.tag_name} is newer than target release, skipping` | ||
); | ||
newerPreleaseCount++; | ||
continue; | ||
} else { | ||
console.log( | ||
`Prerelease ${prerelease.tag_name} is older than target release, adding to cleanup list` | ||
); | ||
olderPreleases.push(prerelease); | ||
} | ||
} | ||
|
||
console.log( | ||
`Found ${olderPreleases.length} older prereleases to cleanup, ${newerPreleaseCount} newer prereleases skipped` | ||
); | ||
|
||
// Delete older prereleases | ||
for (const olderPrerelease of olderPreleases) { | ||
await github.rest.repos.deleteRelease({ | ||
owner, | ||
repo, | ||
release_id: olderPrerelease.id, | ||
}); | ||
} | ||
|
||
console.log("Promoting draft release to production"); | ||
// Promote draft release to production | ||
await github.rest.repos.updateRelease({ | ||
owner, | ||
repo, | ||
release_id: "${{ steps.validate_deployment.outputs.result }}", | ||
draft: false, | ||
prerelease: false, | ||
latest: true, | ||
}); | ||
} else { | ||
console.log("Target is an existing release, marking release as latest"); | ||
|
||
await github.rest.repos.updateRelease({ | ||
owner, | ||
repo, | ||
release_id: "${{ steps.validate_deployment.outputs.result }}", | ||
make_latest: true, | ||
}); | ||
} | ||
}; |
Oops, something went wrong.