81569f3461
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
333 lines
13 KiB
YAML
333 lines
13 KiB
YAML
name: Release Make
|
|
on:
|
|
workflow_call:
|
|
secrets:
|
|
ELEMENT_BOT_TOKEN:
|
|
required: true
|
|
GPG_PASSPHRASE:
|
|
required: false
|
|
GPG_PRIVATE_KEY:
|
|
required: false
|
|
inputs:
|
|
final:
|
|
description: Make final release
|
|
required: true
|
|
default: false
|
|
type: boolean
|
|
npm:
|
|
description: Publish to npm
|
|
type: boolean
|
|
default: false
|
|
gpg-fingerprint:
|
|
description: Fingerprint of the GPG key to use for signing the git tag and assets, if any.
|
|
type: string
|
|
required: false
|
|
asset-path:
|
|
description: |
|
|
The path to the asset you want to upload, if any. You can use glob patterns here.
|
|
Will be GPG signed and an `.asc` file included in the release artifacts if `gpg-fingerprint` is set.
|
|
Relative to `dir`.
|
|
type: string
|
|
required: false
|
|
expected-asset-count:
|
|
description: The number of expected assets, including signatures, excluding generated zip & tarball.
|
|
type: number
|
|
required: false
|
|
dist-dir:
|
|
description: The directory to release
|
|
type: string
|
|
default: "."
|
|
version-dirs:
|
|
description: Directories in which to update package.json `version` field
|
|
type: string
|
|
required: false
|
|
outputs:
|
|
npm-id:
|
|
description: "The npm package@version string we published"
|
|
value: ${{ jobs.npm.outputs.id }}
|
|
permissions: {}
|
|
jobs:
|
|
checks:
|
|
name: Sanity checks
|
|
permissions:
|
|
issues: read
|
|
pull-requests: read
|
|
uses: matrix-org/matrix-js-sdk/.github/workflows/release-checks.yml@develop # zizmor: ignore[unpinned-uses]
|
|
|
|
release:
|
|
name: Release
|
|
runs-on: ubuntu-24.04
|
|
environment: Release
|
|
needs: checks
|
|
permissions:
|
|
contents: write
|
|
steps:
|
|
- name: Load GPG key
|
|
id: gpg
|
|
if: inputs.gpg-fingerprint
|
|
uses: crazy-max/ghaction-import-gpg@2dc316deee8e90f13e1a351ab510b4d5bc0c82cd # v7
|
|
with:
|
|
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
|
|
passphrase: ${{ secrets.GPG_PASSPHRASE }}
|
|
fingerprint: ${{ inputs.gpg-fingerprint }}
|
|
|
|
- name: Get draft release
|
|
id: draft-release
|
|
uses: cardinalby/git-get-release-action@5172c3a026600b1d459b117738c605fabc9e4e44 # 1.2.5
|
|
env:
|
|
GITHUB_TOKEN: ${{ github.token }}
|
|
with:
|
|
draft: true
|
|
latest: true
|
|
|
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
|
with:
|
|
ref: staging
|
|
# We will be pushing to this branch and want the CI to run after we do so we cannot use the GITHUB_TOKEN
|
|
token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
|
fetch-depth: 0
|
|
persist-credentials: true
|
|
|
|
- name: Get actions scripts
|
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
|
with:
|
|
repository: matrix-org/matrix-js-sdk
|
|
persist-credentials: false
|
|
path: .action-repo
|
|
sparse-checkout: |
|
|
.github/actions
|
|
scripts/release
|
|
|
|
- name: Prepare variables
|
|
id: prepare
|
|
working-directory: ${{ inputs.dist-dir }}
|
|
run: |
|
|
echo "VERSION=$VERSION" >> $GITHUB_ENV
|
|
|
|
HAS_DIST=0
|
|
jq -e .scripts.dist package.json >/dev/null 2>&1 && HAS_DIST=1
|
|
echo "has-dist-script=$HAS_DIST" >> $GITHUB_OUTPUT
|
|
env:
|
|
VERSION: ${{ steps.draft-release.outputs.tag_name }}
|
|
|
|
- name: Finalise version
|
|
if: inputs.final
|
|
run: echo "VERSION=$(echo $VERSION | cut -d- -f1)" >> $GITHUB_ENV
|
|
|
|
- name: Check version number not in use
|
|
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
|
|
with:
|
|
script: |
|
|
const { VERSION } = process.env;
|
|
github.rest.repos.getReleaseByTag({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
tag: VERSION,
|
|
}).then(() => {
|
|
core.setFailed(`Version ${VERSION} already exists`);
|
|
}).catch(() => {
|
|
// This is fine, we expect there to not be any release with this version yet
|
|
});
|
|
|
|
- name: Set up git
|
|
run: |
|
|
git config --global user.email "releases@riot.im"
|
|
git config --global user.name "RiotRobot"
|
|
|
|
- uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5
|
|
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
|
|
with:
|
|
cache: "pnpm"
|
|
node-version-file: ${{ inputs.dist-dir }}/package.json
|
|
|
|
- name: Install dependencies
|
|
run: "pnpm install --frozen-lockfile"
|
|
|
|
- name: Handle develop dependencies
|
|
working-directory: ${{ inputs.dist-dir }}
|
|
run: |
|
|
ret=0
|
|
cat package.json | jq -r '.dependencies | to_entries | .[] | "\(.key) \(.value)"' | grep '#develop$' | while read -r dep ; do
|
|
IFS=" "
|
|
PACKAGE=${dep[0]}
|
|
VERSION=${dep[1]}
|
|
|
|
echo "::warning title=Develop dependency found::$DEPENDENCY will be kept at $VERSION"
|
|
pnpm add "$PACKAGE@$VERSION" --save-exact
|
|
git add -u
|
|
git commit -m "Keep $PACKAGE at $VERSION"
|
|
done
|
|
|
|
- name: Bump package.json versions
|
|
run: |
|
|
for DIR in $DIRS; do
|
|
pnpm version -C "$DIR" --no-git-tag-version "${VERSION#v}"
|
|
git add "$DIR"/package.json
|
|
done
|
|
env:
|
|
DIRS: ${{ inputs.version-dirs || inputs.dist-dir }}
|
|
|
|
- name: Add to CHANGELOG.md
|
|
if: inputs.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 "$RELEASE_NOTES"
|
|
echo ""
|
|
} > CHANGELOG.md
|
|
|
|
cat CHANGELOG.md.old >> CHANGELOG.md
|
|
rm CHANGELOG.md.old
|
|
git add CHANGELOG.md
|
|
env:
|
|
RELEASE_NOTES: ${{ steps.draft-release.outputs.body }}
|
|
|
|
- name: Commit changes
|
|
run: git commit -m "$VERSION"
|
|
|
|
- name: Build assets
|
|
if: steps.prepare.outputs.has-dist-script == '1'
|
|
working-directory: ${{ inputs.dist-dir }}
|
|
run: DIST_VERSION="$VERSION" pnpm dist
|
|
|
|
- name: Upload release assets & signatures
|
|
if: inputs.asset-path
|
|
uses: ./.action-repo/.github/actions/upload-release-assets
|
|
with:
|
|
gpg-fingerprint: ${{ inputs.gpg-fingerprint }}
|
|
upload-url: ${{ steps.draft-release.outputs.upload_url }}
|
|
asset-path: ${{ inputs.dist-dir }}/${{ inputs.asset-path }}
|
|
|
|
- name: Create signed tag
|
|
if: inputs.gpg-fingerprint
|
|
run: |
|
|
GIT_COMMITTER_EMAIL="$SIGNING_ID" GPG_TTY=$(tty) git tag -u "$SIGNING_ID" -m "Release $VERSION" "$VERSION"
|
|
env:
|
|
SIGNING_ID: ${{ steps.gpg.outputs.email }}
|
|
|
|
- name: Generate & upload tarball signature
|
|
if: inputs.gpg-fingerprint
|
|
uses: ./.action-repo/.github/actions/sign-release-tarball
|
|
with:
|
|
gpg-fingerprint: ${{ inputs.gpg-fingerprint }}
|
|
upload-url: ${{ steps.draft-release.outputs.upload_url }}
|
|
|
|
# We defer pushing changes until after the release assets are built,
|
|
# signed & uploaded to improve the atomicity of this action.
|
|
- name: Push changes to staging
|
|
run: |
|
|
git push origin staging $TAG
|
|
git reset --hard
|
|
env:
|
|
TAG: ${{ inputs.gpg-fingerprint && env.VERSION || '' }}
|
|
|
|
- name: Validate tarball signature
|
|
if: inputs.gpg-fingerprint
|
|
run: |
|
|
wget https://github.com/$GITHUB_REPOSITORY/archive/refs/tags/$VERSION.tar.gz
|
|
gpg --verify "$VERSION.tar.gz.asc" "$VERSION.tar.gz"
|
|
|
|
- name: Validate release has expected assets
|
|
if: inputs.expected-asset-count
|
|
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
|
|
env:
|
|
RELEASE_ID: ${{ steps.draft-release.outputs.id }}
|
|
EXPECTED_ASSET_COUNT: ${{ inputs.expected-asset-count }}
|
|
with:
|
|
retries: 3
|
|
script: |
|
|
const { RELEASE_ID: release_id, EXPECTED_ASSET_COUNT } = process.env;
|
|
const { owner, repo } = context.repo;
|
|
|
|
const { data: release } = await github.rest.repos.getRelease({
|
|
owner,
|
|
repo,
|
|
release_id,
|
|
});
|
|
|
|
if (release.assets.length !== parseInt(EXPECTED_ASSET_COUNT, 10)) {
|
|
core.setFailed(`Found ${release.assets.length} assets but expected ${EXPECTED_ASSET_COUNT}`);
|
|
}
|
|
|
|
- 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@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
|
|
env:
|
|
RELEASE_ID: ${{ steps.draft-release.outputs.id }}
|
|
FINAL: ${{ inputs.final }}
|
|
with:
|
|
retries: 3
|
|
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
|
script: |
|
|
const { RELEASE_ID: release_id, RELEASE_NOTES, VERSION, FINAL } = process.env;
|
|
const { owner, repo } = context.repo;
|
|
|
|
const opts = {
|
|
owner,
|
|
repo,
|
|
release_id,
|
|
tag_name: VERSION,
|
|
name: VERSION,
|
|
draft: false,
|
|
body: RELEASE_NOTES,
|
|
};
|
|
|
|
if (FINAL == "true") {
|
|
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 # zizmor: ignore[unpinned-uses]
|
|
with:
|
|
dir: ${{ inputs.dist-dir }}
|
|
permissions:
|
|
contents: read
|
|
id-token: write
|
|
|
|
post-release:
|
|
name: Post release steps
|
|
needs: release
|
|
runs-on: ubuntu-24.04
|
|
permissions:
|
|
issues: write
|
|
steps:
|
|
- id: repository
|
|
run: echo "REPO=${GITHUB_REPOSITORY#*/}" >> $GITHUB_OUTPUT
|
|
|
|
- name: Advance release blocker labels
|
|
uses: garganshu/github-label-updater@3770d15ebfed2fe2cb06a241047bc340f774a7d1 # v1.0.0
|
|
with:
|
|
owner: ${{ github.repository_owner }}
|
|
repo: ${{ steps.repository.outputs.REPO }}
|
|
token: ${{ secrets.GITHUB_TOKEN }}
|
|
filter-labels: X-Upcoming-Release-Blocker
|
|
remove-labels: X-Upcoming-Release-Blocker
|
|
add-labels: X-Release-Blocker
|
|
|
|
# - name: Wait for master->develop gitflow merge
|
|
# if: inputs.final
|
|
# uses: t3chguy/wait-on-check-action@18541021811b56544d90e0f073401c2b99e249d6 # fork
|
|
# with:
|
|
# ref: master
|
|
# repo-token: ${{ secrets.GITHUB_TOKEN }}
|
|
# wait-interval: 10
|
|
# check-name: merge
|
|
# allowed-conclusions: success
|