diff --git a/.github/workflows/auto-tag.yaml b/.github/workflows/auto-tag.yaml deleted file mode 100644 index 731bc09..0000000 --- a/.github/workflows/auto-tag.yaml +++ /dev/null @@ -1,59 +0,0 @@ -name: Auto Tag on Version Change - -on: - push: - branches: - - main - paths: - - 'package.json' - -jobs: - auto-tag: - runs-on: ubuntu-latest - - permissions: - contents: write - - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 # Fetch all history for tag checking - - - name: Get version from package.json - id: package-version - run: | - VERSION=$(node -p "require('./package.json').version") - echo "version=$VERSION" >> $GITHUB_OUTPUT - echo "tag=v$VERSION" >> $GITHUB_OUTPUT - - - name: Check if tag exists - id: check-tag - run: | - if git rev-parse "v${{ steps.package-version.outputs.version }}" >/dev/null 2>&1; then - echo "exists=true" >> $GITHUB_OUTPUT - else - echo "exists=false" >> $GITHUB_OUTPUT - fi - - - name: Create and push tag - if: steps.check-tag.outputs.exists == 'false' - run: | - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - TAG="${{ steps.package-version.outputs.tag }}" - # Try to create the tag; if it already exists locally, continue. - git tag -a "$TAG" -m "Release $TAG" || echo "Tag $TAG already exists locally, continuing." - # Try to push the tag. If the push fails, check if the tag now exists on the remote. - if ! git push origin "$TAG"; then - if git ls-remote --tags origin "$TAG" | grep -q "$TAG"; then - echo "Tag $TAG already exists on remote (likely created concurrently), skipping." - else - echo "Failed to push tag $TAG to remote." - exit 1 - fi - fi - - - name: Tag already exists - if: steps.check-tag.outputs.exists == 'true' - run: | - echo "Tag ${{ steps.package-version.outputs.tag }} already exists, skipping" diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index 06fec69..108441b 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -25,3 +25,11 @@ jobs: - run: npm run build --if-present - run: npm test - run: npm run lint + + status-check: + name: Node.js CI + runs-on: ubuntu-latest + needs: build + if: always() + steps: + - run: exit 0 diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index ad39bb2..057c3f0 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -2,11 +2,13 @@ name: Publish to npm on: push: - tags: - - 'v*' + branches: + - main + paths: + - 'package.json' jobs: - publish: + publish-release: runs-on: ubuntu-latest permissions: @@ -14,13 +16,26 @@ jobs: steps: - uses: actions/checkout@v4 + with: + fetch-depth: 0 # Fetch all history for tag checking - - name: Verify tagged commit is in main branch history + - name: Get version from package.json + id: package-version run: | - git fetch origin main - if ! git merge-base --is-ancestor $GITHUB_SHA origin/main; then - echo "Tag is not based on main. Aborting release." - exit 1 + VERSION=$(node -p "require('./package.json').version") + echo "version=$VERSION" >> $GITHUB_OUTPUT + echo "tag=v$VERSION" >> $GITHUB_OUTPUT + + - name: Check if version changed + run: | + LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0") + CURRENT_TAG="v${{ steps.package-version.outputs.version }}" + + if [ "$LATEST_TAG" = "$CURRENT_TAG" ]; then + echo "Version $CURRENT_TAG has not changed from latest tag. Skipping release." + exit 0 + else + echo "New version detected: $CURRENT_TAG (previous: $LATEST_TAG)" fi - uses: actions/setup-node@v4 @@ -29,8 +44,22 @@ jobs: registry-url: https://registry.npmjs.org - run: npm ci + - run: npm test + - name: Create and push tag + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + TAG="${{ steps.package-version.outputs.tag }}" + # Try to create the tag; if it already exists locally, continue. + git tag -a "$TAG" -m "Release $TAG" || echo "Tag $TAG already exists locally, continuing." + # Try to push the tag. If the push fails, bail out. + if ! git push origin "$TAG"; then + echo "Failed to push tag $TAG to remote (may already exist)." + exit 1 + fi + - name: Publish to npm run: npm publish env: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9bed376..b17f891 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -22,6 +22,11 @@ npm install npm test ``` +## Development Workflow + +1. Use feature branches for development. +2. PRs for new features should target the main branch. + ### The example test The input file for the `test/example/example.test.js` is taken from the diff --git a/RELEASING.md b/RELEASING.md index 78163c0..86214bb 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -8,20 +8,6 @@ about**, with minimal tooling and clear sources of truth. --- -## Overview - -- Use `npm run release:{patch,minor,major}` to create a release branch. -- Push that branch and open a PR to main. -- Merging that branch triggers workflows that create a tag and publish the - release. - - The auto-tag workflow creates the new tag. - - The release workflow sees the new tag and publishes the npm and GitHub - releases. - -No release bots, changelog generators, or additional CLIs are required. - ---- - ## Versioning This project follows **Semantic Versioning (SemVer)**: @@ -31,9 +17,6 @@ This project follows **Semantic Versioning (SemVer)**: - **Major** (`x.0.0`) — breaking changes (rule behavior changes, removals, stricter defaults) -Versions can be updated manually in package.json or using npm’s built-in -tooling. - --- ## Creating a Release @@ -58,43 +41,35 @@ This script will: Then create a Pull Request to merge the release branch into main. -Once the PR is merged, **the tag is created automatically**. +Once the PR is merged, the `release` workflow will run since the PR makes +changes to package.json. This workflow will run the tests (again), and if the +tests pass will then attempt to create a tag for the new version. If that +succeeds, it then creates a release in both npm and GitHub. -The `auto-tag` workflow monitors package.json changes on main and automatically -creates the corresponding git tag if it doesn't exist. +The release branch can be deleted after the PR is merged and the releases are +published. -When the tag is created on main, this triggers the `release` workflow, which -will create the release in npm and in GitHub. +No release bots, changelog generators, or additional CLIs are required. --- ## Automation (GitHub Actions) -### Automatic Tagging - -The `auto-tag` workflow monitors package.json changes on the main branch. When -a version change is detected, it automatically: +### Release Workflow -1. Reads the version from package.json -2. Checks if a tag for that version already exists -3. Creates and pushes the tag if it doesn't exist +The `release` workflow is triggered by a push to 'main' (e.g. a PR merge) that +modifies "package json'. When triggered, it -This eliminates the manual tagging step after PR merge. - -### Publishing and Releases - -The `release` workflow listens for pushed tags matching `v*` on the main -branch. - -On tag push, it will: - -1. Check out the repository -2. Install dependencies -3. Run tests +1. Check if a tag already exists for this version. If so, the workflow + terminates. +2. Install dependencies and run the tests. These should never fail since PRs + targeting main must pass CI, but this is an extra precaution. +3. Create and push a git tag matching the version in package.json 4. Publish the package to npm -5. Create a GitHub Release for the tag +5. Create a GitHub Release with auto-generated notes -The GitHub Release is only created if npm publishing succeeds. +This single workflow handles the entire release process and ensures the npm and +GitHub releases are in sync and use the version from package.json --- @@ -116,18 +91,6 @@ Publishing requires: - An npm automation token stored as a GitHub secret named `NPM_TOKEN` - `publishConfig.access` set appropriately in `package.json` -Example: - -```json -{ - "publishConfig": { - "access": "public" - } -} -``` - ---- - ## Optional: Changelog A manual `CHANGELOG.md` may be maintained if desired. diff --git a/scripts/prepare-release.sh b/scripts/prepare-release.sh index d72a9b4..1909b8d 100755 --- a/scripts/prepare-release.sh +++ b/scripts/prepare-release.sh @@ -64,6 +64,7 @@ npm test # Run linter echo "Running linter..." npm run lint + # Bump version echo "Bumping version ($VERSION_TYPE)..." npm version "$VERSION_TYPE" --no-git-tag-version