Skip to content

Commit

Permalink
fix: change publish workflow to pull_request
Browse files Browse the repository at this point in the history
This also adds a check to fail if CLI content is updated in this repo
instead of `npm/cli`
  • Loading branch information
lukekarrys committed Jan 9, 2023
1 parent b0e5000 commit 2c54fe2
Show file tree
Hide file tree
Showing 11 changed files with 157 additions and 60 deletions.
53 changes: 53 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,59 @@ jobs:
- name: Test
run: npm test --ignore-scripts

test-cli-content:
name: Test CLI Content - ${{ matrix.platform.name }} - ${{ matrix.node-version }}
if: github.repository_owner == 'npm'
strategy:
fail-fast: false
matrix:
platform:
- name: Linux
os: ubuntu-latest
shell: bash
node-version:
- 18.x
runs-on: ${{ matrix.platform.os }}
defaults:
run:
shell: ${{ matrix.platform.shell }}
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Git User
run: |
git config --global user.email "[email protected]"
git config --global user.name "npm CLI robot"
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
cache: npm
- name: Update Windows npm
# node 12 and 14 ship with npm@6, which is known to fail when updating itself in windows
if: matrix.platform.os == 'windows-latest' && (startsWith(matrix.node-version, '12.') || startsWith(matrix.node-version, '14.'))
run: |
curl -sO https://registry.npmjs.org/npm/-/npm-7.5.4.tgz
tar xf npm-7.5.4.tgz
cd package
node lib/npm.js install --no-fund --no-audit -g ..\npm-7.5.4.tgz
cd ..
rmdir /s /q package
- name: Install npm@7
if: startsWith(matrix.node-version, '10.')
run: npm i --prefer-online --no-fund --no-audit -g npm@7
- name: Install npm@latest
if: ${{ !startsWith(matrix.node-version, '10.') }}
run: npm i --prefer-online --no-fund --no-audit -g npm@latest
- name: npm Version
run: npm -v
- name: Install Dependencies
run: npm i --no-audit --no-fund
- name: Check CLI Documentation
run: npm run build -w cli -- --check-only
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

licenses:
name: REUSE Compliance Check
runs-on: ubuntu-latest
Expand Down
21 changes: 8 additions & 13 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:
push:
branches:
- main
pull_request_target:
pull_request:
workflow_dispatch:
workflow_call:

Expand All @@ -23,19 +23,12 @@ jobs:
run:
shell: bash
steps:
- name: Checkout PR
if: ${{ github.event_name == 'pull_request_target' }}
uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.ref }}
repository: ${{ github.event.pull_request.head.repo.full_name }}
- name: Checkout
if: ${{ github.event_name != 'pull_request_target' }}
uses: actions/checkout@v3
with:
ref: main
- name: Setup Pages
uses: actions/configure-pages@v1
- name: Setup Git User
run: |
git config --global user.email "[email protected]"
git config --global user.name "npm CLI robot"
- name: Setup Node
uses: actions/setup-node@v3
with:
Expand All @@ -47,6 +40,8 @@ jobs:
run: npm -v
- name: Install Dependencies
run: npm i --no-audit --no-fund
- name: Setup Pages
uses: actions/configure-pages@v1
- name: Build documentation
run: npm run build
env:
Expand All @@ -70,4 +65,4 @@ jobs:
id: deployment
uses: actions/deploy-pages@v1
with:
preview: ${{ github.event_name == 'pull_request_target' }}
preview: ${{ github.event_name == 'pull_request' }}
2 changes: 2 additions & 0 deletions .github/workflows/update-cli.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ jobs:
- name: Build documentation
run: npm run build -w cli
env:
# token is used to get files from `npm/cli` that
# are not present in the published tarball
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Check for changes
id: status
Expand Down
46 changes: 34 additions & 12 deletions cli/bin/build.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,43 @@
const { resolve } = require('path')
const { resolve, relative, join } = require('path')
const { spawnSync } = require('child_process')
const build = require('../lib/build.js')
const { nwo } = require('../lib/gh')

// check only build with the current versions instead of checking the registry
// and also fails if any changes are detected. this is used in CI to make sure
// edits to the CLI content are made in the CLI repo
const checkOnly = process.argv.includes('--check-only')

