diff --git a/.github/workflows/retag-release.yaml b/.github/workflows/retag-release.yaml new file mode 100644 index 000000000..5f4d26c69 --- /dev/null +++ b/.github/workflows/retag-release.yaml @@ -0,0 +1,20 @@ +# This script adds a "vX.Y.Z" tag to every new release. +# +# Our releases are tagged like "1.2.3" but we want people to be able to write +# GitHub Action workflows to say "uses: readmeio/readme@v1.2.3" because that's +# the usual GitHub convention. + +name: retag-release + +on: + release: + types: [created] + +jobs: + retag-release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/github-script@v6 + with: + script: require('./bin/retag-release.js')(github, context); diff --git a/bin/retag-release.js b/bin/retag-release.js new file mode 100644 index 000000000..113e6098d --- /dev/null +++ b/bin/retag-release.js @@ -0,0 +1,42 @@ +/* eslint-disable no-console */ +module.exports = async (github, context) => { + const { owner, repo } = context.repo; + const oldTag = context.payload.release.tag_name; + if (!oldTag.match(/^[0-9]+\.[0-9]+\.[0-9]+$/)) { + console.log('Not retagging this release: This script will only retag releases that use'); + console.log(`semantic versioning, like "1.2.3", but this release's tag is "${oldTag}".`); + return {}; + } + const newTag = `v${oldTag}`; + console.log(`Retagging release "${oldTag}" as "${newTag}".`); + + const oldRef = await github.rest.git.getRef({ + owner, + repo, + ref: `tags/${oldTag}`, + }); + if (oldRef.status < 200 || oldRef.status >= 400) { + console.log(oldRef); + throw new Error(`GitHub API call returned HTTP status code ${oldRef.status}`); + } + const sha = oldRef.data.object.sha; + console.log(`Found tag "${oldTag}"; commit hash is ${sha}`); + + console.log(`Creating tag "${newTag}" pointing to commit hash ${sha}...`); + const newRef = await github.rest.git.createRef({ + owner, + repo, + ref: `refs/tags/${newTag}`, + sha, + }); + if (newRef.status < 200 || newRef.status >= 400) { + console.log(newRef); + throw new Error(`GitHub API call returned HTTP status code ${newRef.status}`); + } + console.log('Successfully retagged this release.'); + return { + original_tag: oldTag, + new_tag: newTag, + sha, + }; +};