From a8b8db7412f284f6cfb9ba1b11323f7cc0453f81 Mon Sep 17 00:00:00 2001 From: Ben Miner Date: Fri, 26 Sep 2025 16:53:55 -0500 Subject: [PATCH 1/4] fix commit message changelog generation --- .github/workflows/auto-release.yml | 18 ++++++++++-------- .github/workflows/release.yml | 6 +++--- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/.github/workflows/auto-release.yml b/.github/workflows/auto-release.yml index 21922ce2a..a85dbb482 100644 --- a/.github/workflows/auto-release.yml +++ b/.github/workflows/auto-release.yml @@ -121,20 +121,22 @@ jobs: LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "") if [[ -z "$LAST_TAG" ]]; then - COMMITS=$(git log --pretty=format:"- %s" --no-merges) + git log --pretty=format:"- %s" --no-merges > /tmp/commits.txt else - COMMITS=$(git log ${LAST_TAG}..HEAD --pretty=format:"- %s" --no-merges) + git log ${LAST_TAG}..HEAD --pretty=format:"- %s" --no-merges > /tmp/commits.txt fi echo "Raw commits:" - echo "$COMMITS" - COMMITS_ESCAPED=$(echo "$COMMITS" | sed ':a;N;$!ba;s/\n/\\n/g' | sed 's/"/\\"/g') + cat /tmp/commits.txt + + # Use base64 encoding to safely pass commit messages through JSON + COMMITS_B64=$(base64 -w 0 /tmp/commits.txt) echo "commits<> $GITHUB_OUTPUT - echo "$COMMITS" >> $GITHUB_OUTPUT + cat /tmp/commits.txt >> $GITHUB_OUTPUT echo "EOF" >> $GITHUB_OUTPUT - echo "commits_json=$COMMITS_ESCAPED" >> $GITHUB_OUTPUT + echo "commits_b64=$COMMITS_B64" >> $GITHUB_OUTPUT - name: Amend commit with version run: | @@ -159,12 +161,12 @@ jobs: git tag -a "${TAG}" -m "${TAG_MESSAGE}" git push origin "${TAG}" - COMMIT_MESSAGES_JSON="${{ steps.commit_messages.outputs.commits_json }}" + COMMITS_B64="${{ steps.commit_messages.outputs.commits_b64 }}" curl -X POST \ -H "Accept: application/vnd.github.v3+json" \ -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ https://api.github.com/repos/${{ github.repository }}/dispatches \ - -d "{\"event_type\":\"release\",\"client_payload\":{\"tag\":\"${TAG}\",\"version\":\"${NEW_VERSION}\",\"commits\":\"${COMMIT_MESSAGES_JSON}\"}}" + -d "{\"event_type\":\"release\",\"client_payload\":{\"tag\":\"${TAG}\",\"version\":\"${NEW_VERSION}\",\"commits_b64\":\"${COMMITS_B64}\"}}" - name: Output summary run: | diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4f25f14c1..58795e0c7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -82,13 +82,13 @@ jobs: - name: Format commit messages for release id: changelog run: | - COMMITS="${{ github.event.client_payload.commits }}" + COMMITS_B64="${{ github.event.client_payload.commits_b64 }}" - if [ -z "$COMMITS" ]; then + if [ -z "$COMMITS_B64" ]; then echo "No commits provided in client_payload" FORMATTED_COMMITS="No changes listed" else - FORMATTED_COMMITS=$(echo "$COMMITS" | sed 's/\\n/\n/g') + FORMATTED_COMMITS=$(echo "$COMMITS_B64" | base64 -d) fi RELEASE_BODY=$(printf "## Changes in this release:\n\n%s\n\nReleased as %s" "$FORMATTED_COMMITS" "${{ github.event.client_payload.tag }}") From c9571db66441699ed75d2b56a912601d12b2476e Mon Sep 17 00:00:00 2001 From: Ben Miner Date: Fri, 26 Sep 2025 17:03:02 -0500 Subject: [PATCH 2/4] refactor release flow to be manual --- .../{auto-release.yml => manual-release.yml} | 156 +++++++++++++----- .github/workflows/release.yml | 118 ------------- 2 files changed, 116 insertions(+), 158 deletions(-) rename .github/workflows/{auto-release.yml => manual-release.yml} (53%) delete mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/auto-release.yml b/.github/workflows/manual-release.yml similarity index 53% rename from .github/workflows/auto-release.yml rename to .github/workflows/manual-release.yml index a85dbb482..fed29f816 100644 --- a/.github/workflows/auto-release.yml +++ b/.github/workflows/manual-release.yml @@ -1,15 +1,21 @@ -name: Auto Release +name: Manual Release on: - push: - branches: - - main - paths-ignore: - - "**.md" - - "website/**" - - "docs/**" - - ".github/**" - - "!.github/workflows/**" + workflow_dispatch: + inputs: + release_type: + description: "Type of release" + required: true + default: "patch" + type: choice + options: + - patch + - minor + - major + description: + description: "Release description (optional)" + required: false + type: string concurrency: group: ${{ github.workflow }}-main @@ -18,15 +24,16 @@ concurrency: permissions: contents: write actions: write + id-token: write jobs: - auto-release: - name: Auto Version Bump and Release + complete-release: + name: Complete Manual Release runs-on: ubuntu-latest - if: ${{ !contains(github.event.head_commit.message, '[v') && github.event.head_commit.author.name != 'GitHub Action' && !contains(github.event.head_commit.message, '] [v') }} permissions: contents: write actions: write + id-token: write steps: - name: Checkout code @@ -55,28 +62,12 @@ jobs: echo "current=${CURRENT_VERSION}" >> $GITHUB_OUTPUT echo "Current version: ${CURRENT_VERSION}" - - name: Determine version bump + - name: Set version bump type id: version_bump run: | - LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "") - - if [[ -z "$LAST_TAG" ]]; then - COMMITS=$(git log --pretty=format:"%s" --no-merges) - else - COMMITS=$(git log ${LAST_TAG}..HEAD --pretty=format:"%s" --no-merges) - fi - - BUMP_TYPE="patch" - - if echo "$COMMITS" | grep -qiE "(BREAKING CHANGE|!:|breaking:|major:|bump.*major)"; then - BUMP_TYPE="major" - elif echo "$COMMITS" | grep -qiE "(feat:|feature:|minor:|bump.*minor)"; then - BUMP_TYPE="minor" - else - BUMP_TYPE="patch" - fi - + BUMP_TYPE="${{ github.event.inputs.release_type }}" echo "bump_type=${BUMP_TYPE}" >> $GITHUB_OUTPUT + echo "Selected release type: ${BUMP_TYPE}" - name: Bump version id: bump_version @@ -148,7 +139,7 @@ jobs: git commit --amend -m "${NEW_MESSAGE}" git push --force-with-lease origin main - - name: Create tag and trigger release + - name: Create tag run: | TAG="${{ steps.bump_version.outputs.tag }}" NEW_VERSION="${{ steps.bump_version.outputs.new_version }}" @@ -161,19 +152,104 @@ jobs: git tag -a "${TAG}" -m "${TAG_MESSAGE}" git push origin "${TAG}" + - name: Verify version validation passed + env: + TYPE_GRAPHQL_VERSION: ${{ steps.bump_version.outputs.tag }} + run: | + echo "Verifying release for version: $TYPE_GRAPHQL_VERSION" + + if ! printf "%s\n" "$TYPE_GRAPHQL_VERSION" | grep -q -P '^v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-(alpha|beta|rc)\.(0|[1-9][0-9]*))?$'; then + printf '[ERROR]: Invalid version tag format (%s)\n' "$TYPE_GRAPHQL_VERSION" + exit 1 + fi + + echo "✅ Version tag format is valid" + + - name: Determine if version is prerelease + id: prerelease + env: + TYPE_GRAPHQL_VERSION: ${{ steps.bump_version.outputs.tag }} + run: | + _prerelease= + if printf "%s\n" "$TYPE_GRAPHQL_VERSION" | grep -q -P '^v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$'; then + _prerelease=false + else + _prerelease=true + fi + + printf 'value=%s\n' "$_prerelease" >> "$GITHUB_OUTPUT" + + - name: Setup Node.js for publishing + uses: actions/setup-node@v4 + with: + node-version: 22.x + registry-url: "https://registry.npmjs.org" + + - name: Install latest npm + run: | + npm install -g npm@latest + + - name: Install Dependencies + run: | + npm ci + + - name: Configure npm authentication + run: | + echo "//registry.npmjs.org/:_authToken=\${NPM_TOKEN}" > .npmrc + + - name: Prepare package + run: | + npm run prepublishOnly + env: + TYPE_GRAPHQL_REF: ${{ steps.bump_version.outputs.tag }} + + - name: Format commit messages for release + id: changelog + run: | COMMITS_B64="${{ steps.commit_messages.outputs.commits_b64 }}" - curl -X POST \ - -H "Accept: application/vnd.github.v3+json" \ - -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ - https://api.github.com/repos/${{ github.repository }}/dispatches \ - -d "{\"event_type\":\"release\",\"client_payload\":{\"tag\":\"${TAG}\",\"version\":\"${NEW_VERSION}\",\"commits_b64\":\"${COMMITS_B64}\"}}" + + if [ -z "$COMMITS_B64" ]; then + echo "No commits provided" + FORMATTED_COMMITS="No changes listed" + else + FORMATTED_COMMITS=$(echo "$COMMITS_B64" | base64 -d) + fi + + RELEASE_BODY=$(printf "## Changes in this release:\n\n%s\n\nReleased as %s" "$FORMATTED_COMMITS" "${{ steps.bump_version.outputs.tag }}") + + echo "changelog<> $GITHUB_OUTPUT + echo "$RELEASE_BODY" >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + tag_name: ${{ steps.bump_version.outputs.tag }} + body: ${{ steps.changelog.outputs.changelog }} + prerelease: ${{ steps.prerelease.outputs.value == 'true' }} + + - name: Publish to npm + env: + NPM_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }} + TYPE_GRAPHQL_PRERELEASE: ${{ steps.prerelease.outputs.value }} + run: | + _tag= + if [ "$TYPE_GRAPHQL_PRERELEASE" = "true" ]; then + _tag="next" + else + _tag="latest" + fi + + npm publish --ignore-scripts --access public --tag "$_tag" - name: Output summary run: | - echo "## 🚀 Auto Release Summary" >> $GITHUB_STEP_SUMMARY + echo "## 🚀 Manual Release Summary" >> $GITHUB_STEP_SUMMARY echo "- **Previous Version**: ${{ steps.current_version.outputs.current }}" >> $GITHUB_STEP_SUMMARY echo "- **New Version**: ${{ steps.bump_version.outputs.new_version }}" >> $GITHUB_STEP_SUMMARY echo "- **Bump Type**: ${{ steps.version_bump.outputs.bump_type }}" >> $GITHUB_STEP_SUMMARY echo "- **Tag**: ${{ steps.bump_version.outputs.tag }}" >> $GITHUB_STEP_SUMMARY + echo "- **Description**: ${{ github.event.inputs.description || 'None provided' }}" >> $GITHUB_STEP_SUMMARY echo "- **Commit**: Amended last commit with version info" >> $GITHUB_STEP_SUMMARY - echo "- **Next Step**: Release workflow triggered via repository dispatch" >> $GITHUB_STEP_SUMMARY + echo "- **GitHub Release**: Created with commit messages" >> $GITHUB_STEP_SUMMARY + echo "- **npm Package**: Published successfully" >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index 58795e0c7..000000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,118 +0,0 @@ -name: release - -on: - repository_dispatch: - types: [release] - -concurrency: - group: ${{ github.workflow }} - cancel-in-progress: true - -permissions: - pull-requests: write - contents: read - -jobs: - release: - name: Release package to npm - runs-on: ubuntu-latest - permissions: - contents: write - id-token: write - env: - NPM_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }} - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - ref: ${{ github.event.client_payload.tag }} - - - name: Verify version validation passed - env: - TYPE_GRAPHQL_VERSION: ${{ github.event.client_payload.tag }} - run: | - echo "Verifying release for version: $TYPE_GRAPHQL_VERSION" - - # Ensure this is a valid version tag format - if ! printf "%s\n" "$TYPE_GRAPHQL_VERSION" | grep -q -P '^v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-(alpha|beta|rc)\.(0|[1-9][0-9]*))?$'; then - printf '[ERROR]: Invalid version tag format (%s)\n' "$TYPE_GRAPHQL_VERSION" - exit 1 - fi - - echo "✅ Version tag format is valid" - - - name: Determine if version is prerelease - id: prerelease - env: - TYPE_GRAPHQL_VERSION: ${{ github.event.client_payload.tag }} - run: | - _prerelease= - if printf "%s\n" "$TYPE_GRAPHQL_VERSION" | grep -q -P '^v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$'; then - _prerelease=false - else - _prerelease=true - fi - - printf 'value=%s\n' "$_prerelease" >> "$GITHUB_OUTPUT" - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: 22.x - registry-url: "https://registry.npmjs.org" - - - name: Install latest npm - run: | - npm install -g npm@latest - - - name: Install Dependencies - run: | - npm ci - - - name: Configure npm authentication - run: | - echo "//registry.npmjs.org/:_authToken=\${NPM_TOKEN}" > .npmrc - - - name: Prepare package - run: | - npm run prepublishOnly - env: - TYPE_GRAPHQL_REF: ${{ github.event.client_payload.tag }} - - - name: Format commit messages for release - id: changelog - run: | - COMMITS_B64="${{ github.event.client_payload.commits_b64 }}" - - if [ -z "$COMMITS_B64" ]; then - echo "No commits provided in client_payload" - FORMATTED_COMMITS="No changes listed" - else - FORMATTED_COMMITS=$(echo "$COMMITS_B64" | base64 -d) - fi - - RELEASE_BODY=$(printf "## Changes in this release:\n\n%s\n\nReleased as %s" "$FORMATTED_COMMITS" "${{ github.event.client_payload.tag }}") - - echo "changelog<> $GITHUB_OUTPUT - echo "$RELEASE_BODY" >> $GITHUB_OUTPUT - echo "EOF" >> $GITHUB_OUTPUT - - - name: Release - uses: softprops/action-gh-release@v2 - with: - tag_name: ${{ github.event.client_payload.tag }} - body: ${{ steps.changelog.outputs.changelog }} - prerelease: ${{ steps.prerelease.outputs.value == 'true' }} - - - name: Publish - env: - TYPE_GRAPHQL_PRERELEASE: ${{ steps.prerelease.outputs.value }} - run: | - _tag= - if [ "$TYPE_GRAPHQL_PRERELEASE" = "true" ]; then - _tag="next" - else - _tag="latest" - fi - - npm publish --ignore-scripts --access public --tag "$_tag" From 71c8dc41885258cb28dd9df6ef23d4bd0d829032 Mon Sep 17 00:00:00 2001 From: Ben Miner Date: Fri, 26 Sep 2025 17:03:32 -0500 Subject: [PATCH 3/4] reset version to 2.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 078678d0b..324165192 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@scope3data/type-graphql", - "version": "2.1.0", + "version": "2.0.0", "private": false, "description": "Create GraphQL schema and resolvers with TypeScript, using classes and decorators!", "keywords": [ From 649f274349b039c785acb80235a72c09904cb7f8 Mon Sep 17 00:00:00 2001 From: Ben Miner Date: Fri, 26 Sep 2025 17:06:16 -0500 Subject: [PATCH 4/4] remove github token in checkout --- .github/workflows/manual-release.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/manual-release.yml b/.github/workflows/manual-release.yml index fed29f816..35c003842 100644 --- a/.github/workflows/manual-release.yml +++ b/.github/workflows/manual-release.yml @@ -40,7 +40,6 @@ jobs: uses: actions/checkout@v4 with: fetch-depth: 0 - token: ${{ secrets.GITHUB_TOKEN }} - name: Setup Node.js uses: actions/setup-node@v4