152 lines
6.2 KiB
YAML
152 lines
6.2 KiB
YAML
# This workflow runs after a merge to any release branch of the action. It:
|
|
# 1. Tags the merge commit on the release branch that represents the new release with an `vN.x.y`
|
|
# tag
|
|
# 2. Updates the `vN` tag to refer to this merge commit.
|
|
# 3. Iff vN == vLatest, merges any changes from the release back into the main branch.
|
|
# Typically, this is just a single commit that updates the changelog.
|
|
name: Tag release and merge back
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
inputs:
|
|
baseBranch:
|
|
description: 'The base branch to merge into'
|
|
default: main
|
|
required: false
|
|
|
|
push:
|
|
branches:
|
|
- releases/v*
|
|
|
|
jobs:
|
|
merge-back:
|
|
runs-on: ubuntu-latest
|
|
if: github.repository == 'github/codeql-action'
|
|
env:
|
|
BASE_BRANCH: "${{ github.event.inputs.baseBranch || 'main' }}"
|
|
HEAD_BRANCH: "${{ github.head_ref || github.ref }}"
|
|
|
|
steps:
|
|
- name: Dump environment
|
|
run: env
|
|
|
|
- name: Dump GitHub context
|
|
env:
|
|
GITHUB_CONTEXT: '${{ toJson(github) }}'
|
|
run: echo "${GITHUB_CONTEXT}"
|
|
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 0 # ensure we have all tags and can push commits
|
|
- uses: actions/setup-node@v4
|
|
|
|
- name: Update git config
|
|
run: |
|
|
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
|
git config --global user.name "github-actions[bot]"
|
|
|
|
- name: Get version and new branch
|
|
id: getVersion
|
|
run: |
|
|
VERSION="v$(jq '.version' -r 'package.json')"
|
|
echo "version=${VERSION}" >> $GITHUB_OUTPUT
|
|
short_sha="${GITHUB_SHA:0:8}"
|
|
NEW_BRANCH="mergeback/${VERSION}-to-${BASE_BRANCH}-${short_sha}"
|
|
echo "newBranch=${NEW_BRANCH}" >> $GITHUB_OUTPUT
|
|
LATEST_RELEASE_BRANCH=$(git branch -r | grep -E "origin/releases/v[0-9]+$" | sed 's/origin\///g' | sort -V | tail -1 | xargs)
|
|
echo "latest_release_branch=${LATEST_RELEASE_BRANCH}" >> $GITHUB_OUTPUT
|
|
|
|
- name: Dump branches
|
|
env:
|
|
NEW_BRANCH: "${{ steps.getVersion.outputs.newBranch }}"
|
|
run: |
|
|
echo "BASE_BRANCH ${BASE_BRANCH}"
|
|
echo "HEAD_BRANCH ${HEAD_BRANCH}"
|
|
echo "NEW_BRANCH ${NEW_BRANCH}"
|
|
echo "LATEST_RELEASE_BRANCH ${LATEST_RELEASE_BRANCH}"
|
|
echo "GITHUB_REF ${GITHUB_REF}"
|
|
|
|
- name: Create mergeback branch
|
|
env:
|
|
NEW_BRANCH: "${{ steps.getVersion.outputs.newBranch }}"
|
|
run: |
|
|
git checkout -b "${NEW_BRANCH}"
|
|
|
|
- name: Check for tag
|
|
id: check
|
|
env:
|
|
VERSION: "${{ steps.getVersion.outputs.version }}"
|
|
run: |
|
|
set +e # don't fail on an errored command
|
|
git ls-remote --tags origin | grep "${VERSION}"
|
|
exists="$?"
|
|
if [ "${exists}" -eq 0 ]; then
|
|
echo "Tag ${VERSION} exists. Not going to re-release."
|
|
echo "exists=true" >> $GITHUB_OUTPUT
|
|
else
|
|
echo "Tag ${VERSION} does not exist yet."
|
|
fi
|
|
|
|
# we didn't tag the release during the update-release-branch workflow because the
|
|
# commit that actually makes it to the release branch is a merge commit,
|
|
# and not yet known during the first workflow. We tag now because we know the correct commit.
|
|
- name: Tag release
|
|
if: steps.check.outputs.exists != 'true'
|
|
env:
|
|
VERSION: ${{ steps.getVersion.outputs.version }}
|
|
run: |
|
|
# Create the `vx.y.z` tag
|
|
git tag --annotate "${VERSION}" --message "${VERSION}"
|
|
# Update the `vx` tag
|
|
major_version_tag=$(cut -d '.' -f1 <<< "${VERSION}")
|
|
# Use `--force` to overwrite the major version tag
|
|
git tag --annotate "${major_version_tag}" --message "${major_version_tag}" --force
|
|
# Push the tags, using:
|
|
# - `--atomic` to make sure we either update both tags or neither (an intermediate state,
|
|
# e.g. where we update the vN.x.y tag on the remote but not the vN tag, could result in
|
|
# unwanted Dependabot updates, e.g. from vN to vN.x.y)
|
|
# - `--force` since we're overwriting the `vN` tag
|
|
git push origin --atomic --force refs/tags/"${VERSION}" refs/tags/"${major_version_tag}"
|
|
|
|
- name: Create mergeback branch
|
|
if: ${{ steps.check.outputs.exists != 'true' && endsWith(github.ref_name, steps.getVersion.outputs.latest_release_branch) }}
|
|
env:
|
|
VERSION: "${{ steps.getVersion.outputs.version }}"
|
|
NEW_BRANCH: "${{ steps.getVersion.outputs.newBranch }}"
|
|
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
|
run: |
|
|
set -exu
|
|
pr_title="Mergeback ${VERSION} ${HEAD_BRANCH} into ${BASE_BRANCH}"
|
|
pr_body=$(cat << EOF
|
|
This PR bumps the version number and updates the changelog after the ${VERSION} release.
|
|
|
|
Please do the following:
|
|
|
|
- [ ] Remove and re-add the "Update dependencies" label to the PR to trigger just this workflow.
|
|
- [ ] Wait for the "Update dependencies" workflow to push a commit updating the dependencies.
|
|
- [ ] Mark the PR as ready for review to trigger the full set of PR checks.
|
|
- [ ] Approve and merge the PR. When merging the PR, make sure "Create a merge commit" is
|
|
selected rather than "Squash and merge" or "Rebase and merge".
|
|
EOF
|
|
)
|
|
|
|
# Update the version number ready for the next release
|
|
npm version patch --no-git-tag-version
|
|
|
|
# Update the changelog
|
|
perl -i -pe 's/^/## \[UNRELEASED\]\n\nNo user facing changes.\n\n/ if($.==5)' CHANGELOG.md
|
|
git add .
|
|
git commit -m "Update changelog and version after ${VERSION}"
|
|
|
|
git push origin "${NEW_BRANCH}"
|
|
|
|
# PR checks won't be triggered on PRs created by Actions. Therefore mark the PR as draft
|
|
# so that a maintainer can take the PR out of draft, thereby triggering the PR checks.
|
|
gh pr create \
|
|
--head "${NEW_BRANCH}" \
|
|
--base "${BASE_BRANCH}" \
|
|
--title "${pr_title}" \
|
|
--label "Update dependencies" \
|
|
--body "${pr_body}" \
|
|
--assignee "${GITHUB_ACTOR}" \
|
|
--draft
|