diff --git a/.github/release.yml b/.github/release.yml index 501e509..bd24669 100644 --- a/.github/release.yml +++ b/.github/release.yml @@ -4,18 +4,16 @@ changelog: - "ignore for release" categories: - - title: Security Fixes - labels: ["Type: Security", "security"] - title: Breaking Changes - labels: ["Type: Breaking Change"] - - title: Features - labels: ["Type: enhancement"] + labels: ["Type: Breaking Change", "breaking change"] - title: Bug Fixes - labels: ["Type: bug"] + labels: ["Type: bug", "bug"] - title: Documentation labels: ["Type: Documentation", "documentation"] - title: CI labels: ["Type: CI", "ci"] + - title: Security Fixes + labels: ["Type: Security", "security"] - title: Dependency Updates labels: ["Type: Dependencies", "dependencies"] - title: Other Changes diff --git a/.github/workflows/prepare-release-pr.yml b/.github/workflows/prepare-release-pr.yml new file mode 100644 index 0000000..658b83f --- /dev/null +++ b/.github/workflows/prepare-release-pr.yml @@ -0,0 +1,74 @@ +name: Prepare Release PR +run-name: "Prepare release ${{ inputs.release-version }} (${{ github.ref_name }})" + +on: + workflow_dispatch: + inputs: + release-version: + description: Select release semantic version. + required: true + type: choice + options: + - patch + - minor + - major + +defaults: + run: + shell: bash + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: write + pull-requests: write + +jobs: + prepare: + name: Prepare Release PR + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - name: Checkout Repository + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + with: + persist-credentials: false + + - name: Setup Node.js + uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0 + with: + node-version: lts/* + + - name: Bump version + run: | + npm version "${{ inputs.release-version }}" --no-git-tag-version + + - name: Read version + id: version + run: | + echo "version=$(node -p "require('./package.json').version")" >> $GITHUB_OUTPUT + + - name: Create release branch + run: | + git checkout -b release/v${{ steps.version.outputs.version }} + + - name: Commit version change + run: | + git config user.name "github-actions" + git config user.email "github-actions@users.noreply.github.com" + git add package.json + git commit -m "chore(release): v${{ steps.version.outputs.version }}" + git push origin HEAD + + - name: Create Pull Request + run: | + gh pr create \ + --title "release: v${{ steps.version.outputs.version }}" \ + --body "Release v${{ steps.version.outputs.version }}" \ + --base main \ + --head release/v${{ steps.version.outputs.version }} \ + --label "ignore for release" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 98bfaa9..bd3f00c 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -2,50 +2,26 @@ name: Publish run-name: "${{ github.workflow }} (${{ github.ref_name }})" on: - push: - tags: - - v*.*.* + workflow_dispatch: defaults: run: shell: bash -jobs: - validate: - name: Validate Version - runs-on: ubuntu-latest - timeout-minutes: 5 - steps: - - name: Checkout Repository - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - with: - persist-credentials: false - - - name: Extract version from tag - id: tag_version - run: echo "version=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT - - - name: Extract version from package.json - id: pkg_version - run: echo "version=$(node -p "require('./package.json').version")" >> $GITHUB_OUTPUT +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true - - name: Compare versions - run: | - if [ "${{ steps.tag_version.outputs.version }}" != "${{ steps.pkg_version.outputs.version }}" ]; then - echo "Error: Tag version (${{ steps.tag_version.outputs.version }}) does not match package.json version (${{ steps.pkg_version.outputs.version }})" - exit 1 - fi - echo "Version validation successful: v${{ steps.pkg_version.outputs.version }}" +permissions: + contents: write + id-token: write - publish-npm: - name: Publish to npm +jobs: + publish: + name: Publish package runs-on: ubuntu-latest - timeout-minutes: 5 - permissions: - contents: write - id-token: write + timeout-minutes: 10 environment: npm-registry - needs: [validate] steps: - name: Checkout Repository uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 @@ -64,12 +40,30 @@ jobs: - name: Install latest npm run: npm install -g npm@latest + - name: Read version + id: version + run: | + echo "version=$(node -p "require('./package.json').version")" >> $GITHUB_OUTPUT + + - name: Ensure version not published + run: | + VERSION="v${{ steps.version.outputs.version }}" + + if git rev-parse "$VERSION" >/dev/null 2>&1; then + echo "Tag $VERSION already exists" + exit 1 + fi + - name: Publish to npm run: npm publish --provenance --access public + - name: Create and push tag + run: | + git tag "v${{ steps.version.outputs.version }}" + git push origin "v${{ steps.version.outputs.version }}" + - name: Create GitHub Release - uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2.5.0 - with: - generate_release_notes: true + run: | + gh release create "v${{ steps.version.outputs.version }}" --generate-notes env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}