WIP
This commit is contained in:
parent
96459d240d
commit
42c7b1a0e4
121
.github/workflows/beta-release.yml
vendored
121
.github/workflows/beta-release.yml
vendored
@ -11,6 +11,11 @@ on:
|
||||
description: 'Previous version tag for changelog (e.g., 1.23.0)'
|
||||
required: true
|
||||
type: string
|
||||
dry_run:
|
||||
description: 'If true, the release will be a dry run without pushing changes'
|
||||
required: false
|
||||
type: boolean
|
||||
default: true
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
@ -41,95 +46,6 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: npm clean-install --no-fund
|
||||
|
||||
- name: Generate changelog
|
||||
id: changelog
|
||||
run: |
|
||||
echo "Generating changelog since ${{ inputs.previous_version }}"
|
||||
npm run generate-changelog ${{ inputs.previous_version }} > changelog-output.txt 2>&1
|
||||
cat changelog-output.txt
|
||||
|
||||
- name: Sort and categorize changelog with Copilot
|
||||
id: categorize
|
||||
run: |
|
||||
echo "Processing changelog with GitHub Copilot..."
|
||||
|
||||
# Extract the raw PR list from changelog output (before the template)
|
||||
sed -n '/^- #/p' changelog-output.txt > raw-changelog.txt
|
||||
|
||||
# Get the template/prompt
|
||||
sed -n '/LLM Task:/,$p' changelog-output.txt > changelog-prompt.txt
|
||||
|
||||
# Combine them into a single file for Copilot
|
||||
cat raw-changelog.txt > changelog-for-copilot.txt
|
||||
echo "" >> changelog-for-copilot.txt
|
||||
cat changelog-prompt.txt >> changelog-for-copilot.txt
|
||||
|
||||
echo "Changelog content prepared for Copilot categorization"
|
||||
cat changelog-for-copilot.txt
|
||||
|
||||
- name: Create formatted changelog
|
||||
run: |
|
||||
echo "# Changelog for ${{ inputs.version }}" > FORMATTED_CHANGELOG.md
|
||||
echo "" >> FORMATTED_CHANGELOG.md
|
||||
echo "**Note:** This changelog was generated from merged PRs since ${{ inputs.previous_version }}" >> FORMATTED_CHANGELOG.md
|
||||
echo "" >> FORMATTED_CHANGELOG.md
|
||||
echo "## Pull Requests" >> FORMATTED_CHANGELOG.md
|
||||
echo "" >> FORMATTED_CHANGELOG.md
|
||||
cat raw-changelog.txt >> FORMATTED_CHANGELOG.md
|
||||
echo "" >> FORMATTED_CHANGELOG.md
|
||||
echo "---" >> FORMATTED_CHANGELOG.md
|
||||
echo "" >> FORMATTED_CHANGELOG.md
|
||||
echo "**Instructions for manual categorization:**" >> FORMATTED_CHANGELOG.md
|
||||
cat changelog-prompt.txt >> FORMATTED_CHANGELOG.md
|
||||
|
||||
- name: Commit changelog
|
||||
run: |
|
||||
git add FORMATTED_CHANGELOG.md
|
||||
git commit -m "Add changelog for ${{ inputs.version }}"
|
||||
|
||||
- name: Push branch
|
||||
run: |
|
||||
git push origin release
|
||||
|
||||
- name: Create draft pull request
|
||||
id: create-pr
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
PR_URL=$(gh pr create \
|
||||
--base master \
|
||||
--head release \
|
||||
--title "Update to ${{ inputs.version }}" \
|
||||
--body "## Beta Release ${{ inputs.version }}
|
||||
|
||||
This PR prepares the beta release for version ${{ inputs.version }}.
|
||||
|
||||
### Release Steps Completed:
|
||||
- [x] Create draft pull request
|
||||
- [x] Generate changelog from ${{ inputs.previous_version }}
|
||||
- [ ] Manually categorize changelog (see comment below)
|
||||
- [ ] Run release-beta
|
||||
- [ ] Upload dist.tar.gz
|
||||
|
||||
### Next Steps:
|
||||
1. Review the changelog comment below
|
||||
2. Manually categorize the PRs using the template provided
|
||||
3. Run the release-beta build job by triggering it manually
|
||||
" \
|
||||
--draft)
|
||||
echo "pr_url=$PR_URL" >> $GITHUB_OUTPUT
|
||||
echo "PR created: $PR_URL"
|
||||
|
||||
# Extract PR number from URL
|
||||
PR_NUMBER=$(basename "$PR_URL")
|
||||
echo "pr_number=$PR_NUMBER" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Post changelog comment
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
gh pr comment ${{ steps.create-pr.outputs.pr_number }} --body-file FORMATTED_CHANGELOG.md
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@988b5a0280414f521da01fcc63a27aeeb4b104db # v3.6.1
|
||||
|
||||
@ -152,31 +68,14 @@ jobs:
|
||||
- name: Run release-beta
|
||||
env:
|
||||
RELEASE_BETA_VERSION: ${{ inputs.version }}
|
||||
PREVIOUS_VERSION: ${{ inputs.previous_version }}
|
||||
DRY_RUN: ${{ inputs.dry_run }}
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: npm run release-beta
|
||||
|
||||
- name: Create dist tarball
|
||||
- name: Push branch
|
||||
run: |
|
||||
if [ -d dist ]; then
|
||||
tar -zcvf dist.tar.gz dist
|
||||
else
|
||||
echo "Error: dist directory not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Upload dist.tar.gz to PR
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
# Upload the tarball as a release asset comment
|
||||
echo "Uploading dist.tar.gz to PR #${{ steps.create-pr.outputs.pr_number }}"
|
||||
|
||||
# Create a comment with instructions
|
||||
gh pr comment ${{ steps.create-pr.outputs.pr_number }} --body "## Distribution Archive
|
||||
|
||||
The \`dist.tar.gz\` archive has been created and is available as an artifact in this workflow run.
|
||||
|
||||
Download it from: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||||
"
|
||||
git push origin release
|
||||
|
||||
- name: Upload dist.tar.gz as artifact
|
||||
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||
|
||||
@ -52,60 +52,63 @@ async function main() {
|
||||
}
|
||||
|
||||
console.log(`Generating changelog since version ${previousVersion}...`);
|
||||
console.log(await generateChangelog(previousVersion));
|
||||
}
|
||||
|
||||
try {
|
||||
const prList = await getPullRequestList(previousVersion);
|
||||
const list = [];
|
||||
/**
|
||||
* Generate Changelog
|
||||
* @param {string} previousVersion Previous Version Tag
|
||||
* @returns {Promise<string>} Changelog Content
|
||||
*/
|
||||
export async function generateChangelog(previousVersion) {
|
||||
const prList = await getPullRequestList(previousVersion);
|
||||
const list = [];
|
||||
let content = "";
|
||||
|
||||
let i = 1;
|
||||
for (const pr of prList) {
|
||||
console.log(`Progress: ${i++}/${prList.length}`);
|
||||
let authorSet = await getAuthorList(pr.number);
|
||||
authorSet = await mainAuthorToFront(pr.author.login, authorSet);
|
||||
let i = 1;
|
||||
for (const pr of prList) {
|
||||
console.log(`Progress: ${i++}/${prList.length}`);
|
||||
let authorSet = await getAuthorList(pr.number);
|
||||
authorSet = await mainAuthorToFront(pr.author.login, authorSet);
|
||||
|
||||
if (mergeList.includes(pr.title)) {
|
||||
// Check if it is already in the list
|
||||
const existingItem = list.find(item => item.title === pr.title);
|
||||
if (existingItem) {
|
||||
existingItem.numbers.push(pr.number);
|
||||
for (const author of authorSet) {
|
||||
existingItem.authors.add(author);
|
||||
// Sort the authors
|
||||
existingItem.authors = new Set([ ...existingItem.authors ].sort((a, b) => a.localeCompare(b)));
|
||||
}
|
||||
continue;
|
||||
if (mergeList.includes(pr.title)) {
|
||||
// Check if it is already in the list
|
||||
const existingItem = list.find(item => item.title === pr.title);
|
||||
if (existingItem) {
|
||||
existingItem.numbers.push(pr.number);
|
||||
for (const author of authorSet) {
|
||||
existingItem.authors.add(author);
|
||||
// Sort the authors
|
||||
existingItem.authors = new Set([ ...existingItem.authors ].sort((a, b) => a.localeCompare(b)));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
const item = {
|
||||
numbers: [ pr.number ],
|
||||
title: pr.title,
|
||||
authors: authorSet,
|
||||
};
|
||||
|
||||
list.push(item);
|
||||
}
|
||||
|
||||
for (const item of list) {
|
||||
// Concat pr numbers into a string like #123 #456
|
||||
const prPart = item.numbers.map(num => `#${num}`).join(" ");
|
||||
const item = {
|
||||
numbers: [ pr.number ],
|
||||
title: pr.title,
|
||||
authors: authorSet,
|
||||
};
|
||||
|
||||
// Concat authors into a string like @user1 @user2
|
||||
let authorPart = [ ...item.authors ].map(author => `@${author}`).join(" ");
|
||||
|
||||
if (authorPart) {
|
||||
authorPart = `(Thanks ${authorPart})`;
|
||||
}
|
||||
|
||||
console.log(`- ${prPart} ${item.title} ${authorPart}`);
|
||||
}
|
||||
|
||||
console.log(template);
|
||||
|
||||
} catch (e) {
|
||||
console.error("Failed to get pull request list:", e);
|
||||
process.exit(1);
|
||||
list.push(item);
|
||||
}
|
||||
|
||||
for (const item of list) {
|
||||
// Concat pr numbers into a string like #123 #456
|
||||
const prPart = item.numbers.map(num => `#${num}`).join(" ");
|
||||
|
||||
// Concat authors into a string like @user1 @user2
|
||||
let authorPart = [ ...item.authors ].map(author => `@${author}`).join(" ");
|
||||
|
||||
if (authorPart) {
|
||||
authorPart = `(Thanks ${authorPart})`;
|
||||
}
|
||||
|
||||
content += `- ${prPart} ${item.title} ${authorPart}\n`;
|
||||
}
|
||||
|
||||
return content + "\n" + template;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -9,11 +9,19 @@ import {
|
||||
getRepoNames,
|
||||
execSync,
|
||||
checkReleaseBranch,
|
||||
createDistTarGz,
|
||||
createReleasePR,
|
||||
} from "./lib.mjs";
|
||||
import semver from "semver";
|
||||
|
||||
const repoNames = getRepoNames();
|
||||
const version = process.env.RELEASE_BETA_VERSION;
|
||||
const dryRun = process.env.DRY_RUN === "true";
|
||||
const previousVersion = process.env.RELEASE_PREVIOUS_VERSION;
|
||||
|
||||
if (dryRun) {
|
||||
console.log("Dry run mode enabled. No images will be pushed.");
|
||||
}
|
||||
|
||||
console.log("RELEASE_BETA_VERSION:", version);
|
||||
|
||||
@ -43,14 +51,29 @@ execSync("node ./extra/beta/update-version.js");
|
||||
// Build frontend dist
|
||||
buildDist();
|
||||
|
||||
// Build slim image (rootless)
|
||||
buildImage(repoNames, [ "beta-slim-rootless", ver(version, "slim-rootless") ], "rootless", "BASE_IMAGE=louislam/uptime-kuma:base2-slim");
|
||||
// TODO: Create Pull Request
|
||||
await createReleasePR(version, previousVersion, dryRun);
|
||||
|
||||
// Build full image (rootless)
|
||||
buildImage(repoNames, [ "beta-rootless", ver(version, "rootless") ], "rootless");
|
||||
if (!dryRun) {
|
||||
// Build slim image (rootless)
|
||||
buildImage(
|
||||
repoNames,
|
||||
["beta-slim-rootless", ver(version, "slim-rootless")],
|
||||
"rootless",
|
||||
"BASE_IMAGE=louislam/uptime-kuma:base2-slim"
|
||||
);
|
||||
|
||||
// Build slim image
|
||||
buildImage(repoNames, [ "beta-slim", ver(version, "slim") ], "release", "BASE_IMAGE=louislam/uptime-kuma:base2-slim");
|
||||
// Build full image (rootless)
|
||||
buildImage(repoNames, ["beta-rootless", ver(version, "rootless")], "rootless");
|
||||
|
||||
// Build full image
|
||||
buildImage(repoNames, [ "beta", version ], "release");
|
||||
// Build slim image
|
||||
buildImage(repoNames, ["beta-slim", ver(version, "slim")], "release", "BASE_IMAGE=louislam/uptime-kuma:base2-slim");
|
||||
|
||||
// Build full image
|
||||
buildImage(repoNames, ["beta", version], "release");
|
||||
} else {
|
||||
console.log("Dry run mode - skipping image build and push.");
|
||||
}
|
||||
|
||||
// TODO: Create
|
||||
await createDistTarGz();
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import "dotenv/config";
|
||||
import * as childProcess from "child_process";
|
||||
import semver from "semver";
|
||||
import {generateChangelog} from "../generate-changelog.mjs";
|
||||
|
||||
export const dryRun = process.env.RELEASE_DRY_RUN === "1";
|
||||
|
||||
@ -202,6 +203,7 @@ export function ver(version, identifier) {
|
||||
* @param {string} version Version
|
||||
* @param {string} githubToken GitHub token
|
||||
* @returns {void}
|
||||
* @deprecated
|
||||
*/
|
||||
export function uploadArtifacts(version, githubToken) {
|
||||
let args = [
|
||||
@ -262,3 +264,28 @@ export function checkReleaseBranch() {
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: similar to "tar -zcvf dist.tar.gz dist", but using nodejs
|
||||
*/
|
||||
export async function createDistTarGz() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Create a draft release PR
|
||||
* @param version
|
||||
* @param previousVersion
|
||||
* @param dryRun Still create the PR, but add "[DRY RUN]" to the title
|
||||
*/
|
||||
export async function createReleasePR(version, previousVersion, dryRun) {
|
||||
const changelog = await generateChangelog(previousVersion);
|
||||
|
||||
// TODO
|
||||
// gh pr create \
|
||||
// --title "Beta Release: ${{ inputs.version }}" \
|
||||
// --body "This PR prepares the beta release version ${{ inputs.version }}. \`dist.tar.gz\` : ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \
|
||||
// --base master \
|
||||
// --head release \
|
||||
// --draft
|
||||
}
|
||||
|
||||
1358
package-lock.json
generated
1358
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user