diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..84c81240 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,121 @@ +name: release + +on: + push: + branches: [main] + pull_request: + types: [closed] + branches: [main] + # this is required to trigger releases when the release PR is merged, or to rerun a release if needed + workflow_dispatch: + +permissions: {} + +jobs: + # Parse commits since the last tag, push a `release/vX.Y.Z` branch, open + # or update a draft release PR, and close any superseded release PRs + # (e.g. `release/v1.0.1` when the bump is now `release/v1.1.0`). + pr: + if: github.event_name == 'push' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) + runs-on: ubuntu-latest + permissions: + contents: write # push the `release/vX.Y.Z` branch and delete superseded ones + pull-requests: write # create a release PR, update its body, close superseded PRs + steps: + - uses: danielroe/uppt/pr@7bcfb5397c37202ef882363f755423130419d28a # v0.5.5 + with: + token: ${{ secrets.GITHUB_TOKEN }} + packages: | + aliases + core + fetchindex + newest + oldest + parsefiles + ranges + static + !opt + !translate + + # The release PR was merged: tag the squash commit, cut a GitHub release + # from the PR body, and dispatch the publish workflow. The `release/v` + # head-ref guard keeps regular feature-PR merges from triggering this; + # the head-repo guard keeps merged fork PRs from triggering it. + release: + if: | + github.event_name == 'pull_request' + && github.event.pull_request.merged == true + && startsWith(github.event.pull_request.head.ref, 'release/v') + && github.event.pull_request.head.repo.full_name == github.repository + runs-on: ubuntu-latest + concurrency: + group: release-${{ github.event.pull_request.number }} + cancel-in-progress: false + permissions: + contents: write # push the `vX.Y.Z` tag and create the GitHub release + actions: write # `gh workflow run release.yml --ref vX.Y.Z` chained dispatch + steps: + - uses: danielroe/uppt/release@7bcfb5397c37202ef882363f755423130419d28a # v0.5.5 + with: + token: ${{ secrets.GITHUB_TOKEN }} + packages: | + aliases + core + fetchindex + newest + oldest + parsefiles + ranges + static + !opt + !translate + + # The chained dispatch from `release` lands here as a `workflow_dispatch` + # event on a `vX.Y.Z` tag ref. The `pack` job installs deps, runs + # `pnpm pack` (or `npm pack`), and uploads the tarball as a workflow + # artifact. See "Lifecycle scripts" below for what runs where. Manual + # recovery uses the same path (Run workflow -> pick a `v*` tag). + pack: + if: github.event_name == 'workflow_dispatch' && startsWith(github.ref, 'refs/tags/v') + runs-on: ubuntu-latest + concurrency: + group: pack-${{ github.ref }} + cancel-in-progress: false + permissions: {} + outputs: + files: ${{ steps.pack.outputs.files }} + steps: + - id: pack + uses: danielroe/uppt/pack@7bcfb5397c37202ef882363f755423130419d28a # v0.5.5 + with: + packages: | + aliases + core + fetchindex + newest + oldest + parsefiles + ranges + static + !opt + !translate + + # `publish` downloads the prebuilt tarball from the pack job's + # artifact and stages it for publish. + publish: + if: | + github.event_name == 'workflow_dispatch' + && startsWith(github.ref, 'refs/tags/v') + && needs.pack.outputs.files != '[]' + needs: pack + runs-on: ubuntu-latest + concurrency: + group: publish-${{ github.ref }} + cancel-in-progress: false + permissions: + id-token: write # OIDC claim for npm trusted publisher + environment: npm # must match the trusted-publisher entry on npmjs.com + steps: + - uses: danielroe/uppt/publish@7bcfb5397c37202ef882363f755423130419d28a # v0.5.5 + with: + files: ${{ needs.pack.outputs.files }} diff --git a/.github/workflows/tests-core.yml b/.github/workflows/tests-core.yml index 9d7772fe..b09ea3a4 100644 --- a/.github/workflows/tests-core.yml +++ b/.github/workflows/tests-core.yml @@ -28,6 +28,4 @@ jobs: - name: Run npm install -w core run: npm install -w core - name: Run npm test -w core - run: npm test -w core - - name: 'Run npm run test:update and npm test -w core' - run: npm run test:update && npm test -w core \ No newline at end of file + run: npm test -w core \ No newline at end of file diff --git a/aliases/package.json b/aliases/package.json index 26898bdb..f80fcc23 100644 --- a/aliases/package.json +++ b/aliases/package.json @@ -1,6 +1,6 @@ { "name": "@nodevu/aliases", - "version": "0.0.2", + "version": "1.0.0", "description": "available aliases for sets of Node.js versions", "main": "index.js", "repository": { diff --git a/core/package.json b/core/package.json index cc28e5f4..5016fff9 100644 --- a/core/package.json +++ b/core/package.json @@ -1,6 +1,6 @@ { "name": "@nodevu/core", - "version": "0.3.0", + "version": "1.0.0", "description": "nodevu core API: comprehensive node.js version tooling", "main": "index.js", "scripts": { diff --git a/core/util/dev/beforeEachTemplate.js b/core/util/dev/beforeEachTemplate.js index ab42e35b..a209d8a5 100644 --- a/core/util/dev/beforeEachTemplate.js +++ b/core/util/dev/beforeEachTemplate.js @@ -1,5 +1,9 @@ const dns = require('node:dns'); -const { MockAgent, setGlobalDispatcher } = require('undici'); +const { + fetch: undiciFetch, + MockAgent, + setGlobalDispatcher, +} = require('undici'); const staticIndex = require('../../test/data/static/index.json'); const staticSchedule = require('../../test/data/static/schedule.json'); @@ -8,11 +12,16 @@ function beforeEachTemplate() { // this fixes a bug in Node.js - it should be fixed _eventually_ and can be removed: https://github.com/nodejs/undici/issues/1248 dns.setDefaultResultOrder('ipv4first'); - // this mock agent stuff isn't actually working for... some unkown reason const mockAgent = new MockAgent(); mockAgent.disableNetConnect(); setGlobalDispatcher(mockAgent); + // Node.js's built-in globalThis.fetch uses a bundled copy of undici separate from + // the npm package, so setGlobalDispatcher above doesn't affect it. Replacing it here + // ensures all fetch calls (including those that fall through to globalThis.fetch in + // optionsParser) go through the mock dispatcher. + globalThis.fetch = undiciFetch; + const defaultIndexMock = mockAgent.get('https://nodejs.org'); defaultIndexMock .intercept({ path: '/dist/index.json' }) @@ -25,13 +34,9 @@ function beforeEachTemplate() { .intercept({ path: '/nodejs/Release/master/schedule.json' }) .reply(200, staticSchedule); - const customIndexMock = mockAgent.get('https://bnb.im'); - customIndexMock - .intercept({ path: '/dist/index.json' }) - .reply(200, staticIndex); - - const customScheduleMock = mockAgent.get('https://bnb.im'); - customScheduleMock + const customMock = mockAgent.get('https://bnb.im'); + customMock.intercept({ path: '/dist/index.json' }).reply(200, staticIndex); + customMock .intercept({ path: '/dist/schedule.json' }) .reply(200, staticSchedule); } diff --git a/fetchindex/package.json b/fetchindex/package.json index 63669079..b1d37db5 100644 --- a/fetchindex/package.json +++ b/fetchindex/package.json @@ -1,6 +1,6 @@ { "name": "@nodevu/fetchindex", - "version": "0.1.0", + "version": "1.0.0", "description": "A tool that fetches the /dist/index.json file from the Node.js website.", "main": "index.js", "files": ["index.js", "LICENSE"], diff --git a/newest/package.json b/newest/package.json index 17a651ba..3fabd253 100644 --- a/newest/package.json +++ b/newest/package.json @@ -1,6 +1,6 @@ { "name": "@nodevu/newest", - "version": "0.1.0", + "version": "1.0.0", "description": "a module that returns the newest lts or security release of the release line passed.", "main": "index.js", "files": ["index.js", "LICENSE"], diff --git a/oldest/package.json b/oldest/package.json index 2a78414e..4e2d15b6 100644 --- a/oldest/package.json +++ b/oldest/package.json @@ -1,6 +1,6 @@ { "name": "@nodevu/oldest", - "version": "0.1.0", + "version": "1.0.0", "description": "a module that returns the oldest lts or security release of the release line passed.", "main": "index.js", "files": ["index.js", "LICENSE"], diff --git a/opt/package.json b/opt/package.json index aaaa803e..5b33b2a3 100644 --- a/opt/package.json +++ b/opt/package.json @@ -1,6 +1,6 @@ { "name": "@nodevu/opt", - "version": "0.1.0", + "version": "1.0.0", "description": "internal options parser for @nodevu packages.", "main": "index.js", "files": ["index.js", "LICENSE"], diff --git a/parsefiles/package.json b/parsefiles/package.json index 0ceb1087..7792db6c 100644 --- a/parsefiles/package.json +++ b/parsefiles/package.json @@ -1,6 +1,6 @@ { "name": "@nodevu/parsefiles", - "version": "0.0.3", + "version": "1.0.0", "description": "parse the files identifiers from Node.js", "main": "index.js", "scripts": { diff --git a/ranges/package.json b/ranges/package.json index 838f6a32..b55bd227 100644 --- a/ranges/package.json +++ b/ranges/package.json @@ -1,6 +1,6 @@ { "name": "@nodevu/ranges", - "version": "0.2.0", + "version": "1.0.0", "description": "support node's unofficial alias namespace", "main": "index.js", "files": ["index.js", "LICENSE"], diff --git a/static/package.json b/static/package.json index 536ce181..f7457804 100644 --- a/static/package.json +++ b/static/package.json @@ -1,6 +1,6 @@ { "name": "@nodevu/static", - "version": "0.0.4", + "version": "1.0.0", "description": "static outputs from @nodevu/core", "main": "index.js", "scripts": { diff --git a/translate/package.json b/translate/package.json index a66497ce..f294afbb 100644 --- a/translate/package.json +++ b/translate/package.json @@ -1,6 +1,6 @@ { "name": "@nodevu/translate", - "version": "0.0.1", + "version": "1.0.0", "description": "a translation layer between the nodevu naming mechanism and the Node.js supported mechanism. Neceessary for legacy interop.", "keywords": ["nodevu", "node", "nodejs", "versions", "supported"], "homepage": "https://github.com/cutenode/nodevu#readme",