Skip to content

release-plz

release-plz #242

Workflow file for this run

name: 'release-plz'
on:
# PR 作成
workflow_dispatch:
push:
branches:
- main
schedule:
# AM 6:00(JST)
- cron: '0 21 * * *'
# Release 作成
pull_request:
branches:
- main
types:
- closed
paths:
- '.github/release-please-manifest.json'
concurrency:
group: release-plz
jobs:
create-pr:
if: ${{ github.event_name != 'pull_request' && !contains(github.event.head_commit.message, 'workflows/release') }}
runs-on: ubuntu-24.04
timeout-minutes: 15
steps:
# https://github.com/marketplace/actions/checkout
- name: Checkout
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
# https://github.com/marketplace/actions/create-github-app-token
- name: Create GitHub App Token
uses: actions/create-github-app-token@5d869da34e18e7287c1daad50e0b8ea0f506ce69 # v1.11.0
id: app-token
with:
app-id: ${{ vars.BOT_APP_ID }}
private-key: ${{ secrets.BOT_PRIVATE_KEY }}
- name: Get new version
id: resolve-versions
uses: ./.github/actions/resolve-versions
with:
github-token: ${{ steps.app-token.outputs.token }}
# https://github.com/marketplace/actions/github-script
- name: Generate release notes
id: generate_notes
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
github-token: ${{ steps.app-token.outputs.token }}
result-encoding: string
script: |
const script = require('./.github/scripts/generate-release-note-body.cjs');
return await script({
github,
context,
version: '${{ steps.resolve-versions.outputs.new-version }}'
});
# https://github.com/marketplace/actions/github-script
- name: Existing branch
id: existing-branch
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
github-token: ${{ steps.app-token.outputs.token }}
result-encoding: json
script: |
const newVersion = '${{ steps.resolve-versions.outputs.new-version }}';
try {
const { data } = await github.rest.git.getRef({
...context.repo,
ref: `heads/workflows/release/v${newVersion}`,
});
console.log(`data: ${JSON.stringify(data)}`);
return data;
} catch (error) {
console.log(`error: ${error}`);
return null;
}
# https://github.com/marketplace/actions/github-script
- name: Create pull request
if: ${{ steps.existing-branch.outputs.result == 'null' }}
id: create_pr
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
github-token: ${{ steps.app-token.outputs.token }}
script: |
const fs = require('fs');
const newVersion = '${{ steps.resolve-versions.outputs.new-version }}';
const branchName = `workflows/release/v${newVersion}`;
// Create a new branch
await github.rest.git.createRef({
...context.repo,
ref: `refs/heads/${branchName}`,
sha: context.sha,
});
const manifestFilePath = '.github/release-please-manifest.json';
if (!fs.existsSync(manifestFilePath)) {
throw new Error(`File not found: ${manifestFilePath}`);
}
const content = fs.readFileSync(manifestFilePath, 'utf8');
const manifest = JSON.parse(content);
manifest["."] = newVersion;
const newContent = Buffer.from(JSON.stringify(manifest, null, 2)).toString('base64');
// Get the current SHA of the file
const { data: file } = await github.rest.repos.getContent({
...context.repo,
path: manifestFilePath,
ref: branchName,
});
// Update the file in the new branch
await github.rest.repos.createOrUpdateFileContents({
...context.repo,
path: manifestFilePath,
message: `chore: release ${newVersion}`,
content: newContent,
sha: file.sha,
branch: branchName,
});
// Create a pull request
const pr = await github.rest.pulls.create({
...context.repo,
title: `chore: release ${newVersion}`,
head: branchName,
base: 'main',
body: `${{ steps.generate_notes.outputs.result }}`,
});
return pr.data.html_url;
- name: Display PR URL
if: ${{ steps.existing-branch.outputs.result == 'null' }}
run: |
echo "Pull Request URL: ${{ steps.create_pr.outputs.result }}"
# https://github.com/marketplace/actions/github-script
- name: Update pull request
if: ${{ steps.existing-branch.outputs.result != 'null' }}
id: update-pr
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
github-token: ${{ steps.app-token.outputs.token }}
script: |
const fs = require('fs');
const mainRef = await github.rest.git.getRef({
...context.repo,
ref: 'heads/main',
});
// Update branch
const newVersion = '${{ steps.resolve-versions.outputs.new-version }}';
const branchName = `workflows/release/v${newVersion}`;
await github.rest.git.updateRef({
...context.repo,
ref: `heads/${branchName}`,
sha: mainRef.data.object.sha,
force: true,
});
const manifestFilePath = '.github/release-please-manifest.json';
if (!fs.existsSync(manifestFilePath)) {
throw new Error(`File not found: ${manifestFilePath}`);
}
const content = fs.readFileSync(manifestFilePath, 'utf8');
const manifest = JSON.parse(content);
manifest["."] = newVersion;
const newContent = Buffer.from(JSON.stringify(manifest, null, 2)).toString('base64');
// Get the current SHA of the file
const { data: file } = await github.rest.repos.getContent({
...context.repo,
path: manifestFilePath,
ref: branchName,
});
// Update the file in the branch
await github.rest.repos.createOrUpdateFileContents({
...context.repo,
path: manifestFilePath,
message: `chore: release ${newVersion}`,
content: newContent,
sha: file.sha,
branch: branchName,
});
// Get pull request
const { data } = await github.rest.pulls.list({
...context.repo,
state: 'open',
head: `${context.repo.owner}:${branchName}`,
});
// Update pull request
const pr = data[0];
console.log(`pr: ${JSON.stringify(pr)}`);
await github.rest.pulls.update({
...context.repo,
pull_number: pr.number,
body: `${{ steps.generate_notes.outputs.result }}`,
});
return pr.html_url;
- name: Display PR URL
if: ${{ steps.existing-branch.outputs.result != 'null' }}
run: |
echo "Pull Request URL: ${{ steps.update-pr.outputs.result }}"
create-release:
if: ${{ github.event.pull_request.merged == true }}
runs-on: ubuntu-24.04
timeout-minutes: 15
steps:
# https://github.com/marketplace/actions/checkout
- name: Checkout
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
# https://github.com/marketplace/actions/create-github-app-token
- name: Create GitHub App Token
uses: actions/create-github-app-token@5d869da34e18e7287c1daad50e0b8ea0f506ce69 # v1.11.0
id: app-token
with:
app-id: ${{ vars.BOT_APP_ID }}
private-key: ${{ secrets.BOT_PRIVATE_KEY }}
- name: Get new version
id: resolve-versions
uses: ./.github/actions/resolve-versions
with:
github-token: ${{ steps.app-token.outputs.token }}
# https://github.com/marketplace/actions/github-script
- name: Create release
id: create-release
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
github-token: ${{ steps.app-token.outputs.token }}
result-encoding: string
script: |
const releaseVersion = '${{ steps.resolve-versions.outputs.current-version }}';
const release = await github.rest.repos.createRelease({
...context.repo,
tag_name: `v${releaseVersion}`,
generate_release_notes: true,
});
return release.data.html_url;
# https://github.com/marketplace/actions/github-script
- name: Comment on PR
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
github-token: ${{ steps.app-token.outputs.token }}
script: |
const releaseHtmlUrl = '${{ steps.create-release.outputs.result }}';
await github.rest.issues.createComment({
...context.repo,
issue_number: context.payload.number,
body: `:robot: Release is at ${releaseHtmlUrl} :sunflower:`
});