diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000000000..39608e9cb0f9c --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,121 @@ +name: Release - cli + +on: + workflow_dispatch: + pull_request: + schedule: + # 08:00am UTC everyday: https://crontab.guru/#0_8_*_*_* + # https://dateful.com/convert/utc?t=8am + - cron: "0 8 * * *" + +jobs: + lint-all: + if: | + github.event_name == 'schedule' || + github.event_name == 'workflow_dispatch' || + startsWith(github.head_ref, 'release/') + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Use Node.js 16.x + uses: actions/setup-node@v3 + with: + node-version: 16.x + cache: npm + - run: node bin/npm-cli.js run resetdeps + - run: node bin/npm-cli.js run lint-all + + smoke-publish: + if: | + github.event_name == 'schedule' || + github.event_name == 'workflow_dispatch' || + startsWith(github.head_ref, 'release/') + strategy: + fail-fast: false + matrix: + node-version: + - 12.13.0 + - 12.x + - 14.15.0 + - 14.x + - 16.0.0 + - 16.x + platform: + - os: ubuntu-latest + shell: bash + - os: macos-latest + shell: bash + - os: windows-latest + shell: cmd + runs-on: ${{ matrix.platform.os }} + defaults: + run: + shell: ${{ matrix.platform.shell }} + steps: + - uses: actions/checkout@v3 + - name: Use Node.js 16.x + uses: actions/setup-node@v3 + with: + node-version: 16.x + cache: npm + - name: Pack + run: | + node bin/npm-cli.js run resetdeps + git clean -fd + node bin/npm-cli.js ls --production + node bin/npm-cli.js link -f --ignore-scripts + node bin/npm-cli.js prune --production --no-save --no-audit --no-fund + node bin/npm-cli.js pack + - if: matrix.platform.os == 'windows-latest' + run: for %%i in (*.tgz) DO tar xf %%i + - if: matrix.platform.os != 'windows-latest' + run: tar xf npm-*.tgz + - name: Run smoke tests + env: + SMOKE_TEST_NPM_PACKAGE: package + run: | + node bin/npm-cli.js run resetdeps + node bin/npm-cli.js run smoke-tests + - name: git status + if: matrix.platform.os != 'windows-latest' + run: node scripts/git-dirty.js + + test-all: + if: | + github.event_name == 'schedule' || + github.event_name == 'workflow_dispatch' || + startsWith(github.head_ref, 'release/') + strategy: + fail-fast: false + matrix: + node-version: + - 12.13.0 + - 12.x + - 14.15.0 + - 14.x + - 16.0.0 + - 16.x + platform: + - os: ubuntu-latest + shell: bash + - os: macos-latest + shell: bash + - os: windows-latest + shell: cmd + runs-on: ${{ matrix.platform.os }} + defaults: + run: + shell: ${{ matrix.platform.shell }} + steps: + - uses: actions/checkout@v3 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + cache: npm + - run: node bin/npm-cli.js run resetdeps + - run: node bin/npm-cli.js link -f --ignore-scripts + - run: node bin/npm-cli.js run test-all --ignore-scripts + - name: git status + if: matrix.platform.os != 'windows-latest' + run: node scripts/git-dirty.js diff --git a/Makefile b/Makefile index f863dcdc87fc5..cf225790dc4b4 100644 --- a/Makefile +++ b/Makefile @@ -78,7 +78,7 @@ docs/content/commands/npm-%.md: docs/bin/config-doc-command.js lib/commands/%.js freshdocs: touch lib/utils/config/definitions.js - touch "docs/bin/*.js" + touch docs/bin/*.js make docs test: deps @@ -100,11 +100,10 @@ link: uninstall node bin/npm-cli.js link -f --ignore-scripts prune: deps - node bin/npm-cli.js prune --production --no-save --no-audit - @[[ "$(shell git status -s)" != "" ]] && echo "ERR: found unpruned files" && exit 1 || echo "git status is clean" + node bin/npm-cli.js prune --production --no-save --no-audit --no-fund + node scripts/git-dirty.js publish: gitclean ls-ok link test smoke-tests docs prune - @git push origin :v$(shell node bin/npm-cli.js --no-timing -v) 2>&1 || true git push origin $(BRANCH) &&\ git push origin --tags &&\ node bin/npm-cli.js publish --tag=$(PUBLISHTAG) diff --git a/scripts/git-dirty.js b/scripts/git-dirty.js index 484a4d23e7be2..5730ed9006681 100644 --- a/scripts/git-dirty.js +++ b/scripts/git-dirty.js @@ -1,6 +1,6 @@ #!/usr/bin/env node const { spawnSync } = require('child_process') -const changes = spawnSync('git', ['status', '--porcelain', '-uno']) +const changes = spawnSync('git', ['status', '--porcelain', '-uall']) const stdout = changes.stdout.toString('utf8') const stderr = changes.stderr.toString('utf8') const { status, signal } = changes diff --git a/smoke-tests/index.js b/smoke-tests/index.js index 464187da0e269..1cda932ecffc8 100644 --- a/smoke-tests/index.js +++ b/smoke-tests/index.js @@ -5,17 +5,24 @@ const { join, resolve } = require('path') const t = require('tap') const rimraf = promisify(require('rimraf')) +const cwd = process.cwd() +const npmDir = resolve(__dirname, '..', process.env.SMOKE_TEST_NPM_PACKAGE || '') + const normalizePath = path => path.replace(/[A-Z]:/, '').replace(/\\/g, '/') -const cwd = normalizePath(process.cwd()) + t.cleanSnapshot = s => s - .split(cwd) + .split(normalizePath(npmDir)) + .join('{CWD}') + .split(normalizePath(cwd)) .join('{CWD}') .split(registry) .join('https://registry.npmjs.org/') .split(normalizePath(process.execPath)) .join('node') - .split(process.cwd()) + .split(npmDir) + .join('{CWD}') + .split(cwd) .join('{CWD}') .replace(/\\+/g, '/') .replace(/\r\n/g, '\n') @@ -37,7 +44,7 @@ const path = t.testdir({ }) const localPrefix = resolve(path, 'project') const userconfigLocation = resolve(path, '.npmrc') -const npmLocation = resolve(__dirname, '../bin/npm-cli.js') +const npmLocation = join(npmDir, 'bin', 'npm-cli.js') const cacheLocation = resolve(path, 'cache') const binLocation = resolve(path, 'bin') const env = { @@ -55,7 +62,7 @@ const npmOpts = [ const npmBin = `"${process.execPath}" "${npmLocation}" ${npmOpts}` const exec = async cmd => { const res = await execAsync(cmd, { cwd: localPrefix, env }) - if (res.stderr) { + if (res.stderr && process.env.CI) { console.error(res.stderr) } return String(res.stdout)