From 40e414c35f8c2b65196d9ceaa6ce373b361c233f Mon Sep 17 00:00:00 2001 From: Luke Karrys Date: Mon, 13 Feb 2023 16:48:25 -0700 Subject: [PATCH] fix: misc fixes --- .github/actions/audit/action.yml | 5 +- .github/actions/changed-files/action.yml | 2 +- .github/actions/changed-workspaces/action.yml | 15 +- .github/actions/lint/action.yml | 3 + .github/actions/setup/action.yml | 12 +- .github/workflows/ci.yml | 6 +- .github/workflows/post-dependabot.yml | 4 +- bin/changed-workspaces.js | 2 +- lib/check/check-required.js | 10 +- lib/index.js | 21 +-- lib/util/config.js | 38 ++++ lib/util/has-package.js | 2 +- .../test/apply/source-snapshots.js.test.cjs | 163 ++++++++++-------- .../test/check/diff-snapshots.js.test.cjs | 6 +- test/apply/dependabot.js | 63 ------- test/check/snapshots.js | 5 +- test/setup.js | 58 ++++--- test/util/has-package.js | 2 +- workspaces/config/lib/index.js | 47 ++--- workspaces/content/lib/actions/audit.yml | 5 +- .../content/lib/actions/changed-files.yml | 2 +- .../lib/actions/changed-workspaces.yml | 15 +- workspaces/content/lib/actions/lint.yml | 3 + workspaces/content/lib/actions/setup.yml | 12 +- workspaces/content/lib/index.js | 3 - workspaces/content/lib/workflows/ci.yml | 6 +- .../content/lib/workflows/post-dependabot.yml | 4 +- workspaces/files/lib/index.js | 11 +- 28 files changed, 251 insertions(+), 274 deletions(-) create mode 100644 lib/util/config.js diff --git a/.github/actions/audit/action.yml b/.github/actions/audit/action.yml index c66c5ea4..decff931 100644 --- a/.github/actions/audit/action.yml +++ b/.github/actions/audit/action.yml @@ -10,8 +10,11 @@ inputs: runs: using: composite steps: - - name: Run Audit + - name: Run Production Audit shell: ${{ inputs.shell }} run: | npm audit --omit=dev + - name: Run Full Audit + shell: ${{ inputs.shell }} + run: | npm audit --audit-level=none diff --git a/.github/actions/changed-files/action.yml b/.github/actions/changed-files/action.yml index 721ad58e..75d85a84 100644 --- a/.github/actions/changed-files/action.yml +++ b/.github/actions/changed-files/action.yml @@ -8,7 +8,7 @@ inputs: required: true outputs: - files: + names: value: ${{ steps.files.outputs.result }} runs: diff --git a/.github/actions/changed-workspaces/action.yml b/.github/actions/changed-workspaces/action.yml index dced0657..aa0eac55 100644 --- a/.github/actions/changed-workspaces/action.yml +++ b/.github/actions/changed-workspaces/action.yml @@ -5,15 +5,8 @@ name: Get Changed Workspaces inputs: token: description: GitHub token to use - shell: - description: shell to run on - default: bash - all: - default: false - type: boolean files: - description: json stringified array of file names - type: string + description: json stringified array of file names or --all outputs: flags: @@ -24,14 +17,14 @@ runs: steps: - name: Get Changed Files uses: ./.github/actions/changed-files - if: ${{ !inputs.all && !inputs.files }} + if: ${{ !inputs.files }} id: files with: token: ${{ inputs.token }} - name: Get Workspaces - shell: ${{ inputs.shell }} + shell: bash id: workspaces run: | - flags=$(npm exec --offline -- template-oss-changed-workspaces '${{ (inputs.all && '--all') || (inputs.files || steps.files.outputs.result) }}') + flags=$(npm exec --offline -- template-oss-changed-workspaces '${{ inputs.files || steps.files.outputs.names }}') echo "flags=${flags}" >> $GITHUB_OUTPUT diff --git a/.github/actions/lint/action.yml b/.github/actions/lint/action.yml index 2c335673..43090451 100644 --- a/.github/actions/lint/action.yml +++ b/.github/actions/lint/action.yml @@ -16,4 +16,7 @@ runs: shell: ${{ inputs.shell }} run: | npm run lint --ignore-scripts ${{ inputs.flags }} + - name: Post Lint + shell: ${{ inputs.shell }} + run: | npm run postlint --ignore-scripts ${{ inputs.flags }} diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml index 2d35f859..774b1897 100644 --- a/.github/actions/setup/action.yml +++ b/.github/actions/setup/action.yml @@ -12,15 +12,13 @@ inputs: default: latest cache: description: whether to cache npm install or not - type: boolean default: false shell: description: shell to run on default: bash deps: description: whether to run the deps step - type: boolean - default: true + default: 'true' deps-command: description: command to run for the dependencies step default: install --ignore-scripts --no-audit --no-fund @@ -40,12 +38,12 @@ runs: uses: actions/setup-node@v3 with: node-version: ${{ inputs.node-version }} - cache: ${{ (inputs.cache && 'npm') || null }} + cache: ${{ (inputs.cache == 'true' && 'npm') || '' }} - name: Check Node Version if: inputs.npm-version id: node-version - shell: ${{ inputs.shell }} + shell: bash run: | NODE_VERSION=$(node --version) echo $NODE_VERSION @@ -83,13 +81,13 @@ runs: run: npm -v - name: Setup Dependencies - if: inputs.deps + if: inputs.deps == 'true' uses: ./.github/actions/deps with: command: ${{ inputs.deps-command }} flags: ${{ inputs.deps-flags }} - name: Add Problem Matcher - shell: ${{ inputs.shell }} + shell: bash run: | [[ -f ./.github/matchers/tap.json ]] && echo "::add-matcher::.github/matchers/tap.json" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 07af9fea..610c71f3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -67,7 +67,7 @@ jobs: uses: ./.github/actions/changed-workspaces with: token: ${{ secrets.GITHUB_TOKEN }} - all: ${{ inputs.all }} + files: ${{ (inputs.all && '--all') || '' }} - name: Lint uses: ./.github/actions/lint @@ -113,6 +113,7 @@ jobs: steps: - name: Continue Matrix Run id: continue-matrix + shell: bash run: | if [[ "${{ matrix.node-version }}" == "14.17.0" || "${{ inputs.all }}" == "true" ]]; then echo "result=true" >> $GITHUB_OUTPUT @@ -148,9 +149,8 @@ jobs: continue-on-error: ${{ !!steps.check.outputs.check-id }} uses: ./.github/actions/changed-workspaces with: - shell: ${{ matrix.platform.shell }} token: ${{ secrets.GITHUB_TOKEN }} - all: ${{ inputs.all }} + files: ${{ (inputs.all && '--all') || '' }} - name: Test if: steps.continue-matrix.outputs.result diff --git a/.github/workflows/post-dependabot.yml b/.github/workflows/post-dependabot.yml index 381a2055..942bc623 100644 --- a/.github/workflows/post-dependabot.yml +++ b/.github/workflows/post-dependabot.yml @@ -5,8 +5,8 @@ name: Post Dependabot on: pull_request jobs: - template-oss: - name: template-oss + npmcli-template-oss: + name: "@npmcli/template-oss" permissions: contents: write if: github.repository_owner == 'npm' && github.actor == 'dependabot[bot]' diff --git a/bin/changed-workspaces.js b/bin/changed-workspaces.js index c36d75db..51c2a2d4 100755 --- a/bin/changed-workspaces.js +++ b/bin/changed-workspaces.js @@ -44,7 +44,7 @@ const main = async ({ cwd, files, all }) => { const arg = process.argv[2] const all = arg === '--all' -const files = all ? [] : JSON.parse(arg ?? '[]') +const files = all ? [] : JSON.parse(arg || '[]') module.exports = main({ cwd: process.cwd(), diff --git a/lib/check/check-required.js b/lib/check/check-required.js index cb0485bf..4a32a0b2 100644 --- a/lib/check/check-required.js +++ b/lib/check/check-required.js @@ -1,6 +1,7 @@ const log = require('proc-log') const npa = require('npm-package-arg') const { partition } = require('lodash') +const { NAME, VERSION } = require('../util/config.js') const hasPackage = require('../util/has-package.js') const rmCommand = (specs) => @@ -11,10 +12,17 @@ const installCommand = (specs, flags) => specs.length ? // ensure required packages are present in the correct place const run = ({ pkg, path, config: { requiredPackages = {} } }) => { + const allRequiredPackages = { + ...requiredPackages, + devDependencies: [ + `${NAME}@${VERSION}`, + ...(requiredPackages.devDependencies || []), + ], + } // keys are the dependency location in package.json // values are a filtered list of parsed specs that dont exist in the current package // { [location]: [spec1, spec2] } - const requiredByLocation = Object.entries(requiredPackages) + const requiredByLocation = Object.entries(allRequiredPackages) .reduce((acc, [location, pkgs]) => { acc[location] = pkgs .filter((spec) => !hasPackage(pkg, spec, [location], path)) diff --git a/lib/index.js b/lib/index.js index adfcd037..945ebb5f 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,14 +1,14 @@ const log = require('proc-log') const { resolve } = require('path') -const getConfig = require('@npmcli/template-oss-config') const PackageJson = require('@npmcli/package-json') const mapWorkspaces = require('@npmcli/map-workspaces') +const { getConfig, CONFIG_KEY } = require('./util/config.js') const getPkg = async (path) => { log.verbose('get-pkg', path) const pkgJson = (await PackageJson.load(path)).content - const pkgConfig = getConfig.getPkgConfig(pkgJson) + const pkgConfig = pkgJson[CONFIG_KEY] || {} log.verbose('get-pkg', pkgConfig) if (pkgConfig.content) { @@ -43,23 +43,12 @@ const getWsPkgs = async (root, rootPkg) => { return wsPkgs } -const getPkgs = async (root) => { - log.verbose('get-pkgs', 'root', root) +const runAll = async (root, checks) => { + const results = [] const rootPkg = await getPkg(root) - const wsPkgs = await getWsPkgs(root, rootPkg) - - return { - rootPkg, - wsPkgs, - pkgs: [rootPkg].concat(wsPkgs), - } -} - -const runAll = async (root, checks) => { - const results = [] - const { pkgs, rootPkg, wsPkgs } = await getPkgs(root) + const pkgs = [rootPkg].concat(wsPkgs) const fullRootConfig = await getConfig({ pkg: rootPkg, diff --git a/lib/util/config.js b/lib/util/config.js new file mode 100644 index 00000000..a2822fd1 --- /dev/null +++ b/lib/util/config.js @@ -0,0 +1,38 @@ +const getDefaultConfig = require('@npmcli/template-oss-config') + +const { name: NAME, version: VERSION } = require('../../package.json') +const DEFAULT_CONTENT = require.resolve('@npmcli/template-oss-content') +const CONFIG_KEY = 'templateOSS' + +const getConfig = async (opts) => { + const { pkg, rootPkg } = opts + const isLatest = pkg.config.version === VERSION + const isDogFood = rootPkg.pkgJson.name === NAME + const isForce = process.argv.includes('--force') + + return { + ...await getDefaultConfig({ + ...opts, + defaultContent: DEFAULT_CONTENT, + }), + __NAME__: NAME, + __NAME_FS__: NAME.replace(/\//g, '-').replace(/@/g, ''), + __CONFIG_KEY__: CONFIG_KEY, + __VERSION__: VERSION, + // needs update if we are dogfooding this repo, with force argv, or its + // behind the current version + needsUpdate: isForce || isDogFood || !isLatest, + // booleans to control application of updates + isForce, + isDogFood, + isLatest, + } +} + +module.exports = { + getConfig, + NAME, + VERSION, + CONFIG_KEY, + DEFAULT_CONTENT, +} diff --git a/lib/util/has-package.js b/lib/util/has-package.js index bffddfad..f0c08d7d 100644 --- a/lib/util/has-package.js +++ b/lib/util/has-package.js @@ -2,7 +2,7 @@ const semver = require('semver') const npa = require('npm-package-arg') const { has } = require('lodash') const { join, extname } = require('path') -const { name: NAME } = require('../../package.json') +const { NAME } = require('../util/config.js') const installLocations = [ 'dependencies', diff --git a/tap-snapshots/test/apply/source-snapshots.js.test.cjs b/tap-snapshots/test/apply/source-snapshots.js.test.cjs index 13d1989c..93d15ab7 100644 --- a/tap-snapshots/test/apply/source-snapshots.js.test.cjs +++ b/tap-snapshots/test/apply/source-snapshots.js.test.cjs @@ -53,10 +53,13 @@ inputs: runs: using: composite steps: - - name: Run Audit + - name: Run Production Audit shell: \${{ inputs.shell }} run: | npm audit --omit=dev + - name: Run Full Audit + shell: \${{ inputs.shell }} + run: | npm audit --audit-level=none .github/actions/changed-files/action.yml @@ -71,7 +74,7 @@ inputs: required: true outputs: - files: + names: value: \${{ steps.files.outputs.result }} runs: @@ -110,15 +113,8 @@ name: Get Changed Workspaces inputs: token: description: GitHub token to use - shell: - description: shell to run on - default: bash - all: - default: false - type: boolean files: - description: json stringified array of file names - type: string + description: json stringified array of file names or --all outputs: flags: @@ -129,16 +125,16 @@ runs: steps: - name: Get Changed Files uses: ./.github/actions/changed-files - if: \${{ !inputs.all && !inputs.files }} + if: \${{ !inputs.files }} id: files with: token: \${{ inputs.token }} - name: Get Workspaces - shell: \${{ inputs.shell }} + shell: bash id: workspaces run: | - flags=$(npm exec --offline -- template-oss-changed-workspaces '\${{ (inputs.all && '--all') || (inputs.files || steps.files.outputs.result) }}') + flags=$(npm exec --offline -- template-oss-changed-workspaces '\${{ inputs.files || steps.files.outputs.names }}') echo "flags=\${flags}" >> $GITHUB_OUTPUT .github/actions/conclude-check/action.yml @@ -279,6 +275,9 @@ runs: shell: \${{ inputs.shell }} run: | npm run lint --ignore-scripts \${{ inputs.flags }} + - name: Post Lint + shell: \${{ inputs.shell }} + run: | npm run postlint --ignore-scripts \${{ inputs.flags }} .github/actions/setup/action.yml @@ -297,15 +296,13 @@ inputs: default: latest cache: description: whether to cache npm install or not - type: boolean default: false shell: description: shell to run on default: bash deps: description: whether to run the deps step - type: boolean - default: true + default: 'true' deps-command: description: command to run for the dependencies step default: install --ignore-scripts --no-audit --no-fund @@ -325,12 +322,12 @@ runs: uses: actions/setup-node@v3 with: node-version: \${{ inputs.node-version }} - cache: \${{ (inputs.cache && 'npm') || null }} + cache: \${{ (inputs.cache == 'true' && 'npm') || '' }} - name: Check Node Version if: inputs.npm-version id: node-version - shell: \${{ inputs.shell }} + shell: bash run: | NODE_VERSION=$(node --version) echo $NODE_VERSION @@ -368,14 +365,14 @@ runs: run: npm -v - name: Setup Dependencies - if: inputs.deps + if: inputs.deps == 'true' uses: ./.github/actions/deps with: command: \${{ inputs.deps-command }} flags: \${{ inputs.deps-flags }} - name: Add Problem Matcher - shell: \${{ inputs.shell }} + shell: bash run: | [[ -f ./.github/matchers/tap.json ]] && echo "::add-matcher::.github/matchers/tap.json" @@ -713,7 +710,7 @@ jobs: uses: ./.github/actions/changed-workspaces with: token: \${{ secrets.GITHUB_TOKEN }} - all: \${{ inputs.all }} + files: \${{ (inputs.all && '--all') || '' }} - name: Lint uses: ./.github/actions/lint @@ -759,6 +756,7 @@ jobs: steps: - name: Continue Matrix Run id: continue-matrix + shell: bash run: | if [[ "\${{ matrix.node-version }}" == "14.17.0" || "\${{ inputs.all }}" == "true" ]]; then echo "result=true" >> $GITHUB_OUTPUT @@ -794,9 +792,8 @@ jobs: continue-on-error: \${{ !!steps.check.outputs.check-id }} uses: ./.github/actions/changed-workspaces with: - shell: \${{ matrix.platform.shell }} token: \${{ secrets.GITHUB_TOKEN }} - all: \${{ inputs.all }} + files: \${{ (inputs.all && '--all') || '' }} - name: Test if: steps.continue-matrix.outputs.result @@ -1428,6 +1425,9 @@ package.json { "name": "testpkg", "version": "1.0.0", + "devDependencies": { + "@npmcli/template-oss": "{{VERSION}}" + }, "scripts": { "lint": "eslint /"**/*.js/"", "postlint": "template-oss-check", @@ -1527,7 +1527,10 @@ package.json "version": "{{VERSION}}" }, "name": "testpkg", - "version": "1.0.0" + "version": "1.0.0", + "devDependencies": { + "@npmcli/template-oss": "{{VERSION}}" + } } ` @@ -1583,10 +1586,13 @@ inputs: runs: using: composite steps: - - name: Run Audit + - name: Run Production Audit shell: \${{ inputs.shell }} run: | npm audit --omit=dev + - name: Run Full Audit + shell: \${{ inputs.shell }} + run: | npm audit --audit-level=none .github/actions/changed-files/action.yml @@ -1601,7 +1607,7 @@ inputs: required: true outputs: - files: + names: value: \${{ steps.files.outputs.result }} runs: @@ -1640,15 +1646,8 @@ name: Get Changed Workspaces inputs: token: description: GitHub token to use - shell: - description: shell to run on - default: bash - all: - default: false - type: boolean files: - description: json stringified array of file names - type: string + description: json stringified array of file names or --all outputs: flags: @@ -1659,16 +1658,16 @@ runs: steps: - name: Get Changed Files uses: ./.github/actions/changed-files - if: \${{ !inputs.all && !inputs.files }} + if: \${{ !inputs.files }} id: files with: token: \${{ inputs.token }} - name: Get Workspaces - shell: \${{ inputs.shell }} + shell: bash id: workspaces run: | - flags=$(npm exec --offline -- template-oss-changed-workspaces '\${{ (inputs.all && '--all') || (inputs.files || steps.files.outputs.result) }}') + flags=$(npm exec --offline -- template-oss-changed-workspaces '\${{ inputs.files || steps.files.outputs.names }}') echo "flags=\${flags}" >> $GITHUB_OUTPUT .github/actions/conclude-check/action.yml @@ -1809,6 +1808,9 @@ runs: shell: \${{ inputs.shell }} run: | npm run lint --ignore-scripts \${{ inputs.flags }} + - name: Post Lint + shell: \${{ inputs.shell }} + run: | npm run postlint --ignore-scripts \${{ inputs.flags }} .github/actions/setup/action.yml @@ -1827,15 +1829,13 @@ inputs: default: latest cache: description: whether to cache npm install or not - type: boolean default: false shell: description: shell to run on default: bash deps: description: whether to run the deps step - type: boolean - default: true + default: 'true' deps-command: description: command to run for the dependencies step default: install --ignore-scripts --no-audit --no-fund @@ -1855,12 +1855,12 @@ runs: uses: actions/setup-node@v3 with: node-version: \${{ inputs.node-version }} - cache: \${{ (inputs.cache && 'npm') || null }} + cache: \${{ (inputs.cache == 'true' && 'npm') || '' }} - name: Check Node Version if: inputs.npm-version id: node-version - shell: \${{ inputs.shell }} + shell: bash run: | NODE_VERSION=$(node --version) echo $NODE_VERSION @@ -1898,14 +1898,14 @@ runs: run: npm -v - name: Setup Dependencies - if: inputs.deps + if: inputs.deps == 'true' uses: ./.github/actions/deps with: command: \${{ inputs.deps-command }} flags: \${{ inputs.deps-flags }} - name: Add Problem Matcher - shell: \${{ inputs.shell }} + shell: bash run: | [[ -f ./.github/matchers/tap.json ]] && echo "::add-matcher::.github/matchers/tap.json" @@ -2267,7 +2267,7 @@ jobs: uses: ./.github/actions/changed-workspaces with: token: \${{ secrets.GITHUB_TOKEN }} - all: \${{ inputs.all }} + files: \${{ (inputs.all && '--all') || '' }} - name: Lint uses: ./.github/actions/lint @@ -2313,6 +2313,7 @@ jobs: steps: - name: Continue Matrix Run id: continue-matrix + shell: bash run: | if [[ "\${{ matrix.node-version }}" == "14.17.0" || "\${{ inputs.all }}" == "true" ]]; then echo "result=true" >> $GITHUB_OUTPUT @@ -2348,9 +2349,8 @@ jobs: continue-on-error: \${{ !!steps.check.outputs.check-id }} uses: ./.github/actions/changed-workspaces with: - shell: \${{ matrix.platform.shell }} token: \${{ secrets.GITHUB_TOKEN }} - all: \${{ inputs.all }} + files: \${{ (inputs.all && '--all') || '' }} - name: Test if: steps.continue-matrix.outputs.result @@ -2988,6 +2988,9 @@ package.json { "name": "testpkg", "version": "1.0.0", + "devDependencies": { + "@npmcli/template-oss": "{{VERSION}}" + }, "workspaces": [ "workspaces/a", "workspaces/b" @@ -3137,6 +3140,9 @@ workspaces/a/package.json { "name": "a", "version": "1.0.0", + "devDependencies": { + "@npmcli/template-oss": "{{VERSION}}" + }, "scripts": { "lint": "eslint /"**/*.js/"", "postlint": "template-oss-check", @@ -3215,6 +3221,9 @@ workspaces/b/package.json { "name": "b", "version": "1.0.0", + "devDependencies": { + "@npmcli/template-oss": "{{VERSION}}" + }, "scripts": { "lint": "eslint /"**/*.js/"", "postlint": "template-oss-check", @@ -3260,10 +3269,13 @@ inputs: runs: using: composite steps: - - name: Run Audit + - name: Run Production Audit shell: \${{ inputs.shell }} run: | npm audit --omit=dev + - name: Run Full Audit + shell: \${{ inputs.shell }} + run: | npm audit --audit-level=none .github/actions/changed-files/action.yml @@ -3278,7 +3290,7 @@ inputs: required: true outputs: - files: + names: value: \${{ steps.files.outputs.result }} runs: @@ -3317,15 +3329,8 @@ name: Get Changed Workspaces inputs: token: description: GitHub token to use - shell: - description: shell to run on - default: bash - all: - default: false - type: boolean files: - description: json stringified array of file names - type: string + description: json stringified array of file names or --all outputs: flags: @@ -3336,16 +3341,16 @@ runs: steps: - name: Get Changed Files uses: ./.github/actions/changed-files - if: \${{ !inputs.all && !inputs.files }} + if: \${{ !inputs.files }} id: files with: token: \${{ inputs.token }} - name: Get Workspaces - shell: \${{ inputs.shell }} + shell: bash id: workspaces run: | - flags=$(npm exec --offline -- template-oss-changed-workspaces '\${{ (inputs.all && '--all') || (inputs.files || steps.files.outputs.result) }}') + flags=$(npm exec --offline -- template-oss-changed-workspaces '\${{ inputs.files || steps.files.outputs.names }}') echo "flags=\${flags}" >> $GITHUB_OUTPUT .github/actions/conclude-check/action.yml @@ -3486,6 +3491,9 @@ runs: shell: \${{ inputs.shell }} run: | npm run lint --ignore-scripts \${{ inputs.flags }} + - name: Post Lint + shell: \${{ inputs.shell }} + run: | npm run postlint --ignore-scripts \${{ inputs.flags }} .github/actions/setup/action.yml @@ -3504,15 +3512,13 @@ inputs: default: latest cache: description: whether to cache npm install or not - type: boolean default: false shell: description: shell to run on default: bash deps: description: whether to run the deps step - type: boolean - default: true + default: 'true' deps-command: description: command to run for the dependencies step default: install --ignore-scripts --no-audit --no-fund @@ -3532,12 +3538,12 @@ runs: uses: actions/setup-node@v3 with: node-version: \${{ inputs.node-version }} - cache: \${{ (inputs.cache && 'npm') || null }} + cache: \${{ (inputs.cache == 'true' && 'npm') || '' }} - name: Check Node Version if: inputs.npm-version id: node-version - shell: \${{ inputs.shell }} + shell: bash run: | NODE_VERSION=$(node --version) echo $NODE_VERSION @@ -3575,14 +3581,14 @@ runs: run: npm -v - name: Setup Dependencies - if: inputs.deps + if: inputs.deps == 'true' uses: ./.github/actions/deps with: command: \${{ inputs.deps-command }} flags: \${{ inputs.deps-flags }} - name: Add Problem Matcher - shell: \${{ inputs.shell }} + shell: bash run: | [[ -f ./.github/matchers/tap.json ]] && echo "::add-matcher::.github/matchers/tap.json" @@ -3863,7 +3869,7 @@ jobs: uses: ./.github/actions/changed-workspaces with: token: \${{ secrets.GITHUB_TOKEN }} - all: \${{ inputs.all }} + files: \${{ (inputs.all && '--all') || '' }} - name: Lint uses: ./.github/actions/lint @@ -3909,6 +3915,7 @@ jobs: steps: - name: Continue Matrix Run id: continue-matrix + shell: bash run: | if [[ "\${{ matrix.node-version }}" == "14.17.0" || "\${{ inputs.all }}" == "true" ]]; then echo "result=true" >> $GITHUB_OUTPUT @@ -3944,9 +3951,8 @@ jobs: continue-on-error: \${{ !!steps.check.outputs.check-id }} uses: ./.github/actions/changed-workspaces with: - shell: \${{ matrix.platform.shell }} token: \${{ secrets.GITHUB_TOKEN }} - all: \${{ inputs.all }} + files: \${{ (inputs.all && '--all') || '' }} - name: Test if: steps.continue-matrix.outputs.result @@ -4537,6 +4543,9 @@ package.json }, "name": "testpkg", "version": "1.0.0", + "devDependencies": { + "@npmcli/template-oss": "{{VERSION}}" + }, "workspaces": [ "workspaces/a", "workspaces/b" @@ -4633,6 +4642,9 @@ workspaces/a/package.json { "name": "a", "version": "1.0.0", + "devDependencies": { + "@npmcli/template-oss": "{{VERSION}}" + }, "scripts": { "lint": "eslint /"**/*.js/"", "postlint": "template-oss-check", @@ -4711,6 +4723,9 @@ workspaces/b/package.json { "name": "b", "version": "1.0.0", + "devDependencies": { + "@npmcli/template-oss": "{{VERSION}}" + }, "scripts": { "lint": "eslint /"**/*.js/"", "postlint": "template-oss-check", @@ -4760,6 +4775,9 @@ package.json }, "name": "testpkg", "version": "1.0.0", + "devDependencies": { + "@npmcli/template-oss": "{{VERSION}}" + }, "workspaces": [ "workspaces/a" ] @@ -4773,6 +4791,9 @@ workspaces/a/package.json "version": "{{VERSION}}" }, "name": "a", - "version": "1.0.0" + "version": "1.0.0", + "devDependencies": { + "@npmcli/template-oss": "{{VERSION}}" + } } ` diff --git a/tap-snapshots/test/check/diff-snapshots.js.test.cjs b/tap-snapshots/test/check/diff-snapshots.js.test.cjs index 9608bb2c..aa83c67f 100644 --- a/tap-snapshots/test/check/diff-snapshots.js.test.cjs +++ b/tap-snapshots/test/check/diff-snapshots.js.test.cjs @@ -164,14 +164,14 @@ The repo file ci.yml needs to be updated: .github/workflows/ci.yml ======================================== @@ -146,4 +146,24 @@ + - name: Get Changed Workspaces if: steps.continue-matrix.outputs.result id: workspaces continue-on-error: \${{ !!steps.check.outputs.check-id }} - uses: ./.github/actions/changed-workspaces + + uses: ./.github/actions/changed-workspaces + with: - + shell: \${{ matrix.platform.shell }} + token: \${{ secrets.GITHUB_TOKEN }} - + all: \${{ inputs.all }} + + files: \${{ (inputs.all && '--all') || '' }} + + - name: Test + if: steps.continue-matrix.outputs.result diff --git a/test/apply/dependabot.js b/test/apply/dependabot.js index fdf3b758..871301dc 100644 --- a/test/apply/dependabot.js +++ b/test/apply/dependabot.js @@ -54,66 +54,3 @@ t.test('basic', async t => { await t.test(name, t => setupDependabot(t, config, assert)) } }) - -// t.test('root', async (t) => { -// const s = await setup(t, { -// ok: true, -// package: { -// templateOSS: { -// lockfile: true, -// }, -// }, -// }) -// await s.apply() - -// const dependabot = await s.readFile(join('.github', 'dependabot.yml')) - -// t.same(await s.check(), []) -// await s.apply() -// await s.apply() -// await s.apply() -// t.same(await s.check(), []) -// }) - -// t.test('root + workspaces', async (t) => { -// const s = await setup(t, { -// ok: true, -// workspaces: { a: 'a', b: 'b', c: 'c' }, -// package: { -// templateOSS: { -// lockfile: true, -// }, -// }, -// }) -// await s.apply() - -// const dependabot = await s.readFile(join('.github', 'dependabot.yml')) - -// t.same(await s.check(), []) -// await s.apply() -// await s.apply() -// await s.apply() -// t.same(await s.check(), []) -// }) - -// t.test('workspaces only', async (t) => { -// const s = await setup(t, { -// ok: true, -// package: { -// templateOSS: { -// rootRepo: false, -// lockfile: true, -// }, -// }, -// workspaces: { a: 'a', b: 'b', c: 'c' }, -// }) -// await s.apply() - -// const dependabot = await s.readFile(join('.github', 'dependabot.yml')) - -// t.same(await s.check(), []) -// await s.apply() -// await s.apply() -// await s.apply() -// t.same(await s.check(), []) -// }) diff --git a/test/check/snapshots.js b/test/check/snapshots.js index 07fd3c38..01dd1481 100644 --- a/test/check/snapshots.js +++ b/test/check/snapshots.js @@ -6,19 +6,20 @@ t.cleanSnapshot = setup.clean t.formatSnapshot = setup.format.checks t.test('check empty dir', async (t) => { - const s = await setup(t) + const s = await setup(t, { requireSelf: false }) await t.resolveMatchSnapshot(s.check()) }) t.test('workspaces with empty dir', async (t) => { const s = await setup(t, { workspaces: { a: '@name/aaaa', b: 'bbb' }, + requireSelf: false, }) await t.resolveMatchSnapshot(s.check()) }) t.test('not ok without required', async (t) => { - const s = await setup(t) + const s = await setup(t, { requireSelf: false }) await s.apply() await t.resolveMatchSnapshot(s.check()) }) diff --git a/test/setup.js b/test/setup.js index 5010796c..7fd6fff2 100644 --- a/test/setup.js +++ b/test/setup.js @@ -8,8 +8,7 @@ const npa = require('npm-package-arg') const output = require('../lib/util/output.js') const apply = require('../lib/apply/index.js') const check = require('../lib/check/index.js') -const CONTENT = require('@npmcli/template-oss-content') -const { name: NAME, version: VERSION } = require('../package.json') +const { DEFAULT_CONTENT, NAME, VERSION } = require('../lib/util/config.js') const createPackageJson = (pkg) => ({ 'package.json': JSON.stringify(pkg, null, 2), @@ -27,21 +26,24 @@ const pkgWithName = (name, defName) => { } // minimum package.json for no errors -const okPackage = () => Object.entries(CONTENT.requiredPackages) - .reduce((acc, [location, deps]) => { - acc[location] = Object.fromEntries(deps.map((name) => { - const arg = npa(name) - return [arg.name, arg.fetchSpec === 'latest' ? '*' : arg.fetchSpec] - })) - return acc - }, { - tap: { - 'nyc-arg': [ - '--exclude', - 'tap-snapshots/**', - ], - }, - }) +const okPackage = () => { + const pkg = Object.entries(DEFAULT_CONTENT.requiredPackages) + .reduce((acc, [location, deps]) => { + acc[location] = Object.fromEntries(deps.map((name) => { + const arg = npa(name) + return [arg.name, arg.fetchSpec === 'latest' ? '*' : arg.fetchSpec] + })) + return acc + }, { + tap: { + 'nyc-arg': [ + '--exclude', + 'tap-snapshots/**', + ], + }, + }) + return pkg +} const setupRoot = async (root) => { const rootPath = (...p) => join(root, ...p) @@ -102,13 +104,18 @@ const setup = async (t, { workspaces = {}, testdir = {}, ok, + requireSelf = true, } = {}) => { - const wsLookup = {} - const pkg = merge( - pkgWithName(package, 'testpkg'), - ok ? okPackage() : {} + const mergePkg = (name, defName) => merge( + {}, + pkgWithName(name, defName), + ok ? okPackage() : {}, + requireSelf || ok ? { devDependencies: { [NAME]: VERSION } } : {} ) + const wsLookup = {} + const pkg = mergePkg(package, 'testpkg') + // convenience for passing in workspaces as an object // and getting those converted to a proper workspaces array // and adding the workspaces to the testdir @@ -119,10 +126,7 @@ const setup = async (t, { merge(testdir, { [wsDir]: {} }) for (const [wsBase, wsPkgName] of wsEntries) { - const wsPkg = merge( - pkgWithName(wsPkgName, wsBase), - ok ? okPackage() : {} - ) + const wsPkg = mergePkg(wsPkgName, wsBase) const wsPath = posix.join(wsDir, wsBase) // obj to lookup workspaces by path in tests wsLookup[wsBase] = wsPath @@ -169,6 +173,7 @@ const cleanSnapshot = (str) => str .replace(/\\+/g, '/') .replace(/\r\n/g, '\n') .replace(new RegExp(`("version": "|${esc(NAME)}@)${esc(VERSION)}`, 'g'), '$1{{VERSION}}') + .replace(new RegExp(`("${NAME}": ")${VERSION.replace(/\./g, '\\.')}(")`, 'g'), '$1{{VERSION}}$2') const formatSnapshots = { checks: (arr) => output(arr).trim(), readdir: (arr) => arr.sort(localeCompare).join('\n').trim(), @@ -181,11 +186,10 @@ const formatSnapshots = { module.exports = setup module.exports.git = setupGit -module.exports.content = CONTENT +module.exports.content = DEFAULT_CONTENT module.exports.pkgVersion = VERSION module.exports.clean = cleanSnapshot module.exports.format = formatSnapshots -module.exports.okPackage = okPackage module.exports.fixture = (f) => fs.readFile(resolve(__dirname, 'fixtures', f), 'utf-8') module.exports.log = (t, f = () => true) => { const cb = (...args) => f(...args) && console.error(...args) diff --git a/test/util/has-package.js b/test/util/has-package.js index 08921091..a8ca69a6 100644 --- a/test/util/has-package.js +++ b/test/util/has-package.js @@ -2,7 +2,7 @@ const fs = require('fs/promises') const t = require('tap') const path = require('path') const hasPackage = require('../../lib/util/has-package.js') -const { name: NAME } = require('../../package.json') +const { name: NAME } = require('../../lib/util/config.js') const checks = [ [{ a: '1.2.3' }, 'a@1.2.3', true], diff --git a/workspaces/config/lib/index.js b/workspaces/config/lib/index.js index 178162f2..cd9e9187 100644 --- a/workspaces/config/lib/index.js +++ b/workspaces/config/lib/index.js @@ -5,19 +5,21 @@ const parseCIVersions = require('./parse-ci-versions.js') const getGitUrl = require('./get-git-url.js') const gitignore = require('./gitignore.js') const withArrays = require('./merge-with-arrays.js') -const { FILE_KEYS, parseConfig: parseFiles, getAddedFiles } = require('@npmcli/template-oss-files') +const { parseConfigFiles, getAddedFiles } = require('@npmcli/template-oss-files') -const CONFIG_KEY = 'templateOSS' -const getPkgConfig = (pkg) => pkg[CONFIG_KEY] || {} - -const { name: NAME, version: LATEST_VERSION } = require('../../../package.json') +const FILE_KEYS = ['rootRepo', 'rootModule', 'workspaceRepo', 'workspaceModule'] const MERGE_KEYS = [...FILE_KEYS, 'defaultContent', 'content'] -const DEFAULT_CONTENT = require.resolve('@npmcli/template-oss-content') const merge = withArrays('branches', 'distPaths', 'allowPaths', 'ignorePaths') const makePosix = (v) => v.split(win32.sep).join(posix.sep) -const deglob = (v) => makePosix(v).replace(/[/*]+$/, '') +const deglob = (v) => { + let posixGlob = makePosix(v) + while (posixGlob.endsWith('/') || posixGlob.endsWith('*')) { + posixGlob = posixGlob.slice(0, -1) + } + return posixGlob +} const posixDir = (v) => `${v === '.' ? '' : deglob(v).replace(/\/$/, '')}${posix.sep}` const posixGlob = (str) => `${posixDir(str)}**` @@ -36,10 +38,10 @@ const getCmdPath = (key, { rootConfig, defaultConfig, isRoot, pkg, rootPkg }) => } } -const mergeConfigs = (...configs) => { +const mergeConfigs = (defaultContent, ...configs) => { const mergedConfig = merge(...configs.map(c => pick(c, MERGE_KEYS))) return defaults(mergedConfig, { - defaultContent: DEFAULT_CONTENT, + defaultContent, // allow all file types by default ...FILE_KEYS.reduce((acc, key) => { acc[key] = true @@ -78,7 +80,10 @@ const getFiles = (path, rawConfig) => { if (!dir) { return [] } - return [parseFiles(pick(content, FILE_KEYS), dir, pick(rawConfig, FILE_KEYS)), dir] + return [ + parseConfigFiles(pick(content, FILE_KEYS), dir, pick(rawConfig, FILE_KEYS), FILE_KEYS), + dir, + ] } const getFullConfig = async ({ @@ -90,22 +95,19 @@ const getFullConfig = async ({ rootPkg, // the root pkg (same as pkg when operating on the root) pkgs, // an array of all packages to be operated on wsPkgs, // an array of all workspaces being operated + defaultContent, // path to default content dir }) => { const isRoot = rootPkg.path === pkg.path const isWorkspace = !isRoot const isMono = !!wsPkgs.length const isRootMono = isRoot && isMono - const isLatest = pkg.config.version === LATEST_VERSION - const isDogFood = rootPkg.pkgJson.name === NAME - const isForce = process.argv.includes('--force') - // These config items are merged betweent the root and child workspaces and only come from // the package.json because they can be used to read configs from other the content directories - const mergedConfig = mergeConfigs(rootPkg.config, pkg.config) + const mergedConfig = mergeConfigs(defaultContent, rootPkg.config, pkg.config) - const defaultConfig = getConfig(DEFAULT_CONTENT) - const [defaultFiles, defaultDir] = getFiles(DEFAULT_CONTENT, mergedConfig) + const defaultConfig = getConfig(defaultContent) + const [defaultFiles, defaultDir] = getFiles(defaultContent, mergedConfig) const useDefault = mergedConfig.defaultContent && defaultConfig const rootConfig = getConfig(rootPkg.config.content, rootPkg.config) @@ -188,10 +190,6 @@ const getFullConfig = async ({ pkgFlags: isWorkspace ? `-w ${pkg.pkgJson.name}` : '', workspacePaths, workspaceGlobs: workspacePaths.map(posixGlob), - // booleans to control application of updates - isForce, - isDogFood, - isLatest, // whether to install and update npm in ci // only do this if we aren't using a custom path to bin updateNpm: !npmPath.isLocal, @@ -215,13 +213,7 @@ const getFullConfig = async ({ ? gitignore.allowDir(wsPkgs.map((p) => makePosix(relative(rootPkg.path, p.path)))) : [], ], - // needs update if we are dogfooding this repo, with force argv, or its - // behind the current version - needsUpdate: isForce || isDogFood || !isLatest, // templateoss specific values - __NAME__: NAME, - __CONFIG_KEY__: CONFIG_KEY, - __VERSION__: LATEST_VERSION, __PARTIAL_DIRS__: fileDirs, } @@ -266,4 +258,3 @@ const getFullConfig = async ({ } module.exports = getFullConfig -module.exports.getPkgConfig = getPkgConfig diff --git a/workspaces/content/lib/actions/audit.yml b/workspaces/content/lib/actions/audit.yml index 14c4f25d..7733ebe7 100644 --- a/workspaces/content/lib/actions/audit.yml +++ b/workspaces/content/lib/actions/audit.yml @@ -8,8 +8,11 @@ inputs: runs: using: composite steps: - - name: Run Audit + - name: Run Production Audit shell: $\{{ inputs.shell }} run: | {{ rootNpmPath }} audit --omit=dev + - name: Run Full Audit + shell: $\{{ inputs.shell }} + run: | {{ rootNpmPath }} audit --audit-level=none diff --git a/workspaces/content/lib/actions/changed-files.yml b/workspaces/content/lib/actions/changed-files.yml index fc326245..ae415a99 100644 --- a/workspaces/content/lib/actions/changed-files.yml +++ b/workspaces/content/lib/actions/changed-files.yml @@ -6,7 +6,7 @@ inputs: required: true outputs: - files: + names: value: $\{{ steps.files.outputs.result }} runs: diff --git a/workspaces/content/lib/actions/changed-workspaces.yml b/workspaces/content/lib/actions/changed-workspaces.yml index 40dcd75b..2b47f13d 100644 --- a/workspaces/content/lib/actions/changed-workspaces.yml +++ b/workspaces/content/lib/actions/changed-workspaces.yml @@ -3,15 +3,8 @@ name: Get Changed Workspaces inputs: token: description: GitHub token to use - shell: - description: shell to run on - default: {{ shell }} - all: - default: false - type: boolean files: - description: json stringified array of file names - type: string + description: json stringified array of file names or --all outputs: flags: @@ -22,14 +15,14 @@ runs: steps: - name: Get Changed Files uses: ./.github/actions/changed-files - if: $\{{ !inputs.all && !inputs.files }} + if: $\{{ !inputs.files }} id: files with: token: $\{{ inputs.token }} - name: Get Workspaces - shell: $\{{ inputs.shell }} + shell: bash id: workspaces run: | - flags=$({{ rootNpmPath }} exec --offline -- template-oss-changed-workspaces '$\{{ (inputs.all && '--all') || (inputs.files || steps.files.outputs.result) }}') + flags=$({{ rootNpmPath }} exec --offline -- template-oss-changed-workspaces '$\{{ inputs.files || steps.files.outputs.names }}') echo "flags=${flags}" >> $GITHUB_OUTPUT diff --git a/workspaces/content/lib/actions/lint.yml b/workspaces/content/lib/actions/lint.yml index ecac7587..d52e1842 100644 --- a/workspaces/content/lib/actions/lint.yml +++ b/workspaces/content/lib/actions/lint.yml @@ -14,4 +14,7 @@ runs: shell: $\{{ inputs.shell }} run: | {{ rootNpmPath }} run lint --ignore-scripts $\{{ inputs.flags }} + - name: Post Lint + shell: $\{{ inputs.shell }} + run: | {{ rootNpmPath }} run postlint --ignore-scripts $\{{ inputs.flags }} diff --git a/workspaces/content/lib/actions/setup.yml b/workspaces/content/lib/actions/setup.yml index ef135e1e..e5349125 100644 --- a/workspaces/content/lib/actions/setup.yml +++ b/workspaces/content/lib/actions/setup.yml @@ -10,15 +10,13 @@ inputs: default: {{#if updateNpm}}{{ npmSpec }}{{/if}} cache: description: whether to cache npm install or not - type: boolean default: {{ lockfile }} shell: description: shell to run on default: {{ shell }} deps: description: whether to run the deps step - type: boolean - default: true + default: 'true' deps-command: description: command to run for the dependencies step default: install --ignore-scripts --no-audit --no-fund @@ -38,12 +36,12 @@ runs: uses: actions/setup-node@v3 with: node-version: $\{{ inputs.node-version }} - cache: $\{{ (inputs.cache && 'npm') || null }} + cache: $\{{ (inputs.cache == 'true' && 'npm') || '' }} - name: Check Node Version if: inputs.npm-version id: node-version - shell: $\{{ inputs.shell }} + shell: bash run: | NODE_VERSION=$(node --version) echo $NODE_VERSION @@ -81,14 +79,14 @@ runs: run: {{ rootNpmPath }} -v - name: Setup Dependencies - if: inputs.deps + if: inputs.deps == 'true' uses: ./.github/actions/deps with: command: $\{{ inputs.deps-command }} flags: $\{{ inputs.deps-flags }} - name: Add Problem Matcher - shell: $\{{ inputs.shell }} + shell: bash run: | [[ -f ./.github/matchers/tap.json ]] && echo "::add-matcher::.github/matchers/tap.json" diff --git a/workspaces/content/lib/index.js b/workspaces/content/lib/index.js index 86680061..5333c84d 100644 --- a/workspaces/content/lib/index.js +++ b/workspaces/content/lib/index.js @@ -1,5 +1,3 @@ -const { name: NAME, version: LATEST_VERSION } = require('../../../package.json') - const isPublic = (p) => p.config.isPublic const sharedRootAdd = () => ({ @@ -192,7 +190,6 @@ module.exports = { ], requiredPackages: { devDependencies: [ - `${NAME}@${LATEST_VERSION}`, '@npmcli/eslint-config', 'tap', ], diff --git a/workspaces/content/lib/workflows/ci.yml b/workspaces/content/lib/workflows/ci.yml index f92fda17..155a1867 100644 --- a/workspaces/content/lib/workflows/ci.yml +++ b/workspaces/content/lib/workflows/ci.yml @@ -60,7 +60,7 @@ jobs: uses: ./.github/actions/changed-workspaces with: token: $\{{ secrets.GITHUB_TOKEN }} - all: $\{{ inputs.all }} + files: $\{{ (inputs.all && '--all') || '' }} - name: Lint uses: ./.github/actions/lint @@ -83,6 +83,7 @@ jobs: steps: - name: Continue Matrix Run id: continue-matrix + shell: bash run: | if [[ "$\{{ matrix.node-version }}" == "{{ first ciVersions }}" || "$\{{ inputs.all }}" == "true" ]]; then echo "result=true" >> $GITHUB_OUTPUT @@ -118,9 +119,8 @@ jobs: continue-on-error: $\{{ !!steps.check.outputs.check-id }} uses: ./.github/actions/changed-workspaces with: - shell: $\{{ matrix.platform.shell }} token: $\{{ secrets.GITHUB_TOKEN }} - all: $\{{ inputs.all }} + files: $\{{ (inputs.all && '--all') || '' }} - name: Test if: steps.continue-matrix.outputs.result diff --git a/workspaces/content/lib/workflows/post-dependabot.yml b/workspaces/content/lib/workflows/post-dependabot.yml index 5a0f311b..f272b881 100644 --- a/workspaces/content/lib/workflows/post-dependabot.yml +++ b/workspaces/content/lib/workflows/post-dependabot.yml @@ -6,8 +6,8 @@ on: jobs: - template-oss: - name: template-oss + {{ __NAME_FS__ }}: + name: "{{ __NAME__ }}" permissions: contents: write {{#> partialsJobIf}}&& github.actor == 'dependabot[bot]'{{/ partialsJobIf}} diff --git a/workspaces/files/lib/index.js b/workspaces/files/lib/index.js index aae52b4c..f2abad91 100644 --- a/workspaces/files/lib/index.js +++ b/workspaces/files/lib/index.js @@ -7,8 +7,6 @@ const merge = require('./merge.js') const Parser = require('./parser.js') const template = require('./template.js') -const FILE_KEYS = ['rootRepo', 'rootModule', 'workspaceRepo', 'workspaceModule'] - const globify = pattern => pattern.split('\\').join('/') const fileEntries = (dir, files, options) => Object.entries(files) @@ -72,7 +70,7 @@ const parseEach = async (dir, files, options, fn) => { return res.filter(Boolean) } -const parseConfig = (files, dir, overrides) => { +const parseConfigFiles = (files, dir, overrides, configKeys) => { const normalizeFiles = (v) => deepMapValues(v, (value, key) => { if (key === 'rm' && Array.isArray(value)) { return value.reduce((acc, k) => { @@ -84,14 +82,14 @@ const parseConfig = (files, dir, overrides) => { const file = join(dir, value) return key === 'file' ? file : { file } } - if (value === true && FILE_KEYS.includes(key)) { + if (value === true && configKeys.includes(key)) { return {} } return value }) const merged = merge(normalizeFiles(files), normalizeFiles(overrides)) - const withDefaults = defaultsDeep(merged, FILE_KEYS.reduce((acc, k) => { + const withDefaults = defaultsDeep(merged, configKeys.reduce((acc, k) => { acc[k] = { add: {}, rm: {} } return acc }, {})) @@ -104,7 +102,6 @@ const getAddedFiles = (files) => files ? Object.keys(files.add || {}) : [] module.exports = { rmEach, parseEach, - FILE_KEYS, - parseConfig, + parseConfigFiles, getAddedFiles, }