const ROOT = resolve(__dirname, '../..')
const contentPath = join(ROOT, 'content/cli')
const navPath = join(ROOT, 'src/theme/nav.yml')

const checkContent = () => {
const status = spawnSync('git', ['status', '--porcelain', contentPath], { encoding: 'utf-8' })
if (status.stdout) {
const msg = [
`The following untracked changes to ${relative(process.cwd(), contentPath)} were found:`,
status.stdout,
`These files are generated and changes might need to be made in the ${nwo} repository.`,
]
throw new Error(msg.join('\n'))
}
}

build({
releases: require('../releases.json'),
loglevel: process.argv.includes('--debug') || process.env.CI ? 'verbose' : 'info',
prerelease: false,
contentPath: resolve(__dirname, '..', '..', 'content', 'cli'),
releasesPath: resolve(__dirname, '..', 'releases.json'),
navPath: resolve(
__dirname,
'..',
'..',
'src',
'theme',
'nav.yml'
),
useCurrent: checkOnly,
contentPath,
navPath,
})
.then(() => console.log('DONE'))
.then(() => {
if (checkOnly) {
checkContent()
}
return console.log('DONE')
})
.catch((e) => {
console.error(e)
process.exit(1)
Expand Down
40 changes: 30 additions & 10 deletions cli/lib/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,25 @@ const updateNav = async (updates, { nav, path }) => {
return fs.writeFile(path, nav.toString(), 'utf-8')
}

const getCurrentVersions = (nav) => {
// the only place the current versions are stored is in the nav
const currentSections = nav.find(s => s.url === `/${DOCS_PATH}`).variants

const currentVersions = currentSections.map((v) => {
const version = v.title?.match(/^Version\s(.*?)\s/)[1]
return version
}).sort(semver.compare)

return {
versions: currentVersions,
latest: currentVersions[currentVersions.length - 1],
}
}

const main = async ({
loglevel,
releasesPath,
releases: rawReleases,
useCurrent,
navPath,
contentPath,
prerelease,
Expand All @@ -50,12 +66,18 @@ const main = async ({
log.on(loglevel)
}

const pack = await pacote.packument('npm', { preferOnline: true }).then(p => ({
versions: Object.keys(p.versions),
latest: p['dist-tags'].latest,
}))
const baseNav = await fs.readFile(navPath, 'utf-8')
const navData = yaml.parse(baseNav)
const navDoc = yaml.parseDocument(baseNav)

const pack = useCurrent
? getCurrentVersions(navData)
: await pacote.packument('npm', { preferOnline: true }).then(p => ({
versions: Object.keys(p.versions),
latest: p['dist-tags'].latest,
}))

const releaseVersions = require(releasesPath).map(release => {
const releaseVersions = rawReleases.map(release => {
const major = Number(release.id.replace(/^v/, ''))
const range = `>=${major}.0.0-a <${major + 1}.0.0` // include all prereleases
const version = semver.parse(semver.maxSatisfying(pack.versions, range))
Expand Down Expand Up @@ -86,15 +108,13 @@ const main = async ({
}
})

const baseNav = await fs.readFile(navPath, 'utf-8')

const updates = await Promise.all(
releases.map((r) =>
extractRelease(r, { contentPath, baseNav: yaml.parse(baseNav), prerelease })
extractRelease(r, { contentPath, baseNav: navData, prerelease })
)
).then((r) => r.filter(Boolean))

await updateNav(updates, { nav: yaml.parseDocument(baseNav), path: navPath })
await updateNav(updates, { nav: navDoc, path: navPath })
}

module.exports = main
11 changes: 4 additions & 7 deletions cli/lib/extract.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,6 @@ const unpackRelease = async (
log.info(release.id, release)

const cwd = join(contentPath, release.id)
await fs
.rm(cwd, { force: true, recursive: true })
.then(() => fs.mkdir(cwd, { recursive: true }))

const builtPath = join('docs', 'content')
const srcPath = join('docs', 'lib', 'content')
Expand All @@ -119,10 +116,10 @@ const unpackRelease = async (
?? await gh.pathExists(release.branch, join('docs', 'nav.yml')),
})

// If we are using the release's GitHub ref, then we fetch
// the tree of the doc directory's sha which has all the docs
// we need in it. Note that this requires the docs to all be
// built in source, which is true for v6 but not for v9 and later.
await fs
.rm(cwd, { force: true, recursive: true })
.then(() => fs.mkdir(cwd, { recursive: true }))

const files = await unpackTarball({
release,
cwd,
Expand Down
4 changes: 4 additions & 0 deletions cli/lib/gh.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
const { Octokit } = require('@octokit/rest')
const { posix, sep } = require('path')

if (!process.env.GITHUB_TOKEN) {
throw new Error('GITHUB_TOKEN env var is required to build CLI docs')
}

const octokit = new Octokit({ auth: process.env.GITHUB_TOKEN })
const owner = 'npm'
const repo = 'cli'
Expand Down
2 changes: 2 additions & 0 deletions cli/scripts/template-oss/update-cli.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ jobs:
- name: Build documentation
run: npm run build -w cli
env:
# token is used to get files from `npm/cli` that
# are not present in the published tarball
GITHUB_TOKEN: $\{{ secrets.GITHUB_TOKEN }}
- name: Check for changes
id: status
Expand Down
12 changes: 10 additions & 2 deletions cli/test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ const mockBuild = async ({ releases, packument = {}, testdir: testdirOpts }) =>
const nav = yaml.parse(rawNav)

const testdir = t.testdir({
'releases.json': JSON.stringify(releases),
'nav.yml': rawNav,
content: {},
...testdirOpts,
Expand Down Expand Up @@ -102,8 +101,8 @@ const mockBuild = async ({ releases, packument = {}, testdir: testdirOpts }) =>
return {
testdir,
build: (opts) => build({
releases,
contentPath: join(testdir, 'content'),
releasesPath: join(testdir, 'releases.json'),
navPath: join(testdir, 'nav.yml'),
...opts,
}),
Expand Down Expand Up @@ -158,6 +157,15 @@ t.test('earlier release is latest', async (t) => {
await build()
})

t.test('can skip fetching latest', async (t) => {
const releases = getReleases()
const { build } = await mockBuild({
releases,
})

await build({ useCurrent: true })
})

t.test('add variant to nav', async (t) => {
const releases = getReleases()
const { build } = await mockBuild({
Expand Down
7 changes: 7 additions & 0 deletions scripts/template-oss/ci.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
{{> ci }}

test-cli-content:
{{> jobMatrix jobName="Test CLI Content" }}
- name: Check CLI Documentation
run: npm run build -w cli -- --check-only
env:
GITHUB_TOKEN: $\{{ secrets.GITHUB_TOKEN }}

licenses:
name: REUSE Compliance Check
runs-on: ubuntu-latest
Expand Down
19 changes: 3 additions & 16 deletions scripts/template-oss/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ on:
push:
branches:
- {{ defaultBranch }}
pull_request_target:
pull_request:
workflow_dispatch:
workflow_call:

Expand All @@ -13,22 +13,9 @@ jobs:
permissions:
contents: read
pages: read
{{> job jobName="Build and Upload" jobSkipSetup=true }}
- name: Checkout PR
if: $\{{ github.event_name == 'pull_request_target' }}
uses: actions/checkout@v3
with:
ref: $\{{ github.event.pull_request.head.ref }}
repository: $\{{ github.event.pull_request.head.repo.full_name }}
- name: Checkout
if: $\{{ github.event_name != 'pull_request_target' }}
uses: actions/checkout@v3
with:
ref: {{ defaultBranch }}
{{> job jobName="Build and Upload" }}
- name: Setup Pages
uses: actions/configure-pages@v1
{{> stepNode }}
{{> stepDeps }}
- name: Build documentation
run: npm run build
env:
Expand All @@ -52,4 +39,4 @@ jobs:
id: deployment
uses: actions/deploy-pages@v1
with:
preview: $\{{ github.event_name == 'pull_request_target' }}
preview: $\{{ github.event_name == 'pull_request' }}

0 comments on commit 2c54fe2

Please sign in to comment.