Skip to content

Commit

Permalink
Make release automation reusable and add dependency upgrade support (#…
Browse files Browse the repository at this point in the history
…3848)

* Extract release into reusable action

Signed-off-by: Michael Telatynski <[email protected]>

* Add dependency upgrade task to release-action

Signed-off-by: Michael Telatynski <[email protected]>

* Prevent develop dependencies

Signed-off-by: Michael Telatynski <[email protected]>

* Simplify dependency management

Signed-off-by: Michael Telatynski <[email protected]>

* Add missing secret declaration

Signed-off-by: Michael Telatynski <[email protected]>

---------

Signed-off-by: Michael Telatynski <[email protected]>
  • Loading branch information
t3chguy authored Nov 1, 2023
1 parent 36c9586 commit 4458dcc
Show file tree
Hide file tree
Showing 2 changed files with 196 additions and 123 deletions.
191 changes: 191 additions & 0 deletions .github/workflows/release-action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
name: Release Action
on:
workflow_call:
secrets:
ELEMENT_BOT_TOKEN:
required: true
NPM_TOKEN:
required: false
inputs:
final:
description: Make final release
required: true
default: false
type: boolean
npm:
description: Publish to npm
type: boolean
default: false
dependencies:
description: |
List of dependencies to update in `npm-dep=version` format.
`version` can be `"current"` to leave it at the current version.
type: string
required: false
jobs:
release:
name: Release
runs-on: ubuntu-latest
steps:
- name: Get draft release
id: release
uses: cardinalby/git-get-release-action@cedef2faf69cb7c55b285bad07688d04430b7ada # v1
env:
GITHUB_TOKEN: ${{ github.token }}
with:
draft: true
latest: true

- name: Load version
run: echo "VERSION=$VERSION" >> $GITHUB_ENV
env:
VERSION: ${{ steps.release.outputs.tag_name }}

- name: Finalise version
if: inputs.mode == 'final'
run: echo "VERSION=$(echo $VERSION | cut -d- -f1)" >> $GITHUB_ENV

- uses: actions/checkout@v4
with:
ref: staging
token: ${{ secrets.ELEMENT_BOT_TOKEN }}
fetch-depth: 0

- name: Set up git
run: |
git config --global user.email "[email protected]"
git config --global user.name "RiotRobot"
- uses: actions/setup-node@v3
with:
cache: "yarn"

- name: Install dependencies
run: "yarn install --frozen-lockfile"

