Skip to content

Commit

Permalink
chore: add infrastructure to patch latest version (#2497)
Browse files Browse the repository at this point in the history
  • Loading branch information
nedsalk committed Jun 23, 2024
1 parent e2259ed commit 0790f9c
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 20 deletions.
38 changes: 30 additions & 8 deletions .github/workflows/pr-validate-changesets.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -121,22 +121,44 @@ jobs:
env:
CHANGESET_FILE: ${{ env.CHANGESET_FILE }}

- name: Validate that there are only patch changes
- name: Validate release/* branch changesets
if: startsWith(github.base_ref, 'release/')
run: |
LATEST_RELEASE=$(pnpm run --silent changeset:get-latest-release)
pnpm changeset version
RELEASE_VERSION=v$(sed -nE 's/^\s*"version": "(.*?)",$/\1/p' packages/fuels/package.json)
git reset --hard
pnpm add --global semver
RELEASE_VERSION_HIGHER_THAN_LATEST=$(semver $LATEST_RELEASE $RELEASE_VERSION | tail -n1 | grep ${RELEASE_VERSION#v} --silent && echo true || echo false)
CHANGES=$(sed -n '/---/,/---/p' .changeset/*.md)
echo $CHANGES | grep -E 'patch' --silent && echo "Patch changes found." || (echo "No patch changes found." && exit 1)
echo $CHANGES | grep -E 'minor|major' --silent && echo "Old releases can only be patched; no minor and major versions allowed." && exit 1 || echo "No minor nor major changes."
- name: Validate that there was no release for the next patch version
if: startsWith(github.base_ref, 'release/')
if [ "$RELEASE_VERSION_HIGHER_THAN_LATEST" = "true" ]; then
echo $CHANGES | grep -E 'patch|minor' --silent && echo "Patch or minor changes found." || (echo "No patch nor minor changes found." && exit 1)
echo $CHANGES | grep -E 'major' --silent && echo "The latest release can have a patch or minor version update; no major version updates allowed." && exit 1 || echo "No major changes."
else
echo $CHANGES | grep -E 'patch' --silent && echo "Patch changes found." || (echo "No patch changes found." && exit 1)
echo $CHANGES | grep -E 'minor|major' --silent && echo "Old releases can only be patched; no minor and major version updates allowed." && exit 1 || echo "No minor nor major changes."
fi
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Validate that there was no release for the next version
run: |
OLD_VERSION=$(sed -nE 's/^\s*"version": "(.*?)",$/\1/p' packages/fuels/package.json)
pnpm changeset version
VERSION=$(sed -nE 's/^\s*"version": "(.*?)",$/\1/p' packages/fuels/package.json)
NEW_VERSION=$(sed -nE 's/^\s*"version": "(.*?)",$/\1/p' packages/fuels/package.json)
git reset --hard
STATUS_CODE=$(curl -s -w '%{http_code}\n' "https://www.npmjs.com/package/fuels/v/$VERSION" | tail -n1)
if [ "$OLD_VERSION" = "$NEW_VERSION" ]; then
# the versions didn't change so we won't be releasing it anyways
exit 0
fi
STATUS_CODE=$(curl -s -w '%{http_code}\n' "https://www.npmjs.com/package/fuels/v/$NEW_VERSION" | tail -n1)
if [[ $STATUS_CODE != 404 ]]; then
echo "Release for version $VERSION already exists or curl received an unexpected result (result is $STATUS_CODE). Exiting."
echo "Release for version $NEW_VERSION already exists or curl received an unexpected result (result is $STATUS_CODE). Exiting."
exit 1
else
exit 0
Expand Down
45 changes: 35 additions & 10 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,11 @@ jobs:
- name: Get latest release
run: |
echo "LATEST_RELEASE=$(pnpm run --silent changeset:get-latest-release)" >> $GITHUB_ENV
LATEST_RELEASE=$(pnpm run --silent changeset:get-latest-release)
echo "LATEST_RELEASE=$LATEST_RELEASE" >> $GITHUB_ENV
pnpm add --global semver
echo "RELEASE_VERSION_HIGHER_THAN_LATEST=$(semver $LATEST_RELEASE $RELEASE_VERSION | tail -n1 | grep ${RELEASE_VERSION#v} --silent && echo true || echo false)" >> $GITHUB_ENV
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Expand All @@ -86,12 +90,7 @@ jobs:
PUBLISHED: ${{ steps.changesets.outputs.published }}
REF_NAME: ${{ github.ref_name }}
LATEST_RELEASE: ${{ env.LATEST_RELEASE }}

- name: Delete the release branch
if: steps.changesets.outputs.published == 'true' && startsWith(github.ref_name, 'release/')
run: git push origin --delete ${{ github.ref_name }}
env:
GITHUB_TOKEN: ${{ secrets.REPO_TOKEN }}
RELEASE_VERSION_HIGHER_THAN_LATEST: ${{ env.RELEASE_VERSION_HIGHER_THAN_LATEST }}

- name: Release to @next tag on npm
if: github.ref_name == 'master' && steps.changesets.outputs.published != 'true'
Expand Down Expand Up @@ -123,7 +122,7 @@ jobs:
run: echo LAST_COMMIT_MSG=$(git --no-pager log -1 --pretty=%B) >> $GITHUB_ENV

- name: Decides if Docs should be deployed
if: github.ref_name == 'master' && startsWith(env.LAST_COMMIT_MSG, 'ci(changesets):')
if: startsWith(env.LAST_COMMIT_MSG, 'ci(changesets):') && env.RELEASE_VERSION_HIGHER_THAN_LATEST == 'true'
run: echo SHOULD_DEPLOY_DOCS=true >> $GITHUB_ENV

- name: Configure GitHub Pages
Expand Down Expand Up @@ -153,7 +152,7 @@ jobs:
run: |
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git config user.name "github-actions[bot]"
git merge origin/master --no-edit
git merge origin/$GITHUB_REF_NAME --no-edit
pnpm install
pnpm build
rm -f apps/docs/.gitignore
Expand All @@ -164,14 +163,40 @@ jobs:
git restore apps/docs/.gitignore
- name: Update docs (nightly)
if: env.SHOULD_DEPLOY_DOCS == 'true'
if: github.ref_name == 'master' && env.SHOULD_DEPLOY_DOCS == 'true'
uses: benc-uk/workflow-dispatch@v1
with:
workflow: update-nightly.yml
ref: master
repo: FuelLabs/docs-hub
token: ${{ secrets.REPO_TOKEN }}

- name: Create PR to apply latest release to master
if: steps.changesets.outputs.published == 'true' && startsWith(github.ref_name, 'release/') && env.RELEASE_VERSION_HIGHER_THAN_LATEST == 'true'
run: |
PR_TITLE_TEXT='apply `latest` release to `master`'
if [ ${RELEASE_VERSION#v} = "$(semver "$LATEST_VERSION" --increment minor)" ]; then
PR_TITLE="build!: $PR_TITLE_TEXT"
else
PR_TITLE="build: $PR_TITLE_TEXT"
fi
PR_BODY='Automatically created when `latest` published release is newer than `master` due to publishing done via `release/*` branches.'
gh pr create -B master -H $GITHUB_REF_NAME --title "$PR_TITLE" --body "$PR_BODY"
env:
GITHUB_TOKEN: ${{ secrets.REPO_TOKEN }}
RELEASE_VERSION: ${{ env.RELEASE_VERSION }}
LATEST_VERSION: ${{ env.LATEST_VERSION }}

- name: Delete the release branch
# We check env.RELEASE_VERSION_HIGHER_THAN_LATEST == 'false'
# because we don't want to delete the branch that is used in the "Create PR to apply latest release to master" step above
if: steps.changesets.outputs.published == 'true' && startsWith(github.ref_name, 'release/') && env.RELEASE_VERSION_HIGHER_THAN_LATEST == 'false'
run: git push origin --delete ${{ github.ref_name }}
env:
GITHUB_TOKEN: ${{ secrets.REPO_TOKEN }}

# Upload assets to S3
- uses: unfor19/install-aws-cli-action@v1.0.3
if: github.ref_name == 'master' && steps.changesets.outputs.published != 'true'
Expand Down
17 changes: 16 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,22 @@ The following example is for releasing a patch for `v0.69.0` -> `v0.69.1`.
- Create PRs with base set to that release branch
- When the PR is merged, a changeset PR is created
- When the changeset PR is merged into the release branch, the next patch version is released and the commit is tagged (e.g. `v0.69.1`)
- After release, delete the release branch from GitHub
- After release, the release branch will be automatically deleted

# Patching latest release

Imagine the scenario:

1. We release `v0.80.0`
1. One day later, we have a new changesets PR that will bump things to `v0.81.0`
1. Before releasing `v0.81.0`, we find an issue and need to make a `v0.80.1` patch

We'd follow the same approach as explained in the [Patching old releases](#patching-old-releases) section above, bearing in mind the following after the release:

- A PR merging the `latest` release's branch into `master` will be automatically created,
- The automatically-created PR **must** be merged as soon as possible in order to
- have the versions of packages on `master` match the `latest` released package versions,
- have the released functionality on `master` as well

# FAQ

Expand Down
3 changes: 2 additions & 1 deletion scripts/changeset/update-changelog.mts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const {
RELEASE_TAG,
REF_NAME,
LATEST_RELEASE,
RELEASE_VERSION_HIGHER_THAN_LATEST,
} = process.env;

function sleep(time: number) {
Expand Down Expand Up @@ -156,7 +157,7 @@ await (async () => {
return;
}

if (REF_NAME !== "master") {
if (RELEASE_VERSION_HIGHER_THAN_LATEST !== "true") {
await reapplyLatestTagToActualLatestRelease();
}

Expand Down

0 comments on commit 0790f9c

Please sign in to comment.