From 7cb05b20c4f9ccec17de1fb78ac65268f47b9418 Mon Sep 17 00:00:00 2001 From: Philipp Kief Date: Wed, 13 Nov 2024 15:10:39 +0100 Subject: [PATCH] fix(workflows): changelog generation in release process (#2704) --- .github/workflows/release.yml | 52 ++++------- changelog.config.ts | 18 ---- package.json | 1 - src/scripts/generateChangelog.ts | 148 ------------------------------- 4 files changed, 17 insertions(+), 202 deletions(-) delete mode 100644 changelog.config.ts delete mode 100644 src/scripts/generateChangelog.ts diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c575dff228..06e0fb2ef1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -2,16 +2,6 @@ name: 🚀 Release + Publish on: workflow_dispatch: - inputs: - versionChange: - type: choice - description: Select the version change - required: true - default: "minor" - options: - - major - - minor - - patch permissions: id-token: write @@ -20,8 +10,6 @@ permissions: jobs: release: runs-on: ubuntu-latest - env: - VERSION_CHANGE: ${{ github.event.inputs.versionChange }} permissions: contents: write @@ -29,7 +17,8 @@ jobs: attestations: write steps: - - uses: actions/create-github-app-token@5d869da34e18e7287c1daad50e0b8ea0f506ce69 # v1.11.0 + - name: ✅ Use App Token for the Bot which is allowed to create releases + uses: actions/create-github-app-token@5d869da34e18e7287c1daad50e0b8ea0f506ce69 # v1.11.0 id: app-token with: app-id: ${{ vars.BOT_APP_ID }} @@ -52,13 +41,19 @@ jobs: bun install --frozen-lockfile bun add -g npm - - name: 🔄 Update version + - name: 🔧 Configure Git run: | git config user.name 'github-actions[bot]' git config user.email 'github-actions[bot]@users.noreply.github.com' - git config --global push.followTags true - npm version ${{ env.VERSION_CHANGE }} -m "Release %s" + + - name: 🚀 Prepare release + run: bun run preversion + + - name: 📜 Generate changelog and release notes + run: | + bunx changelogen --release --push + bunx changelogen github release --token ${{ secrets.GITHUB_TOKEN }} - name: 📝 Get metadata run: | @@ -70,13 +65,6 @@ jobs: echo "NAME=$NAME" >> $GITHUB_ENV echo "DISPLAY_NAME=$DISPLAY_NAME" >> $GITHUB_ENV - - name: 📜 Generate changelog and release notes - run: | - release_notes="$(bun run changelog --version ${{ env.VERSION }})" - echo "RELEASE_NOTES=$release_notes" >> $GITHUB_ENV - - git add CHANGELOG.md - - name: 🛠️ Build extension run: bunx @vscode/vsce package @@ -86,18 +74,6 @@ jobs: with: subject-path: "${{ env.NAME }}-${{ env.VERSION }}.vsix" - - name: 📌 Push tags - run: git push - - - name: 🚀 Release ${{ env.VERSION }} - uses: softprops/action-gh-release@01570a1f39cb168c169c802c3bceb9e93fb10974 # v2.1.0 - with: - files: ${{ env.NAME }}-${{ env.VERSION }}.vsix - tag_name: v${{ env.VERSION }} - body: ${{ env.RELEASE_NOTES }} - name: ${{ env.DISPLAY_NAME }} v${{ env.VERSION }} - generate_release_notes: false - - name: 🌐 Publish to Open VSX Registry uses: HaaLeo/publish-vscode-extension@28e2d3f5817fccf23c1f219eb0cecc903132d1a2 # v1.6.2 with: @@ -115,3 +91,9 @@ jobs: run: | npm set "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" npm publish --provenance --access public + + - name: ⬆️ Upload VSIX to GitHub release + run: | + gh release upload v${{ env.VERSION }} ${{ env.NAME }}-${{ env.VERSION }}.vsix + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/changelog.config.ts b/changelog.config.ts deleted file mode 100644 index 75e08d0253..0000000000 --- a/changelog.config.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { type ChangelogConfig } from 'changelogen'; - -/** - * Changelogen configuration - * - * @see https://github.com/unjs/changelogen - * @see https://github.com/unjs/changelogen/blob/3c3adbba396ae2b6aafc2f1eb58a25689bf235d4/src/config.ts - */ -const ChangelogenConfig: Partial = { - types: { - feat: { - title: '✨ Enhancements', - }, - }, - output: 'CHANGELOG.md', -}; - -export default ChangelogenConfig; diff --git a/package.json b/package.json index 807896dfa9..26d67becb2 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,6 @@ "postcompile": "bun run compile:declarations && bun run generateJson && bun run generateClones && bun run check", "build": "bun run compile && bun ./build/build-with-esbuild.ts", "watch": "bun ./build/watch-with-esbuild.ts", - "changelog": "bun --bun ./src/scripts/generateChangelog.ts", "check-colors": "bun ./src/scripts/svg/checkSvgColors.ts", "check": "bun ./src/scripts/icons/checks/run.ts", "contributors": "bun ./src/scripts/contributors/contributors.ts", diff --git a/src/scripts/generateChangelog.ts b/src/scripts/generateChangelog.ts deleted file mode 100644 index 4f48d41710..0000000000 --- a/src/scripts/generateChangelog.ts +++ /dev/null @@ -1,148 +0,0 @@ -import fs from 'fs'; -import { - type ResolvedChangelogConfig, - generateMarkDown, - getCurrentGitTag, - getGitDiff, - getLastGitTag, - loadChangelogConfig, - parseCommits, -} from 'changelogen'; -import ChangelogenConfig from '../../changelog.config'; - -/** - * Parses the command line arguments to extract the version string. - * - * @returns The version string if found, otherwise `undefined`. - */ -function getVersionFromCLI(): string | undefined { - const args = process.argv.slice(2); - - let version: string | undefined; - - for (let i = 0; i < args.length; i++) { - const arg = args[i]; - if (arg === '--version' || arg === '-v') { - version = args[i + 1]; - } else if (arg.startsWith('--version=')) { - version = arg.split('=')[1]; - } else if (!version && !arg.startsWith('-')) { - version = arg; - } - } - - return version; -} - -/** - * Updates the changelog file with the provided changelog content. - * - * @param changelog - The new changelog content to be added. - * @param config - The resolved configuration for the changelog. - */ -async function updateChangelogFile( - changelog: string, - config: ResolvedChangelogConfig -): Promise { - const changelogFilePath: string = - typeof config.output === 'string' ? config.output : ''; - - if (!changelogFilePath || !fs.existsSync(changelogFilePath)) { - throw new Error(`Invalid output path in config: ${changelogFilePath}`); - } - - // Check if the output path is writable - let changelogMarkdown: string = await loadChangelogFile(changelogFilePath); - - // Update the changelog with the new release notes - - /** The last version in the changelog */ - const lastEntry = changelogMarkdown.match(/^###?\s+.*$/m); - - if (lastEntry) { - // If there is a last version entry, add the new changelog on top of it - changelogMarkdown = - changelogMarkdown.slice(0, lastEntry.index) + - changelog + - '\n\n' + - changelogMarkdown.slice(lastEntry.index); - } else { - // If there is no last entry, just add the new changelog to the top - const changelogHeader = '# Changelog'; - const headerIndex = changelogMarkdown.indexOf(changelogHeader); - - changelogMarkdown = - changelogMarkdown.slice(0, headerIndex + changelogHeader.length) + - '\n\n' + - changelog + - changelogMarkdown.slice(headerIndex + changelogHeader.length); - } - - // Write the updated changelog to the file - await Bun.write(changelogFilePath, changelogMarkdown); -} - -/** - * Loads the changelog file and returns the markdown content. - * - * @param changelogFilePath - The path to the changelog file. - * @returns The markdown content of the changelog file. - */ -async function loadChangelogFile(changelogFilePath: string) { - try { - fs.accessSync(changelogFilePath, fs.constants.W_OK); - } catch { - throw new Error(`Output path is not writable: ${changelogFilePath}`); - } - - /** Markdown of the current changelog file */ - let changelogMarkdown: string; - - // Read the changelog file - try { - changelogMarkdown = await Bun.file(changelogFilePath).text(); - } catch (error) { - throw new Error(`Error reading changelog file: ${error}`); - } - return changelogMarkdown; -} - -/** - * Generates a changelog based on the git history using `changelogen` and updates the changelog file. - * - * @returns A promise that resolves when the changelog generation is complete. - */ -async function generateChangelog(): Promise { - const version: string | undefined = getVersionFromCLI(); - - const currentTag = getCurrentGitTag(); - const lastTag = await getLastGitTag(); - - /** The changelogen configuration */ - const config = await loadChangelogConfig(process.cwd(), { - ...ChangelogenConfig, - - // 'v1.2.3'.slice(1) => '1.2.3' - newVersion: version || currentTag.slice(1), - }); - - // Get the git diff between the last and current tags - const rawGitCommits = await getGitDiff(lastTag); - const newCommits = parseCommits(rawGitCommits, config); - - const generatedChangelog: string = await generateMarkDown(newCommits, config); - - /** Release notes from the changelog without the header */ - const releaseNotes: string = generatedChangelog - .split('\n') - .slice(3) - .join('\n'); - - // Write the release notes to the standard output for further processing in the CI/CD pipeline - process.stdout.write(releaseNotes); - - console.info(`Updating ${config.output}`); - updateChangelogFile(generatedChangelog, config); -} - -generateChangelog();