diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index df2416b..11b32a2 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -290,54 +290,6 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} parallel-finished: true - publish: - name: Publish - runs-on: ubuntu-latest - permissions: - contents: write - id-token: write - needs: - - lint - - test - - test-macOS-windows-binding - - test-linux-binding - steps: - - uses: actions/checkout@v5 - - name: Setup node - uses: actions/setup-node@v4 - with: - node-version: 22 - cache: yarn - - name: Install dependencies - run: yarn install - - name: create npm dirs - run: yarn napi create-npm-dirs - - name: Download all artifacts - uses: actions/download-artifact@v5 - with: - path: artifacts - - name: Move artifacts - run: yarn artifacts - - name: List packages - run: ls -R ./npm - shell: bash - - name: Publish - run: | - npm config set provenance true - if git log -1 --pretty=%B | grep "^[0-9]\+\.[0-9]\+\.[0-9]\+$"; - then - echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc - npm publish --access public - elif git log -1 --pretty=%B | grep "^[0-9]\+\.[0-9]\+\.[0-9]\+"; - then - echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc - npm publish --tag next --access public - else - echo "Not a release, skipping publish" - fi - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - NPM_TOKEN: ${{ secrets.NPM_TOKEN }} license-and-audit: runs-on: ubuntu-latest steps: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..991e597 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,213 @@ +name: Release + +on: + workflow_dispatch: + inputs: + version: + description: 'Version to release (e.g., 1.0.0)' + required: true + type: string + +env: + DEBUG: napi:* + APP_NAME: atlas-local + MACOSX_DEPLOYMENT_TARGET: '10.13' + +jobs: + update-version: + name: Update Version + runs-on: ubuntu-latest + outputs: + version: ${{ steps.version.outputs.version }} + steps: + - name: Set Apix Bot token + id: app-token + uses: mongodb/apix-action/token@6c3fde402c21942fa46cde003f190c2b23c59530 + with: + app-id: ${{ secrets.APIXBOT_APP_ID }} + private-key: ${{ secrets.APIXBOT_APP_PEM }} + - uses: actions/checkout@v5 + with: + token: ${{ steps.app-token.outputs.token }} + fetch-depth: 0 + - name: Setup node + uses: actions/setup-node@v4 + with: + node-version: 22 + cache: yarn + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + with: + toolchain: stable + targets: x86_64-unknown-linux-gnu + - name: Install dependencies + run: yarn install + - name: Install cargo tools for license verification + run: | + cargo install --locked --version 0.8.2 cargo-about + - name: Update package.json version + run: | + npm version ${{ github.event.inputs.version }} --no-git-tag-version + - name: Update Cargo.toml version + run: | + sed -i 's/^version = ".*"/version = "${{ github.event.inputs.version }}"/' Cargo.toml + - name: Update third-party licenses + run: | + cargo about generate about.hbs > LICENSE-3RD-PARTY.txt + - name: Generate changelog + uses: orhun/git-cliff-action@v4 + with: + config: cliff.toml + args: --verbose + env: + OUTPUT: CHANGELOG.md + GITHUB_REPO: ${{ github.repository }} + - name: Build to update generated files + run: yarn build --target x86_64-unknown-linux-gnu --use-napi-cross + - name: Commit version changes + run: | + git config --global user.name "${{ steps.app-token.outputs.user-name }}" + git config --global user.email "${{ steps.app-token.outputs.user-email }}" + git add package.json Cargo.toml index.js index.d.ts CHANGELOG.md LICENSE-3RD-PARTY.txt + git commit -m "${{ github.event.inputs.version }}" + git push + - name: Set version output + id: version + run: echo "version=${{ github.event.inputs.version }}" >> $GITHUB_OUTPUT + + build: + name: Build Release + needs: update-version + strategy: + fail-fast: false + matrix: + settings: + - host: macos-latest + target: x86_64-apple-darwin + build: yarn build --target x86_64-apple-darwin + - host: windows-latest + build: yarn build --target x86_64-pc-windows-msvc + target: x86_64-pc-windows-msvc + - host: ubuntu-latest + target: x86_64-unknown-linux-gnu + build: yarn build --target x86_64-unknown-linux-gnu --use-napi-cross + - host: macos-latest + target: aarch64-apple-darwin + build: yarn build --target aarch64-apple-darwin + - host: ubuntu-latest + target: aarch64-unknown-linux-gnu + build: yarn build --target aarch64-unknown-linux-gnu --use-napi-cross + runs-on: ${{ matrix.settings.host }} + steps: + - uses: actions/checkout@v5 + with: + ref: main + - name: Setup node + uses: actions/setup-node@v4 + with: + node-version: 22 + cache: yarn + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + with: + toolchain: stable + targets: ${{ matrix.settings.target }} + - name: Cache cargo + uses: actions/cache@v4 + with: + path: | + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + ~/.napi-rs + .cargo-cache + target/ + key: ${{ matrix.settings.target }}-cargo-${{ matrix.settings.host }} + - uses: mlugg/setup-zig@v2 + if: ${{ contains(matrix.settings.target, 'musl') }} + with: + version: 0.14.1 + - name: Install cargo-zigbuild + uses: taiki-e/install-action@v2 + if: ${{ contains(matrix.settings.target, 'musl') }} + env: + GITHUB_TOKEN: ${{ github.token }} + with: + tool: cargo-zigbuild + - name: Setup toolchain + run: ${{ matrix.settings.setup }} + if: ${{ matrix.settings.setup }} + shell: bash + - name: Install dependencies + run: yarn install + - name: Build + run: ${{ matrix.settings.build }} + shell: bash + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: bindings-${{ matrix.settings.target }} + path: | + ${{ env.APP_NAME }}.*.node + ${{ env.APP_NAME }}.*.wasm + if-no-files-found: error + + publish: + name: Publish Release + runs-on: ubuntu-latest + permissions: + contents: write + id-token: write + needs: [update-version, build] + steps: + - uses: actions/checkout@v5 + with: + ref: main + - name: Setup node + uses: actions/setup-node@v4 + with: + node-version: 22 + cache: yarn + - name: Install dependencies + run: yarn install + - name: Create npm dirs + run: yarn napi create-npm-dirs + - name: Download all artifacts + uses: actions/download-artifact@v5 + with: + path: artifacts + - name: Move artifacts + run: yarn artifacts + - name: List packages + run: ls -R ./npm + shell: bash + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + tag_name: v${{ needs.update-version.outputs.version }} + name: Release v${{ needs.update-version.outputs.version }} + files: artifacts/bindings-*/*.node + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Publish to NPM + run: | + npm config set provenance true + COMMIT_MSG=$(git log -1 --pretty=%B) + if echo "$COMMIT_MSG" | grep -E "^[0-9]+\.[0-9]+\.[0-9]+$" > /dev/null; + then + echo "Publishing stable release to latest tag" + echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc + npm publish --access public + elif echo "$COMMIT_MSG" | grep -E "^[0-9]+\.[0-9]+\.[0-9]+" > /dev/null; + then + echo "Publishing pre-release to next tag" + echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc + npm publish --tag next --access public + else + echo "Invalid release tag format: '$COMMIT_MSG'" + echo "Expected format: X.Y.Z or X.Y.Z-suffix" + echo "Skipping publish" + exit 0 + fi + env: + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/README.md b/README.md index 2657d67..5241f56 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,10 @@ The complete API documentation is available in the generated TypeScript definiti Contributions are welcome! Please feel free to submit a Pull Request. +## Changelog + +See [CHANGELOG.md](CHANGELOG.md) for a detailed history of changes. + ## License This project is licensed under the Apache License, Version 2.0 (see `LICENSE`). It also makes use of third-party libraries, which are distributed under their own respective licenses (see `LICENSE-3RD-PARTY.txt`). diff --git a/cliff.toml b/cliff.toml new file mode 100644 index 0000000..a0d0102 --- /dev/null +++ b/cliff.toml @@ -0,0 +1,93 @@ +# git-cliff ~ configuration file +# https://git-cliff.org/docs/configuration + + +[changelog] +# A Tera template to be rendered for each release in the changelog. +# See https://keats.github.io/tera/docs/#introduction +body = """ +{% if version %}\ + ## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }} +{% else %}\ + ## [unreleased] +{% endif %}\ +{% for group, commits in commits | group_by(attribute="group") %} + ### {{ group | striptags | trim | upper_first }} + {% for commit in commits %} + - {% if commit.scope %}*({{ commit.scope }})* {% endif %}\ + {% if commit.breaking %}[**breaking**] {% endif %}\ + {{ commit.message | upper_first }}\ + {% endfor %} +{% endfor %} +""" +# Remove leading and trailing whitespaces from the changelog's body. +trim = true +# Render body even when there are no releases to process. +render_always = true +# An array of regex based postprocessors to modify the changelog. +postprocessors = [ + { pattern = '\((\w+\s)?#([0-9]+)\)', replace = "([#${2}](https://github.com/$GITHUB_REPO/issues/${2}))" }, +] +# render body even when there are no releases to process +# render_always = true +# output file path +# output = "test.md" + +[git] +# Parse commits according to the conventional commits specification. +# See https://www.conventionalcommits.org +conventional_commits = true +# Exclude commits that do not match the conventional commits specification. +filter_unconventional = true +# Require all commits to be conventional. +# Takes precedence over filter_unconventional. +require_conventional = false +# Split commits on newlines, treating each line as an individual commit. +split_commits = false +# An array of regex based parsers to modify commit messages prior to further processing. +commit_preprocessors = [ + # Replace issue numbers with link templates to be updated in `changelog.postprocessors`. + #{ pattern = '\((\w+\s)?#([0-9]+)\)', replace = "([#${2}](/issues/${2}))"}, + # Check spelling of the commit message using https://github.com/crate-ci/typos. + # If the spelling is incorrect, it will be fixed automatically. + #{ pattern = '.*', replace_command = 'typos --write-changes -' }, +] +# Prevent commits that are breaking from being excluded by commit parsers. +protect_breaking_commits = false +# An array of regex based parsers for extracting data from the commit message. +# Assigns commits to groups. +# Optionally sets the commit's scope and can decide to exclude commits from further processing. +commit_parsers = [ + { message = "^feat", group = "๐Ÿš€ Features" }, + { message = "^fix", group = "๐Ÿ› Bug Fixes" }, + { message = "^doc", group = "๐Ÿ“š Documentation" }, + { message = "^perf", group = "โšก Performance" }, + { message = "^refactor", group = "๐Ÿšœ Refactor" }, + { message = "^style", group = "๐ŸŽจ Styling" }, + { message = "^test", group = "๐Ÿงช Testing" }, + { message = "^chore\\(release\\): prepare for", skip = true }, + { message = "^chore\\(deps.*\\)", skip = true }, + { message = "^chore\\(pr\\)", skip = true }, + { message = "^chore\\(pull\\)", skip = true }, + { message = "^chore|^ci", group = "โš™๏ธ Miscellaneous Tasks" }, + { body = ".*security", group = "๐Ÿ›ก๏ธ Security" }, + { message = "^revert", group = "โ—€๏ธ Revert" }, + { message = ".*", group = "๐Ÿ’ผ Other" }, +] +# Exclude commits that are not matched by any commit parser. +filter_commits = false +# An array of link parsers for extracting external references, and turning them into URLs, using regex. +link_parsers = [ + { pattern = "#(\\d+)", href = "https://github.com/$GITHUB_REPO/issues/$1" } +] +# Include only the tags that belong to the current branch. +use_branch_tags = false +# Order releases topologically instead of chronologically. +topo_order = false +# Order releases topologically instead of chronologically. +topo_order_commits = true +# Order of commits in each group/release within the changelog. +# Allowed values: newest, oldest +sort_commits = "oldest" +# Process submodules commits +recurse_submodules = false diff --git a/package.json b/package.json index 6123105..435ff72 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,8 @@ "index.d.ts", "index.js", "LICENSE", - "LICENSE-3RD-PARTY.txt" + "LICENSE-3RD-PARTY.txt", + "CHANGELOG.md" ], "napi": { "binaryName": "atlas-local",