Merge pull request #113 from acid-info/release-workflow

ci: add release workflows
This commit is contained in:
jeangovil
2023-10-09 11:06:05 +03:30
committed by GitHub
5 changed files with 481 additions and 0 deletions
+54
View File
@@ -0,0 +1,54 @@
name: Canary Release
on:
pull_request:
concurrency:
group: ${{ github.workflow }}
cancel-in-progress: false
jobs:
publish-canary:
if: startsWith(github.head_ref, 'topic-')
runs-on: ubuntu-latest
steps:
- name: Get branch name
shell: bash
run: echo "name=$(echo $GITHUB_HEAD_REF | sed 's/refs\/heads\///' | tr '/' '-')" >> $GITHUB_OUTPUT
id: branch_name
- uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: 1
ref: ${{ github.event.pull_request.head.sha }}
- uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'yarn'
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Publish
id: publish
run: |
echo ".npmrc" >> .git/info/exclude
echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > .npmrc
mkdir ${{ runner.temp }}/${{ steps.branch_name.outputs.name }}
yarn lerna publish prerelease --canary --no-private --no-verify-access --yes --exact --dist-tag=${{ steps.branch_name.outputs.name }} --preid=${{ steps.branch_name.outputs.name }} --summary-file=${{ runner.temp }}/${{ steps.branch_name.outputs.name }}
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
- uses: actions/github-script@v6
with:
github-token: ${{secrets.GITHUB_TOKEN}}
script: |
const fs = require('fs');
const summary = JSON.parse(fs.readFileSync('${{ runner.temp }}/${{ steps.branch_name.outputs.name }}/lerna-publish-summary.json', 'utf8'));
const packages = summary.map(pkg => `**${pkg.packageName}@${pkg.version}**\n\`\`\`bash\nyarn add ${pkg.packageName}@${{ steps.branch_name.outputs.name }}\n\`\`\``).join('\n');
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `🎉 Canary Release!\n\n${packages}`
})
+116
View File
@@ -0,0 +1,116 @@
name: Prerelease
on:
push:
branches:
- 'main'
concurrency:
group: ${{ github.workflow }}
cancel-in-progress: true
jobs:
prerelease:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: 1
- name: Extract version from lerna.json
run: echo "value=$(jq .version lerna.json -r)" >> $GITHUB_OUTPUT
id: current_version
- name: Determine Prerelease Preid
shell: bash
run: echo "value=$([[ ${{ steps.current_version.outputs.value }} =~ beta ]] && echo "beta" || echo "alpha")" >> $GITHUB_OUTPUT
id: preid
- uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'yarn'
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Check for changed packages
id: changes
run: |
error_filename="${{ runner.temp }}/changes_errors.log";
changes=$(echo $(yarn -s lerna changed --json --loglevel 2>>$error_filename) 2>>$error_filename);
cat $error_filename;
count=$([[ -n $changes ]] && echo $(echo $changes | jq '. | map(select(.private == false)) | length')) || echo 0
changed=$([[ $changes > 0 ]] && echo "true" || echo "false")
echo "changes=$count" >> $GITHUB_OUTPUT
echo "changed=$changed" >> $GITHUB_OUTPUT
echo "changes: $changes - changed: $changed"
- name: Publish
id: publish
if: ${{ steps.changes.outputs.changed == 'true' }}
run: |
git config --global user.name 'github-actions'
git config --global user.email 'github-actions@users.noreply.github.com'
echo ".npmrc" >> .git/info/exclude
echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > .npmrc
yarn lerna version prerelease --no-private --conventional-commits --conventional-prerelease --preid=${{ steps.preid.outputs.value }} --yes
yarn lerna publish from-git --summary-file=${{ runner.temp }} --yes
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Run release-pr.yaml workflow
if: ${{ steps.changes.outputs.changed == 'true' }}
run: |
tag=$(git describe --tags $(git rev-list --tags --max-count=1))
echo "${{ runner.temp }}/lerna-publish-summary.json";
if [[ -f "${{ runner.temp }}/lerna-publish-summary.json" ]]; then
gh workflow run release-pr.yml --ref $tag;
fi;
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Get release commit
if: ${{ steps.changes.outputs.changed == 'true' }}
shell: bash
run: echo "sha=$(git rev-parse --verify HEAD)" >> $GITHUB_OUTPUT
id: release_commit
- uses: actions/github-script@v6
if: ${{ steps.changes.outputs.changed == 'true' }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const fs = require("fs/promises");
let summary = null;
try {
summary = await fs.readFile(
"${{ runner.temp }}/lerna-publish-summary.json",
"utf8"
);
} catch {
console.log("No new releases!");
}
if (!summary) return;
summary = JSON.parse(summary);
const packages = summary
.map(
(pkg) =>
`**${pkg.packageName}@${pkg.version}**\n\`\`\`bash\nyarn add ${pkg.packageName}@${pkg.version}\n\`\`\``
)
.join("\n");
const preid = "${{ steps.preid.outputs.value }}";
github.rest.repos.createCommitComment({
commit_sha: "${{ steps.release_commit.outputs.sha }}",
owner: context.repo.owner,
repo: context.repo.repo,
body: `🎉 ${preid === 'alpha' ? 'Alpha' : 'Beta'} Release!\n\n${packages}`,
});
+81
View File
@@ -0,0 +1,81 @@
name: Publish
on:
pull_request:
branches:
- 'main'
types:
- closed
concurrency:
group: ${{ github.workflow }}
cancel-in-progress: false
jobs:
publish:
if: ${{ (github.head_ref == 'release-stable' || github.head_ref == 'release-beta') && github.event.pull_request.merged == true }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: 1
- name: Extract version from lerna.json
run: echo "value=$(jq .version lerna.json -r)" >> $GITHUB_OUTPUT
id: current_version
- name: Determine Release type
shell: bash
run: echo "value=$([[ ${{ steps.current_version.outputs.value }} =~ beta ]] && echo "beta" || echo "stable")" >> $GITHUB_OUTPUT
id: release_type
- uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'yarn'
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Bump versions
id: bump
run: |
git config --global user.name 'github-actions';
git config --global user.email 'github-actions@users.noreply.github.com';
echo ".npmrc" >> .git/info/exclude
echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > .npmrc;
yarn lerna publish from-package --summary-file=${{ runner.temp }}/ --yes
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Get release commit
shell: bash
run: |
COMMIT_HASH=$(git rev-parse --verify HEAD);
echo "sha=$COMMIT_HASH" >> $GITHUB_OUTPUT
id: release_commit
- uses: actions/github-script@v6
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const fs = require('fs');
const releaseType = "${{ steps.release_type.outputs.value }}";
const summary = JSON.parse(fs.readFileSync('${{ runner.temp }}/lerna-publish-summary.json', 'utf8'));
const packages = summary.map(pkg => `**${pkg.packageName}@${pkg.version}**\n\`\`\`bash\nyarn add ${pkg.packageName}@${{ steps.branch_name.outputs.name }}\n\`\`\``).join('\n');
const body = `🎉 ${releaseType === 'stable' ? "Stable" : "Beta"} Release!\n\n${packages}`
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
github.rest.repos.createCommitComment({
commit_sha: "${{ steps.release_commit.outputs.sha }}",
owner: context.repo.owner,
repo: context.repo.repo,
body,
});
+157
View File
@@ -0,0 +1,157 @@
name: Release PR
on:
push:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+-beta.[0-9]+'
- 'v[0-9]+.[0-9]+.[0-9]+-alpha.[0-9]+'
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}
cancel-in-progress: true
jobs:
delete-release-prs:
runs-on: ubuntu-latest
steps:
- uses: actions/github-script@v6
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const { data: pullRequests } = await github.rest.pulls.list({
owner: context.repo.owner,
repo: context.repo.repo,
state: "open",
});
for (const pr of pullRequests) {
if (
(pr.head.ref === "release-beta" || pr.head.ref === "release-stable") &&
pr.user.login.includes("github-actions")
) {
await github.rest.pulls.update({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: pr.number,
state: "closed",
});
console.log(`Closed PR #${pr.number}`);
}
}
create-release-pr:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: 1
ref: main
- name: Extract version from lerna.json
run: echo "value=$(jq .version lerna.json -r)" >> $GITHUB_OUTPUT
id: current_version
- name: Determine Release type
run: echo "value=$([[ ${{ steps.current_version.outputs.value }} =~ alpha ]] && echo "beta" || echo "stable")" >> $GITHUB_OUTPUT
id: release_type
- uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'yarn'
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Bump versions
id: bump
run: |
git config --global user.name 'github-actions';
git config --global user.email 'github-actions@users.noreply.github.com';
echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > .npmrc;
mkdir ${{ runner.temp }}/main;
export type='${{ steps.release_type.outputs.value }}';
export branch=release-$type;
echo "RELEASE_BRANCH=$branch" >> $GITHUB_ENV;
git switch -C $branch;
if [[ $type == 'beta' ]]; then
out=$(yarn -s lerna version prerelease --no-private --conventional-commits --conventional-prerelease --preid=beta --no-git-tag-version --force-publish --yes);
else
out=$(yarn -s lerna version --conventional-commits --conventional-graduate --no-git-tag-version --yes);
fi;
changes=$(echo "$out" | sed -n '/Changes:/,$p' | sed -n '/^ - .* => .*$/p');
echo "changes<<EOF" >> $GITHUB_OUTPUT;
echo "$changes" >> $GITHUB_OUTPUT;
echo "EOF" >> $GITHUB_OUTPUT;
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Extract version from lerna.json
run: echo "value=$(jq .version lerna.json -r)" >> $GITHUB_OUTPUT
id: next_version
- name: Commit changes
run: |
git add .;
git restore --staged .npmrc;
git commit -m "chore: release v${{ steps.next_version.outputs.value }}";
git push origin $RELEASE_BRANCH --force;
- name: Get release commit
run: |
COMMIT_HASH=$(git rev-parse --verify HEAD);
COMMIT_MESSAGE=$(git log --format=%B -n 1 $COMMIT_HASH);
echo "sha=$COMMIT_HASH" >> $GITHUB_OUTPUT
echo "head=$RELEASE_BRANCH" >> $GITHUB_OUTPUT
echo "message=$COMMIT_MESSAGE" >> $GITHUB_OUTPUT
id: release_commit
- name: Find latest stable release
id: latest_stable_release
run: |
echo "tag=$(git tag | grep -v -- "-alpha" | grep -v -- "-beta" | sort -V | tail -2 | head -1)" > $GITHUB_OUTPUT;
- name: Generate changelog
id: changelog
run: |
# TODO
env:
GITHUB_AUTH: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/github-script@v6
id: pr
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const changes = "${{ steps.bump.outputs.changes }}";
const type = "${{ steps.release_type.outputs.value }}";
const head = "${{ steps.release_commit.outputs.head }}";
const title = "${{ steps.release_commit.outputs.message }}";
let body = '';
body += `This PR will bump the following packages:\n`
body += `\`\`\`\n${changes}\n\`\`\``;
body += `\n\n`;
body += `Please review and test the code, before merging this PR. You can also check the changelog for more details on what has changed.\n\n`
body += `**Warning**: Once you merge this PR, the changes will be published to the npm registry and cannot be undone. Please make sure you are confident about the quality and stability of the code before publishing.`
const res = await github.rest.pulls.create({
body,
head,
title,
base: "main",
repo: context.repo.repo,
owner: context.repo.owner,
});
const { number } = res.data;
core.setOutput('number', number);
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: number,
labels: [`${type}-release`],
});
@@ -0,0 +1,73 @@
name: Remove Canary Releases
on:
schedule:
- cron: '0 0 * * *'
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}
cancel-in-progress: false
jobs:
remove-canary-releases:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Authenticate with NPM
run: |
echo ".npmrc" >> .git/info/exclude
echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > .npmrc
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
- uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'yarn'
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Get package names
id: packages
run: |
packages=$(yarn -s lerna list --json --loglevel error | jq '.[]["name"]')
echo "name<<EOF" >> $GITHUB_OUTPUT
echo $packages >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
cat $GITHUB_OUTPUT
- name: List merged pull requests
id: merged_branches
uses: actions/github-script@v6
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const response = await github.rest.pulls.list({
owner: context.repo.owner,
repo: context.repo.repo,
state: "closed",
base: "main",
head: "topic-*",
});
console.log(response.data.map(pr => pr.head.ref))
const prs = response.data
.filter((pr) => !!pr.merged_at)
.filter((pr) => +new Date() - new Date(pr.merged_at) > 24 * 60 * 60 * 1000);
const branches = prs.map((pr) => pr.head.ref);
core.setOutput('branches', branches.join("\n"));
- name: Remove canary releases
run: |
packages=$(echo "${{ steps.packages.outputs.name }}" | tr -d '"')
branches=$(echo "${{ steps.merged_branches.outputs.branches }}")
for package in $packages; do
for branch in $branches; do
npm view $package dist-tags.$branch | xargs -i -d '\n' sh -c "npm unpublish $package@{} --force 2>&1 || true"
npm dist-tag rm $package $branch 2>&1 || true
done
done