From dc103c0c63b880ab83fc763ed9ac284da77e1d66 Mon Sep 17 00:00:00 2001 From: Kanad Gupta <8854718+kanadgupta@users.noreply.github.com> Date: Tue, 29 Nov 2022 14:08:46 -0600 Subject: [PATCH] feat: major version tags (#682) * refactor: rename files This consolidates getNodeVersion into another file and renames the set-version-output function to have a .js extension so we don't need to have weird `npm run lint` carveouts for it * test: more test coverage * refactor: use core function for output setting This pattern for setting outputs is now deprecated * fix: whoops * refactor: use semver to parse out major version we were previously using a zero-deps approach but now that we need to install deps for the set-version-output step, we might as well use a safer approach here. * refactor: add ability to grab major version + test this will set up some upcoming tagging changes * feat: create file for tagging version * docs: small update * Revert "refactor: add ability to grab major version + test" This reverts commit 0fc0fe2036e69bc87487c06d34dfc618a5493266. * revert(kinda): use semver major instead * refactor: use vanilla imports where possible simple-git isn't really being super helpful here, so we might as well use a vanilla node function instead. i struggled to write tests so not gonna use our `getPkgVersion` function either since importing directly from package.json is just fine. * chore: do a clean install + build before version bump * docs: update github docs URLs * docs: update MAINTAINERS guide i feel like this flow is better, tagging a beta tripped me up the first time * feat: surface major version tag in GHA onboarding we should surface the v8 tag in the github actions that we create. this required a decent refactor to consolidate our major version retrieval logic. a bunch of snapshots had to be updated too. * feat: surface major version tag in our docs * chore: small JSDoc update * fix: don't add major tag if prerelease * fix: cmon dude * refactor: use logger --- .eslintrc | 2 +- .github/workflows/docs.yml | 2 +- MAINTAINERS.md | 10 ++-- README.md | 4 +- .../docs/__snapshots__/index.test.ts.snap | 6 +-- .../openapi/__snapshots__/index.test.ts.snap | 14 +++--- .../__snapshots__/validate.test.ts.snap | 8 +-- __tests__/helpers/get-gha-setup.ts | 4 +- .../lib/__snapshots__/createGHA.test.ts.snap | 32 ++++++------ __tests__/lib/createGHA.test.ts | 15 ++---- __tests__/lib/getNodeVersion.test.ts | 12 ----- __tests__/lib/getPkgVersion.test.ts | 49 +++++++++++++++++++ bin/set-major-version-tag.js | 33 +++++++++++++ bin/set-version-output | 17 ------- bin/set-version-output.js | 16 ++++++ documentation/github-actions-docs-example.md | 2 +- .../github-actions-openapi-example.md | 2 +- documentation/legacy-github-action.md | 2 +- documentation/rdme.md | 2 +- package.json | 5 +- src/lib/createGHA/index.ts | 14 ++---- src/lib/getNodeVersion.js | 17 ------- src/lib/getPkgVersion.ts | 37 +++++++++++--- src/lib/logger.ts | 20 ++++++-- 24 files changed, 200 insertions(+), 125 deletions(-) delete mode 100644 __tests__/lib/getNodeVersion.test.ts create mode 100644 __tests__/lib/getPkgVersion.test.ts create mode 100755 bin/set-major-version-tag.js delete mode 100755 bin/set-version-output create mode 100755 bin/set-version-output.js delete mode 100644 src/lib/getNodeVersion.js diff --git a/.eslintrc b/.eslintrc index 2fbbc6957..f7be50cfa 100644 --- a/.eslintrc +++ b/.eslintrc @@ -6,7 +6,7 @@ }, "overrides": [ { - "files": ["bin/set-version-output", "config/*.js"], + "files": ["bin/set-version-output.js", "bin/set-major-version-tag.js", "config/*.js"], "rules": { "@typescript-eslint/no-var-requires": "off" } diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 307102191..883d938d5 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -21,7 +21,7 @@ jobs: # our package version and our Node.js version. - name: Retrieve version values id: rdme-version - run: ./bin/set-version-output + run: ./bin/set-version-output.js # Next, we use this output to do a few find/replaces! - name: Find and replace Node.js version placeholders diff --git a/MAINTAINERS.md b/MAINTAINERS.md index 6629f55f4..eaecf9dbb 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -18,7 +18,7 @@ The next step is to push these changes to GitHub: ```sh git push # pushes the code -git push --tags # pushes the tags +git push --tags -f # pushes the tags ``` Once the code and tags are pushed to GitHub, [create a new release](https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository#creating-a-release) so the latest tag is surfaced in [the GitHub Marketplace listing](https://github.com/marketplace/actions/rdme-sync-to-readme). @@ -30,14 +30,14 @@ Auto-generating release notes is sufficient, but I like to summarize the changes ## Publishing to `npm` :rocket: -Finally, publish the changes to `npm`. If you're publishing to the default [distribution tag](https://docs.npmjs.com/adding-dist-tags-to-packages) (i.e., `latest`), you can run the following: +Finally, publish the changes to `npm`. If you're publishing to a non-standard [distribution tag](https://docs.npmjs.com/adding-dist-tags-to-packages) for prelease purposes or otherwise (e.g., `alpha`, `beta`, `next`, etc.), you can run the following: ```sh -npm publish +npm publish --tag ``` -If you're publishing to another [distribution tag](https://docs.npmjs.com/adding-dist-tags-to-packages) for prelease purposes or otherwise (e.g., `alpha`, `beta`, `next`, etc.), include the tag like so: +If you're publishing to the default [distribution tag](https://docs.npmjs.com/adding-dist-tags-to-packages) (i.e., `latest`), you can omit the `--tag` flag like so: ```sh -npm publish --tag +npm publish ``` diff --git a/README.md b/README.md index 1220ece19..c041e1ddc 100644 --- a/README.md +++ b/README.md @@ -85,7 +85,7 @@ Once installed in your project, you can use the `npx` prefix (which is included npx rdme openapi:validate [file] ``` -To ensure you're getting the latest features and security updates, we recommend using a tool like [Dependabot](https://docs.github.com/code-security/supply-chain-security/keeping-your-dependencies-updated-automatically/about-dependabot-version-updates) to keep `rdme` (and your other dependencies) up-to-date. +To ensure you're getting the latest features and security updates, we recommend using a tool like [Dependabot](https://docs.github.com/code-security/dependabot/dependabot-version-updates/about-dependabot-version-updates) to keep `rdme` (and your other dependencies) up-to-date. ### Authentication @@ -117,7 +117,7 @@ rdme openapi --github This will run through the `openapi` command, ask you a few quick questions, and then automatically create a fully functional GitHub Actions workflow file for you. πŸͺ„ -You can see examples featuring the latest version in [our docs](https://docs.readme.com/docs/rdme#github-actions-examples). We recommend [configuring Dependabot to keep your actions up-to-date](https://docs.github.com/code-security/supply-chain-security/keeping-your-dependencies-updated-automatically/keeping-your-actions-up-to-date-with-dependabot). +You can see examples featuring the latest version in [our docs](https://docs.readme.com/docs/rdme#github-actions-examples). We recommend [configuring Dependabot to keep your actions up-to-date](https://docs.github.com/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot). ## Usage diff --git a/__tests__/cmds/docs/__snapshots__/index.test.ts.snap b/__tests__/cmds/docs/__snapshots__/index.test.ts.snap index 446aa3cda..316329ddf 100644 --- a/__tests__/cmds/docs/__snapshots__/index.test.ts.snap +++ b/__tests__/cmds/docs/__snapshots__/index.test.ts.snap @@ -35,7 +35,7 @@ jobs: uses: actions/checkout@v3 - name: Run \`docs\` command πŸš€ - uses: readmeio/rdme@7.8.9 + uses: readmeio/rdme@v7 with: rdme: docs ./__tests__/__fixtures__/docs/new-docs --key=\${{ secrets.README_API_KEY }} --version=1.0.0 " @@ -76,7 +76,7 @@ jobs: uses: actions/checkout@v3 - name: Run \`docs\` command πŸš€ - uses: readmeio/rdme@7.8.9 + uses: readmeio/rdme@v7 with: rdme: docs ./__tests__/__fixtures__/docs/new-docs --key=\${{ secrets.README_API_KEY }} --version=1.0.0 " @@ -117,7 +117,7 @@ jobs: uses: actions/checkout@v3 - name: Run \`docs\` command πŸš€ - uses: readmeio/rdme@7.8.9 + uses: readmeio/rdme@v7 with: rdme: docs ./__tests__/__fixtures__/docs/new-docs --key=\${{ secrets.README_API_KEY }} --version=1.0.1 " diff --git a/__tests__/cmds/openapi/__snapshots__/index.test.ts.snap b/__tests__/cmds/openapi/__snapshots__/index.test.ts.snap index 90878dafb..a15e4bc05 100644 --- a/__tests__/cmds/openapi/__snapshots__/index.test.ts.snap +++ b/__tests__/cmds/openapi/__snapshots__/index.test.ts.snap @@ -35,7 +35,7 @@ jobs: uses: actions/checkout@v3 - name: Run \`openapi\` command πŸš€ - uses: readmeio/rdme@7.8.9 + uses: readmeio/rdme@v7 with: rdme: openapi ./__tests__/__fixtures__/ref-oas/petstore.json --key=\${{ secrets.README_API_KEY }} --version=1.0.0 --create " @@ -76,7 +76,7 @@ jobs: uses: actions/checkout@v3 - name: Run \`openapi\` command πŸš€ - uses: readmeio/rdme@7.8.9 + uses: readmeio/rdme@v7 with: rdme: openapi ./__tests__/__fixtures__/ref-oas/petstore.json --key=\${{ secrets.README_API_KEY }} --version=1.0.1 --create " @@ -117,7 +117,7 @@ jobs: uses: actions/checkout@v3 - name: Run \`openapi\` command πŸš€ - uses: readmeio/rdme@7.8.9 + uses: readmeio/rdme@v7 with: rdme: openapi ./__tests__/__fixtures__/ref-oas/petstore.json --key=\${{ secrets.README_API_KEY }} --id=1 " @@ -158,7 +158,7 @@ jobs: uses: actions/checkout@v3 - name: Run \`openapi\` command πŸš€ - uses: readmeio/rdme@7.8.9 + uses: readmeio/rdme@v7 with: rdme: openapi ./__tests__/__fixtures__/ref-oas/petstore.json --key=\${{ secrets.README_API_KEY }} --id=1 " @@ -199,7 +199,7 @@ jobs: uses: actions/checkout@v3 - name: Run \`openapi\` command πŸš€ - uses: readmeio/rdme@7.8.9 + uses: readmeio/rdme@v7 with: rdme: openapi ./__tests__/__fixtures__/ref-oas/petstore.json --key=\${{ secrets.README_API_KEY }} --id=1 " @@ -240,7 +240,7 @@ jobs: uses: actions/checkout@v3 - name: Run \`openapi\` command πŸš€ - uses: readmeio/rdme@7.8.9 + uses: readmeio/rdme@v7 with: rdme: openapi petstore.json --key=\${{ secrets.README_API_KEY }} --id=1 --workingDirectory=./__tests__/__fixtures__/relative-ref-oas " @@ -281,7 +281,7 @@ jobs: uses: actions/checkout@v3 - name: Run \`openapi\` command πŸš€ - uses: readmeio/rdme@7.8.9 + uses: readmeio/rdme@v7 with: rdme: openapi ./__tests__/__fixtures__/ref-oas/petstore.json --key=\${{ secrets.README_API_KEY }} --id=spec2 " diff --git a/__tests__/cmds/openapi/__snapshots__/validate.test.ts.snap b/__tests__/cmds/openapi/__snapshots__/validate.test.ts.snap index cf0fc91a3..6e5943673 100644 --- a/__tests__/cmds/openapi/__snapshots__/validate.test.ts.snap +++ b/__tests__/cmds/openapi/__snapshots__/validate.test.ts.snap @@ -31,7 +31,7 @@ jobs: uses: actions/checkout@v3 - name: Run \`openapi:validate\` command πŸš€ - uses: readmeio/rdme@7.8.9 + uses: readmeio/rdme@v7 with: rdme: openapi:validate __tests__/__fixtures__/petstore-simple-weird-version.json " @@ -68,7 +68,7 @@ jobs: uses: actions/checkout@v3 - name: Run \`openapi:validate\` command πŸš€ - uses: readmeio/rdme@7.8.9 + uses: readmeio/rdme@v7 with: rdme: openapi:validate petstore.json --workingDirectory=./__tests__/__fixtures__/relative-ref-oas " @@ -105,7 +105,7 @@ jobs: uses: actions/checkout@v3 - name: Run \`openapi:validate\` command πŸš€ - uses: readmeio/rdme@7.8.9 + uses: readmeio/rdme@v7 with: rdme: openapi:validate __tests__/__fixtures__/petstore-simple-weird-version.json " @@ -142,7 +142,7 @@ jobs: uses: actions/checkout@v3 - name: Run \`openapi:validate\` command πŸš€ - uses: readmeio/rdme@7.8.9 + uses: readmeio/rdme@v7 with: rdme: openapi:validate __tests__/__fixtures__/petstore-simple-weird-version.json " diff --git a/__tests__/helpers/get-gha-setup.ts b/__tests__/helpers/get-gha-setup.ts index e880d0fc9..4e055c609 100644 --- a/__tests__/helpers/get-gha-setup.ts +++ b/__tests__/helpers/get-gha-setup.ts @@ -35,8 +35,8 @@ export function before(writeFileSyncCb) { process.env.TEST_RDME_CREATEGHA = 'true'; - const spy = jest.spyOn(getPkgVersion, 'getPkgVersion'); - spy.mockReturnValue(Promise.resolve('7.8.9')); + const spy = jest.spyOn(getPkgVersion, 'getMajorPkgVersion'); + spy.mockReturnValue(Promise.resolve(7)); } /** diff --git a/__tests__/lib/__snapshots__/createGHA.test.ts.snap b/__tests__/lib/__snapshots__/createGHA.test.ts.snap index 72e235c30..05cd6cf45 100644 --- a/__tests__/lib/__snapshots__/createGHA.test.ts.snap +++ b/__tests__/lib/__snapshots__/createGHA.test.ts.snap @@ -35,7 +35,7 @@ jobs: uses: actions/checkout@v3 - name: Run \`changelogs\` command πŸš€ - uses: readmeio/rdme@7.8.9 + uses: readmeio/rdme@v7 with: rdme: changelogs ./changelogs --key=\${{ secrets.README_API_KEY }} " @@ -76,7 +76,7 @@ jobs: uses: actions/checkout@v3 - name: Run \`changelogs\` command πŸš€ - uses: readmeio/rdme@7.8.9 + uses: readmeio/rdme@v7 with: rdme: changelogs ./changelogs/rdme.md --key=\${{ secrets.README_API_KEY }} " @@ -117,7 +117,7 @@ jobs: uses: actions/checkout@v3 - name: Run \`changelogs\` command πŸš€ - uses: readmeio/rdme@7.8.9 + uses: readmeio/rdme@v7 with: rdme: changelogs ./changelogs --key=\${{ secrets.README_API_KEY }} " @@ -158,7 +158,7 @@ jobs: uses: actions/checkout@v3 - name: Run \`changelogs\` command πŸš€ - uses: readmeio/rdme@7.8.9 + uses: readmeio/rdme@v7 with: rdme: changelogs ./changelogs/rdme.md --key=\${{ secrets.README_API_KEY }} " @@ -199,7 +199,7 @@ jobs: uses: actions/checkout@v3 - name: Run \`custompages\` command πŸš€ - uses: readmeio/rdme@7.8.9 + uses: readmeio/rdme@v7 with: rdme: custompages ./custompages --key=\${{ secrets.README_API_KEY }} " @@ -240,7 +240,7 @@ jobs: uses: actions/checkout@v3 - name: Run \`custompages\` command πŸš€ - uses: readmeio/rdme@7.8.9 + uses: readmeio/rdme@v7 with: rdme: custompages ./custompages/rdme.md --key=\${{ secrets.README_API_KEY }} " @@ -281,7 +281,7 @@ jobs: uses: actions/checkout@v3 - name: Run \`custompages\` command πŸš€ - uses: readmeio/rdme@7.8.9 + uses: readmeio/rdme@v7 with: rdme: custompages ./custompages --key=\${{ secrets.README_API_KEY }} " @@ -322,7 +322,7 @@ jobs: uses: actions/checkout@v3 - name: Run \`custompages\` command πŸš€ - uses: readmeio/rdme@7.8.9 + uses: readmeio/rdme@v7 with: rdme: custompages ./custompages/rdme.md --key=\${{ secrets.README_API_KEY }} " @@ -363,7 +363,7 @@ jobs: uses: actions/checkout@v3 - name: Run \`docs\` command πŸš€ - uses: readmeio/rdme@7.8.9 + uses: readmeio/rdme@v7 with: rdme: docs --key=\${{ secrets.README_API_KEY }} --version=1.0.0 " @@ -404,7 +404,7 @@ jobs: uses: actions/checkout@v3 - name: Run \`docs\` command πŸš€ - uses: readmeio/rdme@7.8.9 + uses: readmeio/rdme@v7 with: rdme: docs ./docs/rdme.md --key=\${{ secrets.README_API_KEY }} --version=1.0.0 " @@ -445,7 +445,7 @@ jobs: uses: actions/checkout@v3 - name: Run \`docs\` command πŸš€ - uses: readmeio/rdme@7.8.9 + uses: readmeio/rdme@v7 with: rdme: docs --key=\${{ secrets.README_API_KEY }} --version=1.0.0 " @@ -486,7 +486,7 @@ jobs: uses: actions/checkout@v3 - name: Run \`docs\` command πŸš€ - uses: readmeio/rdme@7.8.9 + uses: readmeio/rdme@v7 with: rdme: docs ./docs/rdme.md --key=\${{ secrets.README_API_KEY }} --version=1.0.0 " @@ -527,7 +527,7 @@ jobs: uses: actions/checkout@v3 - name: Run \`openapi\` command πŸš€ - uses: readmeio/rdme@7.8.9 + uses: readmeio/rdme@v7 with: rdme: openapi petstore.json --key=\${{ secrets.README_API_KEY }} --id=spec_id " @@ -568,7 +568,7 @@ jobs: uses: actions/checkout@v3 - name: Run \`openapi\` command πŸš€ - uses: readmeio/rdme@7.8.9 + uses: readmeio/rdme@v7 with: rdme: openapi petstore.json --key=\${{ secrets.README_API_KEY }} --id=spec_id " @@ -605,7 +605,7 @@ jobs: uses: actions/checkout@v3 - name: Run \`openapi:validate\` command πŸš€ - uses: readmeio/rdme@7.8.9 + uses: readmeio/rdme@v7 with: rdme: openapi:validate petstore.json " @@ -642,7 +642,7 @@ jobs: uses: actions/checkout@v3 - name: Run \`openapi:validate\` command πŸš€ - uses: readmeio/rdme@7.8.9 + uses: readmeio/rdme@v7 with: rdme: openapi:validate petstore.json " diff --git a/__tests__/lib/createGHA.test.ts b/__tests__/lib/createGHA.test.ts index ca931c98c..2e44ddc83 100644 --- a/__tests__/lib/createGHA.test.ts +++ b/__tests__/lib/createGHA.test.ts @@ -14,13 +14,8 @@ import DocsCommand from '../../src/cmds/docs'; import OpenAPICommand from '../../src/cmds/openapi'; import OpenAPIValidateCommand from '../../src/cmds/openapi/validate'; import configstore from '../../src/lib/configstore'; -import createGHA, { - getConfigStoreKey, - getGHAFileName, - getGitData, - getMajorRdmeVersion, - git, -} from '../../src/lib/createGHA'; +import createGHA, { getConfigStoreKey, getGHAFileName, getGitData, git } from '../../src/lib/createGHA'; +import { getMajorPkgVersion } from '../../src/lib/getPkgVersion'; import { after, before } from '../helpers/get-gha-setup'; import getGitRemoteMock from '../helpers/get-git-mock'; import ghaWorkflowSchema from '../helpers/github-workflow-schema.json'; @@ -130,7 +125,7 @@ describe('#createGHA', () => { const repoRoot = process.cwd(); - configstore.set(getConfigStoreKey(repoRoot), (await getMajorRdmeVersion()) - 1); + configstore.set(getConfigStoreKey(repoRoot), (await getMajorPkgVersion()) - 1); return expect(createGHA('', cmd, command.args, opts)).resolves.toMatch( 'Your GitHub Actions workflow file has been created!' @@ -153,7 +148,7 @@ describe('#createGHA', () => { ) ); - expect(configstore.get(getConfigStoreKey(repoRoot))).toBe(await getMajorRdmeVersion()); + expect(configstore.get(getConfigStoreKey(repoRoot))).toBe(await getMajorPkgVersion()); }); it('should not run if not a repo', () => { @@ -175,7 +170,7 @@ describe('#createGHA', () => { it('should not run if user previously declined to set up GHA for current directory + pkg version', async () => { const repoRoot = process.cwd(); - configstore.set(getConfigStoreKey(repoRoot), await getMajorRdmeVersion()); + configstore.set(getConfigStoreKey(repoRoot), await getMajorPkgVersion()); return expect(createGHA('success!', cmd, command.args, opts)).resolves.toBe('success!'); }); diff --git a/__tests__/lib/getNodeVersion.test.ts b/__tests__/lib/getNodeVersion.test.ts deleted file mode 100644 index d5476515b..000000000 --- a/__tests__/lib/getNodeVersion.test.ts +++ /dev/null @@ -1,12 +0,0 @@ -import semver from 'semver'; - -import pkg from '../../package.json'; -import getNodeVersion from '../../src/lib/getNodeVersion'; - -describe('#getNodeVersion()', () => { - it('should extract version that matches range in package.json', () => { - const version = parseInt(getNodeVersion(), 10); - const cleanedVersion = semver.valid(semver.coerce(version)); - expect(semver.satisfies(cleanedVersion as string, pkg.engines.node)).toBe(true); - }); -}); diff --git a/__tests__/lib/getPkgVersion.test.ts b/__tests__/lib/getPkgVersion.test.ts new file mode 100644 index 000000000..0d957ff76 --- /dev/null +++ b/__tests__/lib/getPkgVersion.test.ts @@ -0,0 +1,49 @@ +import nock from 'nock'; +import semver from 'semver'; + +import pkg from '../../package.json'; +import { getNodeVersion, getPkgVersion } from '../../src/lib/getPkgVersion'; + +describe('#getNodeVersion()', () => { + it('should extract version that matches range in package.json', () => { + const version = getNodeVersion(); + const cleanedVersion = semver.valid(semver.coerce(version)); + expect(semver.satisfies(cleanedVersion as string, pkg.engines.node)).toBe(true); + }); +}); + +describe('#getPkgVersion()', () => { + let consoleErrorSpy; + + beforeEach(() => { + consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(); + }); + + afterEach(() => { + consoleErrorSpy.mockRestore(); + + nock.cleanAll(); + }); + + it('should grab version from package.json by default', () => { + return expect(getPkgVersion()).resolves.toBe(pkg.version); + }); + + it('should fetch version from npm registry', async () => { + const mock = nock('https://registry.npmjs.com', { encodedQueryParams: true }) + .get('/rdme') + .reply(200, { 'dist-tags': { latest: '1.0' } }); + + await expect(getPkgVersion('latest')).resolves.toBe('1.0'); + + mock.done(); + }); + + it('should fallback if npm registry fails', async () => { + const mock = nock('https://registry.npmjs.com', { encodedQueryParams: true }).get('/rdme').reply(500); + + await expect(getPkgVersion('latest')).resolves.toBe(pkg.version); + + mock.done(); + }); +}); diff --git a/bin/set-major-version-tag.js b/bin/set-major-version-tag.js new file mode 100755 index 000000000..5992b1cf2 --- /dev/null +++ b/bin/set-major-version-tag.js @@ -0,0 +1,33 @@ +#! /usr/bin/env node +const { exec } = require('child_process'); + +const semverParse = require('semver/functions/parse'); + +const pkg = require('../package.json'); + +/** + * Sets major git tag as part of release process + * + * @example v7 + */ +async function setMajorVersionTag() { + const parsedVersion = semverParse(pkg.version); + + if (parsedVersion.prerelease.length) { + // eslint-disable-next-line no-console + console.warn('Pre-release version, not setting major version tag'); + return; + } + + exec(`git tag v${parsedVersion.major} -f -m 'Top-level tag pointing to ${parsedVersion.version}'`, (err, stdout) => { + if (err) { + // eslint-disable-next-line no-console + console.error(err); + process.exit(1); + } + // eslint-disable-next-line no-console + if (stdout) console.log(stdout); + }); +} + +setMajorVersionTag(); diff --git a/bin/set-version-output b/bin/set-version-output deleted file mode 100755 index b9b863772..000000000 --- a/bin/set-version-output +++ /dev/null @@ -1,17 +0,0 @@ -#! /usr/bin/env node -const { getPkgVersion } = require('../dist/src/lib/getPkgVersion'); -const getNodeVersion = require('../src/lib/getNodeVersion'); - -const name1 = 'RDME_VERSION'; -const name2 = 'NODE_VERSION'; - -/** - * Sets output parameters for GitHub Actions workflow - * Docs: https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-output-parameter - */ -async function setOutputs() { - console.log(`::set-output name=${name1}::${await getPkgVersion('latest')}`); // eslint-disable-line no-console - console.log(`::set-output name=${name2}::${getNodeVersion()}`); // eslint-disable-line no-console -} - -setOutputs(); diff --git a/bin/set-version-output.js b/bin/set-version-output.js new file mode 100755 index 000000000..f4d4a34de --- /dev/null +++ b/bin/set-version-output.js @@ -0,0 +1,16 @@ +#! /usr/bin/env node +const core = require('@actions/core'); + +const { getNodeVersion, getMajorPkgVersion } = require('../dist/src/lib/getPkgVersion'); + +/** + * Sets output parameters for GitHub Actions workflow so we can do + * a find-and-replace in our docs prior to syncing them to ReadMe + * Docs: https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-output-parameter + */ +async function setOutputs() { + core.setOutput('RDME_VERSION', `v${await getMajorPkgVersion('latest')}`); + core.setOutput('NODE_VERSION', getNodeVersion()); +} + +setOutputs(); diff --git a/documentation/github-actions-docs-example.md b/documentation/github-actions-docs-example.md index 54c77b99f..72fe4fcac 100644 --- a/documentation/github-actions-docs-example.md +++ b/documentation/github-actions-docs-example.md @@ -65,4 +65,4 @@ In the example above, every push to the `main` branch will sync the Markdown con > πŸ“˜ Keeping `rdme` up-to-date > -> Note that `@RDME_VERSION` (used in the above example) is the latest version of `rdme`. We recommend [configuring Dependabot to keep your actions up-to-date](https://docs.github.com/code-security/supply-chain-security/keeping-your-dependencies-updated-automatically/keeping-your-actions-up-to-date-with-dependabot). +> Note that `@RDME_VERSION` (used in the above example) is the latest version of `rdme`. We recommend [configuring Dependabot to keep your actions up-to-date](https://docs.github.com/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot). diff --git a/documentation/github-actions-openapi-example.md b/documentation/github-actions-openapi-example.md index 9441151f3..bc7764000 100644 --- a/documentation/github-actions-openapi-example.md +++ b/documentation/github-actions-openapi-example.md @@ -112,4 +112,4 @@ In the example above, every push to the `main` branch will sync the OpenAPI file > πŸ“˜ Keeping `rdme` up-to-date > -> Note that `@RDME_VERSION` (used in the above example) is the latest version of `rdme`. We recommend [configuring Dependabot to keep your actions up-to-date](https://docs.github.com/code-security/supply-chain-security/keeping-your-dependencies-updated-automatically/keeping-your-actions-up-to-date-with-dependabot). +> Note that `@RDME_VERSION` (used in the above example) is the latest version of `rdme`. We recommend [configuring Dependabot to keep your actions up-to-date](https://docs.github.com/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot). diff --git a/documentation/legacy-github-action.md b/documentation/legacy-github-action.md index c5e75f71a..d902c6e91 100644 --- a/documentation/legacy-github-action.md +++ b/documentation/legacy-github-action.md @@ -44,7 +44,7 @@ For migrating to [the `rdme`-based GitHub Action](https://docs.readme.com/docs/r There are a few things to note: 1. This workflow will infer the `api-version` based on the `API_DEFINITION_ID` parameter that you pass in, so the API version parameter is no longer needed here. -2. `@RDME_VERSION` is the latest version of `rdme`. To ensure you're getting the latest features and security updates, we strongly recommend setting up [Dependabot](https://docs.github.com/code-security/supply-chain-security/keeping-your-dependencies-updated-automatically/keeping-your-actions-up-to-date-with-dependabot) to keep this package up-to-date. +2. `@RDME_VERSION` is the latest version of `rdme`. To ensure you're getting the latest features and security updates, we strongly recommend setting up [Dependabot](https://docs.github.com/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot) to keep this package up-to-date. 3. If you used secrets to encrypt the `readme-oas-key` value, you'll have to split this value out into two separate secretsβ€”one for the API key and one for the API definition ID. You can see an example of this [here](https://docs.readme.com/docs/github-actions-openapi-example).
diff --git a/documentation/rdme.md b/documentation/rdme.md index 2802fbfc1..58d831b98 100644 --- a/documentation/rdme.md +++ b/documentation/rdme.md @@ -110,7 +110,7 @@ While there are [dozens of event options available](https://docs.github.com/acti > πŸ“˜ Keeping `rdme` up-to-date > -> Note that `@RDME_VERSION` (used in the examples on this page) is the latest version of `rdme`. We recommend [configuring Dependabot to keep your actions up-to-date](https://docs.github.com/code-security/supply-chain-security/keeping-your-dependencies-updated-automatically/keeping-your-actions-up-to-date-with-dependabot). +> Note that `@RDME_VERSION` (used in the examples on this page) is the latest version of `rdme`. We recommend [configuring Dependabot to keep your actions up-to-date](https://docs.github.com/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot). ### Quick Start diff --git a/package.json b/package.json index 6526fa8d4..463fceb93 100644 --- a/package.json +++ b/package.json @@ -97,15 +97,16 @@ "build": "tsc", "bump": "npm version -m 'build: %s release'", "debug": "ts-node src/cli.ts", - "lint": "eslint . bin/rdme bin/set-version-output --ext .js,.ts", + "lint": "eslint . bin/rdme --ext .js,.ts", "lint-docs": "npx alex . && npm run prettier:docs", - "postversion": "git tag $npm_package_version", + "postversion": "git tag $npm_package_version && ./bin/set-major-version-tag.js", "prebuild": "rm -rf dist/", "prepack": "npm run build", "pretest": "npm run lint && npm run lint-docs", "prettier": "prettier --list-different \"./**/**.{md,js,ts}\"", "prettier:docs": "prettier --list-different \"./**/**.md\"", "prettier:write": "prettier --list-different --write \"./**/**.{md,js,ts}\"", + "preversion": "npm ci && npm run build", "release": "npx conventional-changelog-cli -i CHANGELOG.md -s", "test": "jest --coverage", "version": "npm run release && git add CHANGELOG.md" diff --git a/src/lib/createGHA/index.ts b/src/lib/createGHA/index.ts index bc29d46d8..b8b385196 100644 --- a/src/lib/createGHA/index.ts +++ b/src/lib/createGHA/index.ts @@ -7,12 +7,11 @@ import path from 'path'; import chalk from 'chalk'; import prompts from 'prompts'; -import semverMajor from 'semver/functions/major'; import simpleGit from 'simple-git'; import { checkFilePath, cleanFileName } from '../checkFile'; import configstore from '../configstore'; -import { getPkgVersion } from '../getPkgVersion'; +import { getMajorPkgVersion } from '../getPkgVersion'; import isCI, { isNpmScript, isTest } from '../isCI'; import { debug, info } from '../logger'; import promptTerminal from '../promptWrapper'; @@ -34,13 +33,6 @@ export const getConfigStoreKey = (repoRoot: string) => `createGHA.${repoRoot}`; const GITHUB_WORKFLOW_DIR = '.github/workflows'; const GITHUB_SECRET_NAME = 'README_API_KEY'; -/** - * The current major `rdme` version - * - * @example 8 - */ -export const getMajorRdmeVersion = async () => semverMajor(await getPkgVersion()); - export const git = simpleGit(); /** @@ -171,7 +163,7 @@ export default async function createGHA( const configVal = configstore.get(getConfigStoreKey(repoRoot)); debug(`repo value in config: ${configVal}`); - const majorPkgVersion = await getMajorRdmeVersion(); + const majorPkgVersion = await getMajorPkgVersion(); debug(`major pkg version: ${majorPkgVersion}`); if (!opts.github) { @@ -262,7 +254,7 @@ export default async function createGHA( cleanCommand: cleanFileName(command), command, commandString: constructCmdString(command, args, opts), - rdmeVersion: await getPkgVersion(), + rdmeVersion: `v${majorPkgVersion}`, timestamp: new Date().toISOString(), }; diff --git a/src/lib/getNodeVersion.js b/src/lib/getNodeVersion.js deleted file mode 100644 index 074476df8..000000000 --- a/src/lib/getNodeVersion.js +++ /dev/null @@ -1,17 +0,0 @@ -/* eslint-disable @typescript-eslint/no-var-requires */ -const pkg = require('../../package.json'); - -/** - * The reason this file has remained in JavaScript is because we need to - * be able to run this file without installing/building any dependencies. - */ - -/** - * Return the major Node.js version specified in our `package.json` config. - * - * @example 14 - */ -module.exports = function getNodeVersion() { - const { node } = pkg.engines; - return Array.from(node.matchAll(/\d+/g)).pop().toString(); -}; diff --git a/src/lib/getPkgVersion.ts b/src/lib/getPkgVersion.ts index 27cbddb0d..b043d1f49 100644 --- a/src/lib/getPkgVersion.ts +++ b/src/lib/getPkgVersion.ts @@ -1,30 +1,55 @@ // eslint-disable-next-line no-restricted-imports import fetch from 'node-fetch'; +import semver from 'semver'; import pkg from '../../package.json'; +import { error } from './logger'; + const registryUrl = 'https://registry.npmjs.com/rdme'; +/** + * @see {@link https://docs.npmjs.com/adding-dist-tags-to-packages} + */ +type npmDistTag = 'latest'; + +/** + * Return the major Node.js version specified in our `package.json` config. + * + * @example 14 + */ +export function getNodeVersion() { + const { node } = pkg.engines; + return semver.minVersion(node).major; +} + /** * The current `rdme` version * * @param npmDistTag the `npm` dist tag to retrieve. If this value is omitted, * the version from the `package.json` is returned. * @example "8.0.0" - * @see {@link https://docs.npmjs.com/cli/dist-tag} - * @note we mock this function in our snapshots + * @see {@link https://docs.npmjs.com/adding-dist-tags-to-packages} + * @note we mock this function in our snapshots, hence it's not the default * @see {@link https://stackoverflow.com/a/54245672} */ -export async function getPkgVersion(npmDistTag?: 'latest' | 'next'): Promise { +export async function getPkgVersion(npmDistTag?: npmDistTag): Promise { if (npmDistTag) { return fetch(registryUrl) .then(res => res.json()) .then(body => body['dist-tags'][npmDistTag]) - .catch(() => { - // eslint-disable-next-line no-console - console.error('error fetching version from npm registry'); + .catch(err => { + error(`error fetching version from npm registry: ${err.message}`); return pkg.version; }); } return pkg.version; } + +/** + * The current major `rdme` version + * + * @example 8 + */ +export const getMajorPkgVersion = async (npmDistTag?: npmDistTag): Promise => + semver.major(await getPkgVersion(npmDistTag)); diff --git a/src/lib/logger.ts b/src/lib/logger.ts index 26caa8433..f4e3d40e3 100644 --- a/src/lib/logger.ts +++ b/src/lib/logger.ts @@ -20,13 +20,13 @@ function debug(input: string) { } /** - * Wrapper for warn statements. + * Wrapper for error statements. */ -function warn(input: string) { +function error(input: string) { /* istanbul ignore next */ - if (isGHA() && !isTest()) return core.warning(input); + if (isGHA() && !isTest()) return core.error(input); // eslint-disable-next-line no-console - return console.warn(chalk.yellow(`⚠️ Warning! ${input}`)); + return console.error(chalk.red(input)); } /** @@ -53,4 +53,14 @@ function oraOptions() { return opts; } -export { debug, warn, info, oraOptions }; +/** + * Wrapper for warn statements. + */ +function warn(input: string) { + /* istanbul ignore next */ + if (isGHA() && !isTest()) return core.warning(input); + // eslint-disable-next-line no-console + return console.warn(chalk.yellow(`⚠️ Warning! ${input}`)); +} + +export { debug, error, info, oraOptions, warn };