- name: Update dependencies
if: inputs.dependencies
run: |
while IFS= read -r DEPENDENCY; do
[ -z "$DEPENDENCY" ] && continue
IFS="=" read -r PACKAGE UPDATE_VERSION <<< "$DEPENDENCY"
CURRENT_VERSION=$(cat package.json | jq -r .dependencies[\"$PACKAGE\"])
echo "Current $PACKAGE version is $CURRENT_VERSION"
if [ "$CURRENT_VERSION" == "null" ]
then
echo "Unable to find $PACKAGE in package.json"
exit 1
fi
if [ "$UPDATE_VERSION" == "current" ] || [ "$UPDATE_VERSION" == "$CURRENT_VERSION" ]
then
echo "Not updating dependency $PACKAGE"
continue
fi
echo "Upgrading $PACKAGE to $UPDATE_VERSION..."
yarn upgrade "$PACKAGE@$UPDATE_VERSION" --exact
git add -u
git commit -m "Upgrade $PACKAGE to $UPDATE_VERSION"
done <<< "$DEPENDENCIES"
env:
DEPENDENCIES: ${{ inputs.dependencies }}
FINAL: ${{ inputs.final }}

- name: Prevent develop dependencies
if: inputs.dependencies
run: |
ret=0
cat package.json | jq '.dependencies[]' | grep -q '#develop' || ret=$?
if [ "$ret" -eq 0 ]; then
echo "package.json contains develop dependencies. Refusing to release."
exit
fi
- name: Bump package.json version
run: yarn version --no-git-tag-version --new-version "$VERSION"

- name: Add to CHANGELOG.md
if: inputs.mode == 'final'
run: |
mv CHANGELOG.md CHANGELOG.md.old
HEADER="Changes in [${VERSION#v}](https://github.com/${{ github.repository }}/releases/tag/$VERSION) ($(date '+%Y-%m-%d'))"
{
echo "$HEADER"
printf '=%.0s' $(seq ${#HEADER})
echo ""
echo "$BODY"
echo ""
} > CHANGELOG.md
cat CHANGELOG.md.old >> CHANGELOG.md
rm CHANGELOG.md.old
env:
BODY: ${{ steps.release.outputs.body }}

# For the published and dist versions of the package,
# we copy the `matrix_lib_main` and `matrix_lib_typings` fields to `main` and `typings` (if they exist).
# This small bit of gymnastics allows us to use the TypeScript source directly for development without
# needing to build before linting or testing.
- name: Update package.json fields
run: |
for i in main typings browser
do
lib_value=$(jq -r ".matrix_lib_$i" package.json)
if [ "$lib_value" != "null" ]; then
jq ".$i = .matrix_lib_$i" package.json > package.json.new && mv package.json.new package.json && yarn prettier --write package.json
fi
done
- name: Commit and push changes
run: |
git add package.json CHANGELOG.md
git commit -m "$VERSION"
git push origin staging
- name: Merge to master
if: inputs.final
run: |
git checkout master
git merge -X theirs staging
git push origin master
- name: Publish release
uses: actions/github-script@v6
id: my-script
env:
RELEASE_ID: ${{ steps.release.outputs.id }}
MODE: ${{ inputs.final }}
with:
result-encoding: string
retries: 3
script: |
let { RELEASE_ID: release_id, VERSION, MODE } = process.env;
const { owner, repo } = context.repo;
const opts = {
owner,
repo,
release_id,
tag_name: VERSION,
name: VERSION,
draft: false,
};
if (MODE === "final") {
opts.prerelease = false;
opts.make_latest = true;
}
github.rest.repos.updateRelease(opts);
npm:
name: Publish to npm
needs: release
if: inputs.npm
uses: matrix-org/matrix-js-sdk/.github/workflows/release-npm.yml@develop
secrets:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
128 changes: 5 additions & 123 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,121 +23,11 @@ on:
concurrency: ${{ github.workflow }}
jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Get draft release
id: release
uses: cardinalby/git-get-release-action@cedef2faf69cb7c55b285bad07688d04430b7ada # v1
env:
GITHUB_TOKEN: ${{ github.token }}
with:
draft: true
latest: true

- uses: actions/checkout@v4
with:
ref: staging
token: ${{ secrets.ELEMENT_BOT_TOKEN }}
fetch-depth: 0

- uses: actions/setup-node@v3
with:
cache: "yarn"

- name: Install Deps
run: "yarn install --frozen-lockfile"

- name: Load version
run: echo "VERSION=$VERSION" >> $GITHUB_ENV
env:
VERSION: ${{ steps.release.outputs.tag_name }}

- name: Finalise version
if: inputs.mode == 'final'
run: echo "VERSION=$(echo $VERSION | cut -d- -f1)" >> $GITHUB_ENV

- name: Bump package.json version
run: yarn version --no-git-tag-version --new-version "$VERSION"

- name: Add to CHANGELOG.md
if: inputs.mode == 'final'
run: |
mv CHANGELOG.md CHANGELOG.md.old
HEADER="Changes in [${VERSION#v}](https://github.com/${{ github.repository }}/releases/tag/$VERSION) ($(date '+%Y-%m-%d'))"
{
echo "$HEADER"
printf '=%.0s' $(seq ${#HEADER})
echo ""
echo "$BODY"
echo ""
} > CHANGELOG.md
cat CHANGELOG.md.old >> CHANGELOG.md
rm CHANGELOG.md.old
env:
BODY: ${{ steps.release.outputs.body }}

# For the published and dist versions of the package,
# we copy the `matrix_lib_main` and `matrix_lib_typings` fields to `main` and `typings` (if they exist).
# This small bit of gymnastics allows us to use the TypeScript source directly for development without
# needing to build before linting or testing.
- name: Update package.json fields
run: |
for i in main typings browser
do
lib_value=$(jq -r ".matrix_lib_$i" package.json)
if [ "$lib_value" != "null" ]; then
jq ".$i = .matrix_lib_$i" package.json > package.json.new && mv package.json.new package.json && yarn prettier --write package.json
fi
done
- name: Set up git
run: |
git config --global user.email "[email protected]"
git config --global user.name "RiotRobot"
- name: Commit and push changes
run: |
git add package.json CHANGELOG.md
git commit -m "$VERSION"
git push origin staging
- name: Merge to master
if: inputs.mode == 'final'
run: |
git checkout master
git merge -X theirs staging
git push origin master
- name: Publish release
uses: actions/github-script@v6
id: my-script
env:
RELEASE_ID: ${{ steps.release.outputs.id }}
MODE: ${{ inputs.mode }}
with:
result-encoding: string
retries: 3
script: |
let { RELEASE_ID: release_id, VERSION, MODE } = process.env;
const { owner, repo } = context.repo;
const opts = {
owner,
repo,
release_id,
tag_name: VERSION,
name: VERSION,
draft: false,
};
if (MODE === "final") {
opts.prerelease = false;
opts.make_latest = true;
}
github.rest.repos.updateRelease(opts);
uses: matrix-org/matrix-js-sdk/.github/workflows/release-action.yml@develop
secrets: inherit
with:
final: ${{ inputs.mode == 'final' }}
npm: ${{ inputs.npm }}

docs:
name: Publish Documentation
Expand Down Expand Up @@ -184,11 +74,3 @@ jobs:
git commit -m "Update docs"
git push
working-directory: _docs

npm:
name: Publish
needs: release
if: inputs.npm
uses: matrix-org/matrix-js-sdk/.github/workflows/release-npm.yml@develop
secrets:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

0 comments on commit 4458dcc

Please sign in to comment.