Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: npm/template-oss
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 124406e9cad0e54b053e95ea15f260dabb85be10
Choose a base ref
...
head repository: npm/template-oss
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 844092742836cd09d9ac50bf5e8e1b2425b50711
Choose a head ref

Commits on Apr 22, 2022

  1. Copy the full SHA
    9bf3126 View commit details
  2. Copy the full SHA
    eb55928 View commit details
  3. chore(main): release 3.4.2 (#140)

    Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
    github-actions[bot] authored Apr 22, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    53cb445 View commit details

Commits on May 3, 2022

  1. fix: add 'use strict' to .eslintrc.js (#141)

    cacache wants that rule to replace a test and this file fails linting hehe
    wraithgar authored May 3, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    6486967 View commit details
  2. chore(main): release 3.4.3 (#142)

    Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
    github-actions[bot] authored May 3, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    190ecb1 View commit details

Commits on May 10, 2022

  1. 1

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    f802204 View commit details

Commits on May 11, 2022

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    ad8c6fc View commit details
  2. chore(main): release 3.5.0 (#148)

    Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
    github-actions[bot] authored May 11, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    755a300 View commit details

Commits on Aug 15, 2022

  1. fix: compare to \n instead of os.EOL (#157)

    * fix: compare to \n instead of os.EOL
    
    os.EOL is \r\n in win32, which means this check is pretty much guaranteed to fail in windows
    
    * chore: lint
    nlf authored Aug 15, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    5517e9e View commit details

Commits on Aug 16, 2022

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    8176e44 View commit details
  2. fix: pin yaml to 2.0.0-11 (#161)

    nlf authored Aug 16, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    e095275 View commit details
  3. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    4dde648 View commit details

Commits on Aug 22, 2022

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    6f571eb View commit details

Commits on Aug 23, 2022

  1. chore(main): release 3.6.0 (#158)

    Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
    github-actions[bot] authored Aug 23, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    fc95e6e View commit details

Commits on Aug 24, 2022

  1. Verified

    This commit was signed with the committer’s verified signature. The key has expired.
    lukekarrys Luke Karrys
    Copy the full SHA
    e5d3d0e View commit details

Commits on Aug 25, 2022

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    95118ec View commit details
  2. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    0f2a89f View commit details
  3. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    09d955f View commit details
  4. chore(main): release 3.7.0 (#169)

    Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
    github-actions[bot] authored Aug 25, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    b37de29 View commit details
  5. Copy the full SHA
    678cb5a View commit details
  6. Copy the full SHA
    ce977c4 View commit details
  7. chore(main): release 3.7.1

    github-actions[bot] authored and lukekarrys committed Aug 25, 2022
    Copy the full SHA
    8e4e66d View commit details

Commits on Aug 31, 2022

  1. feat: use custom release please script (#174)

    * feat: use custom release please script
    
    * fix: install commitlint deps to package.json
    
    * fix: add breaking changes to changelog notes
    
    * chore: add tap timeout
    
    * fix: allow git installs for required packages
    
    * fix: use actions/checkout for pull requests and make setup deps partial
    
    * fix: pass token to release please
    
    * fix: check out headRefName from release please PR
    
    * fix: allow release please to pass in branch name for testing
    
    * fix: add node-workspace plugin
    
    * fix: branch name typo
    
    * feat: exclude other package commits from root
    
    * feat: call release-test workflow after updating release PR
    
    * fix: checkout head ref for dependabot
    
    * feat: add change default versioning strategy
    
    * feat: rewrite workspace deps
    
    * fix: use release please fork
    
    * fix: only write release test file if necessary
    
    * fix: set release please title patterns
    lukekarrys authored Aug 31, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    7562777 View commit details
  2. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    0f44075 View commit details
  3. chore: release 3.8.0 (#176)

    Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
    github-actions[bot] authored Aug 31, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    e851661 View commit details

Commits on Sep 1, 2022

  1. fix: update a few release nits after trying it on the cli (#179)

    - Correctly link workspace dep changelog entry to release even when
      release component is different than the package name
    - Update changelog entry also when rewriting workspaces deps
    - Clone repo during release process with `fetch-depth: 0` so we can have
      full commit history to build `AUTHORS` files
    - Removes `preversion`, `postversion`, and `prepublishOnly` scripts now
      that all tagging happens via `release-please`
    - Correctly version root when going from prerelease -> release
    
    Closes #178
    lukekarrys authored Sep 1, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    70782b3 View commit details
  2. chore: release 3.8.1 (#181)

    Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
    github-actions[bot] authored Sep 1, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    ae75f91 View commit details

Commits on Sep 8, 2022

  1. feat: update engines to ^14.17.0 || ^16.13.0 || >=18.0.0 (#184)

    BREAKING CHANGE: this updates this package and the templated engines for
    node to `^14.17.0 || ^16.13.0 || >=18.0.0`
    lukekarrys authored Sep 8, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    a72774a View commit details
  2. deps: update yaml requirement from 2.0.0-11 to 2.1.1 (#163)

    Updates the requirements on [yaml](https://github.com/eemeli/yaml) to permit the latest version.
    - [Release notes](https://github.com/eemeli/yaml/releases)
    - [Commits](eemeli/yaml@v2.0.0-11...v2.1.1)
    
    ---
    updated-dependencies:
    - dependency-name: yaml
      dependency-type: direct:production
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    dependabot[bot] authored Sep 8, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    8e4785d View commit details
  3. chore: release 4.0.0 (#185)

    Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
    github-actions[bot] authored Sep 8, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    d281908 View commit details

Commits on Sep 13, 2022

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    352d332 View commit details
  2. fix: use conventional commits from release-please for changelog (#183)

    `release-please` already fetches the commits and parses them into
    conventional commit objects, so we are able to reuse most of that
    instead of fetching it from GitHub again. This also adds tests for the
    changelog output.
    
    This also removes the workspace-deps plugin in favor of extending the
    builtin node-workspace plugin. This fixes the issue of workspaces
    sometimes not getting the correct tag name and changelog title if they
    were only bumped as part of a workspace dep.
    lukekarrys authored Sep 13, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    b58d86a View commit details
  3. chore: release 4.1.0 (#188)

    Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
    github-actions[bot] authored Sep 13, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    f9f0964 View commit details
  4. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    78a05fe View commit details
  5. chore: release 4.1.1 (#191)

    Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
    github-actions[bot] authored Sep 13, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    c0f6c06 View commit details

Commits on Sep 14, 2022

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    6bc355a View commit details
  2. chore: release 4.1.2 (#193)

    Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
    github-actions[bot] authored Sep 14, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    ca5c14e View commit details

Commits on Sep 15, 2022

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    423450f View commit details
  2. feat: add content config option to allow a module to set own content

    This also removes a lot of the redundant snapshot tests in favor of
    testing the actual files written.
    
    This also adds a few other features to allow `npm/cli` to use this in
    the root workspace:
    
    - set `npm` and `npx` paths in workflows via config
    - dependabot now works with workspaces
    - templated files now include more partials which can be overwritten
      with `content` directory config
    - only file config options are merged between root and workspaces. this
      allows for the root to set config which will only apply to itself
    - workspace paths are ignored from linting and testing in the root
    lukekarrys committed Sep 15, 2022
    Copy the full SHA
    849cecc View commit details
  3. fix: dont run workflows outside of npm org (#194)

    This adds a `if: github.repository_owner == 'npm'` to each workflow so
    they don't run outside of the npm organization by default.
    
    Closes #182
    lukekarrys committed Sep 15, 2022
    Copy the full SHA
    ffa2c08 View commit details
  4. chore: release 4.2.0

    github-actions[bot] authored and lukekarrys committed Sep 15, 2022
    Copy the full SHA
    f3bb589 View commit details

Commits on Sep 16, 2022

  1. Copy the full SHA
    e43ee70 View commit details

Commits on Sep 18, 2022

  1. Copy the full SHA
    caf393c View commit details
  2. Copy the full SHA
    5b65537 View commit details

Commits on Sep 19, 2022

  1. Verified

    This commit was signed with the committer’s verified signature. The key has expired.
    lukekarrys Luke Karrys
    Copy the full SHA
    3640080 View commit details
  2. chore: release 4.3.0

    github-actions[bot] authored and lukekarrys committed Sep 19, 2022
    Copy the full SHA
    2abf443 View commit details
  3. Copy the full SHA
    817d49e View commit details
  4. chore: release 4.3.1

    github-actions[bot] authored and lukekarrys committed Sep 19, 2022
    Copy the full SHA
    4bbb731 View commit details
  5. Copy the full SHA
    5fededb View commit details
  6. chore: release 4.3.2

    github-actions[bot] authored and lukekarrys committed Sep 19, 2022
    Copy the full SHA
    dd944ab View commit details
Showing with 10,813 additions and 2,087 deletions.
  1. +2 −0 .eslintrc.js
  2. +0 −6 .eslintrc.local.js
  3. +6 −0 .eslintrc.local.json
  4. +1 −1 .github/dependabot.yml
  5. +32 −0 .github/matchers/tap.json
  6. +0 −2 .github/settings.yml
  7. +22 −12 .github/workflows/audit.yml
  8. +210 −0 .github/workflows/ci-release.yml
  9. +107 −36 .github/workflows/ci.yml
  10. +11 −17 .github/workflows/codeql-analysis.yml
  11. +100 −22 .github/workflows/post-dependabot.yml
  12. +28 −18 .github/workflows/pull-request.yml
  13. +0 −26 .github/workflows/release-please.yml
  14. +298 −0 .github/workflows/release.yml
  15. +13 −10 .gitignore
  16. +3 −0 .release-please-manifest.json
  17. +233 −0 CHANGELOG.md
  18. +7 −0 CODE_OF_CONDUCT.md
  19. +260 −0 bin/release-manager.js
  20. +68 −0 bin/release-please.js
  21. +2 −2 lib/apply/apply-files.js
  22. +1 −1 lib/apply/index.js
  23. +5 −4 lib/check/check-apply.js
  24. +6 −6 lib/check/check-changelog.js
  25. +4 −4 lib/check/check-gitignore.js
  26. +1 −1 lib/check/index.js
  27. +202 −117 lib/config.js
  28. +5 −0 lib/content/CODE_OF_CONDUCT.md
  29. +29 −0 lib/content/_job-matrix.yml
  30. +8 −0 lib/content/_job.yml
  31. +30 −0 lib/content/_on-ci.yml
  32. +2 −0 lib/content/_step-audit.yml
  33. +54 −0 lib/content/_step-checks.yml
  34. +2 −0 lib/content/_step-deps.yml
  35. +12 −0 lib/content/_step-git.yml
  36. +4 −0 lib/content/_step-lint.yml
  37. +12 −9 lib/content/{setup-node.yml → _step-node.yml}
  38. +4 −0 lib/content/_step-test.yml
  39. +6 −0 lib/content/_steps-setup.yml
  40. +4 −8 lib/content/audit.yml
  41. +31 −0 lib/content/ci-release.yml
  42. +15 −52 lib/content/ci.yml
  43. +12 −19 lib/content/codeql-analysis.yml
  44. +1 −1 lib/content/commitlintrc.js
  45. +2 −2 lib/content/dependabot.yml
  46. +9 −0 lib/content/eslintrc.js
  47. +1 −14 lib/content/gitignore
  48. +82 −15 lib/content/index.js
  49. +1 −1 lib/content/npmrc
  50. +34 −18 lib/content/pkg.json
  51. +87 −19 lib/content/post-dependabot.yml
  52. +11 −14 lib/content/pull-request.yml
  53. +13 −0 lib/content/release-please-config.json
  54. +3 −0 lib/content/release-please-manifest.json
  55. +0 −56 lib/content/release-please.yml
  56. +133 −0 lib/content/release.yml
  57. +0 −11 lib/content/setup-git.yml
  58. +28 −0 lib/content/tap.json
  59. +27 −30 lib/index.js
  60. +83 −0 lib/release-please/changelog.js
  61. +56 −0 lib/release-please/github.js
  62. +97 −0 lib/release-please/index.js
  63. +193 −0 lib/release-please/node-workspace.js
  64. +14 −0 lib/release-please/util.js
  65. +103 −0 lib/release-please/version.js
  66. +73 −27 lib/util/files.js
  67. +3 −1 lib/util/get-git-url.js
  68. +34 −0 lib/util/gitignore.js
  69. +13 −1 lib/util/has-package.js
  70. +21 −0 lib/util/merge.js
  71. +79 −22 lib/util/parser.js
  72. +38 −20 lib/util/template.js
  73. +28 −15 package.json
  74. +36 −0 release-please-config.json
  75. +161 −0 tap-snapshots/test/apply/files-snapshots.js.test.cjs
  76. +1,351 −199 tap-snapshots/test/apply/full-content.js.test.cjs
  77. +0 −49 tap-snapshots/test/apply/index.js.test.cjs
  78. +0 −79 tap-snapshots/test/apply/lockfile.js.test.cjs
  79. +4,297 −0 tap-snapshots/test/apply/source-snapshots.js.test.cjs
  80. +0 −23 tap-snapshots/test/check/changelog.js.test.cjs
  81. +244 −0 tap-snapshots/test/check/diff-snapshots.js.test.cjs
  82. +0 −444 tap-snapshots/test/check/diffs.js.test.cjs
  83. +0 −215 tap-snapshots/test/check/gitignore.js.test.cjs
  84. +0 −22 tap-snapshots/test/check/required.js.test.cjs
  85. +248 −29 tap-snapshots/test/check/{index.js.test.cjs → snapshots.js.test.cjs}
  86. +0 −20 tap-snapshots/test/check/unwanted.js.test.cjs
  87. +47 −0 test/apply/allow-paths.js
  88. +81 −0 test/apply/engines.js
  89. +178 −0 test/apply/files-snapshots.js
  90. +0 −48 test/apply/full-content.js
  91. +278 −34 test/apply/index.js
  92. +0 −10 test/apply/lockfile.js
  93. +117 −0 test/apply/merge-yml.js
  94. +3 −71 test/apply/npm-bin.js
  95. +27 −0 test/apply/release.js
  96. +75 −0 test/apply/source-snapshots.js
  97. +27 −0 test/apply/version.js
  98. +0 −17 test/check/changelog.js
  99. +36 −46 test/check/{diffs.js → diff-snapshots.js}
  100. +1 −1 test/check/dogfood.js
  101. +0 −64 test/check/gitignore.js
  102. +10 −15 test/check/index.js
  103. +0 −9 test/check/required.js
  104. +77 −0 test/check/snapshots.js
  105. +0 −17 test/check/unwanted.js
  106. +0 −1 test/fixtures/header.js
  107. +13 −0 test/fixtures/yml-merge.js
  108. +16 −11 test/index.js
  109. +98 −0 test/release-please/changelog.js
  110. +178 −0 test/release-please/node-workspace.js
  111. +62 −0 test/release-please/version.js
  112. +28 −22 test/setup.js
  113. +5 −1 test/util/has-package.js
2 changes: 2 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
/* This file is automatically added by @npmcli/template-oss. Do not edit. */

'use strict'

const { readdirSync: readdir } = require('fs')

const localConfigs = readdir(__dirname)
6 changes: 0 additions & 6 deletions .eslintrc.local.js

This file was deleted.

6 changes: 6 additions & 0 deletions .eslintrc.local.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"ignorePatterns": [
"lib/content/*",
"!lib/content/index.js"
]
}
2 changes: 1 addition & 1 deletion .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@ version: 2

updates:
- package-ecosystem: npm
directory: "/"
directory: /
schedule:
interval: daily
allow:
32 changes: 32 additions & 0 deletions .github/matchers/tap.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"//@npmcli/template-oss": "This file is automatically added by @npmcli/template-oss. Do not edit.",
"problemMatcher": [
{
"owner": "tap",
"pattern": [
{
"regexp": "^\\s*not ok \\d+ - (.*)",
"message": 1
},
{
"regexp": "^\\s*---"
},
{
"regexp": "^\\s*at:"
},
{
"regexp": "^\\s*line:\\s*(\\d+)",
"line": 1
},
{
"regexp": "^\\s*column:\\s*(\\d+)",
"column": 1
},
{
"regexp": "^\\s*file:\\s*(.*)",
"file": 1
}
]
}
]
}
2 changes: 0 additions & 2 deletions .github/settings.yml

This file was deleted.

34 changes: 22 additions & 12 deletions .github/workflows/audit.yml
Original file line number Diff line number Diff line change
@@ -5,23 +5,33 @@ name: Audit
on:
workflow_dispatch:
schedule:
# "At 01:00 on Monday" https://crontab.guru/#0_1_*_*_1
- cron: "0 1 * * 1"
# "At 08:00 UTC (01:00 PT) on Monday" https://crontab.guru/#0_8_*_*_1
- cron: "0 8 * * 1"

jobs:
audit:
name: Audit Dependencies
if: github.repository_owner == 'npm'
runs-on: ubuntu-latest
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@v3
- name: Setup git user
- name: Checkout
uses: actions/checkout@v3
- name: Setup Git User
run: |
git config --global user.email "npm team"
git config --global user.name "ops+robot@npmjs.com"
- uses: actions/setup-node@v3
git config --global user.email "npm-cli+bot@github.com"
git config --global user.name "npm CLI robot"
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: 16.x
- name: Update npm to latest
node-version: 18.x
- name: Install npm@latest
run: npm i --prefer-online --no-fund --no-audit -g npm@latest
- run: npm -v
- run: npm i --ignore-scripts --no-audit --no-fund --package-lock
- run: npm audit
- name: npm Version
run: npm -v
- name: Install Dependencies
run: npm i --ignore-scripts --no-audit --no-fund --package-lock
- name: Run Audit
run: npm audit
210 changes: 210 additions & 0 deletions .github/workflows/ci-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
# This file is automatically added by @npmcli/template-oss. Do not edit.

name: CI - Release

on:
workflow_call:
inputs:
ref:
required: true
type: string
check-sha:
required: true
type: string

jobs:
lint-all:
name: Lint All
if: github.repository_owner == 'npm'
runs-on: ubuntu-latest
defaults:
run:
shell: bash
steps:
- name: Get Workflow Job
uses: actions/github-script@v6

id: check-output
env:
JOB_NAME: "Lint All"
MATRIX_NAME: ""
with:
script: |
const { owner, repo } = context.repo
const { data } = await github.rest.actions.listJobsForWorkflowRun({
owner,
repo,
run_id: context.runId,
per_page: 100
})
const jobName = process.env.JOB_NAME + process.env.MATRIX_NAME
const job = data.jobs.find(j => j.name.endsWith(jobName))
const jobUrl = job?.html_url
const shaUrl = `${context.serverUrl}/${owner}/${repo}/commit/${{ inputs.check-sha }}`
let summary = `This check is assosciated with ${shaUrl}\n\n`
if (jobUrl) {
summary += `For run logs, click here: ${jobUrl}`
} else {
summary += `Run logs could not be found for a job with name: "${jobName}"`
}
return { summary }
- name: Create Check
uses: LouisBrunner/checks-action@v1.3.1
id: check

with:
token: ${{ secrets.GITHUB_TOKEN }}
status: in_progress
name: Lint All
sha: ${{ inputs.check-sha }}
output: ${{ steps.check-output.outputs.result }}
- name: Checkout
uses: actions/checkout@v3
with:
ref: ${{ inputs.ref }}
- name: Setup Git User
run: |
git config --global user.email "npm-cli+bot@github.com"
git config --global user.name "npm CLI robot"
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: 18.x
- name: Install npm@latest
run: npm i --prefer-online --no-fund --no-audit -g npm@latest
- name: npm Version
run: npm -v
- name: Install Dependencies
run: npm i --ignore-scripts --no-audit --no-fund
- name: Lint
run: npm run lint --ignore-scripts
- name: Post Lint
run: npm run postlint --ignore-scripts
- name: Conclude Check
uses: LouisBrunner/checks-action@v1.3.1
if: always()
with:
token: ${{ secrets.GITHUB_TOKEN }}
conclusion: ${{ job.status }}
check_id: ${{ steps.check.outputs.check_id }}

test-all:
name: Test All - ${{ matrix.platform.name }} - ${{ matrix.node-version }}
if: github.repository_owner == 'npm'
strategy:
fail-fast: false
matrix:
platform:
- name: Linux
os: ubuntu-latest
shell: bash
- name: macOS
os: macos-latest
shell: bash
- name: Windows
os: windows-latest
shell: cmd
node-version:
- 14.17.0
- 14.x
- 16.13.0
- 16.x
- 18.0.0
- 18.x
runs-on: ${{ matrix.platform.os }}
defaults:
run:
shell: ${{ matrix.platform.shell }}
steps:
- name: Get Workflow Job
uses: actions/github-script@v6

id: check-output
env:
JOB_NAME: "Test All"
MATRIX_NAME: " - ${{ matrix.platform.name }} - ${{ matrix.node-version }}"
with:
script: |
const { owner, repo } = context.repo
const { data } = await github.rest.actions.listJobsForWorkflowRun({
owner,
repo,
run_id: context.runId,
per_page: 100
})
const jobName = process.env.JOB_NAME + process.env.MATRIX_NAME
const job = data.jobs.find(j => j.name.endsWith(jobName))
const jobUrl = job?.html_url
const shaUrl = `${context.serverUrl}/${owner}/${repo}/commit/${{ inputs.check-sha }}`
let summary = `This check is assosciated with ${shaUrl}\n\n`
if (jobUrl) {
summary += `For run logs, click here: ${jobUrl}`
} else {
summary += `Run logs could not be found for a job with name: "${jobName}"`
}
return { summary }
- name: Create Check
uses: LouisBrunner/checks-action@v1.3.1
id: check

with:
token: ${{ secrets.GITHUB_TOKEN }}
status: in_progress
name: Test All - ${{ matrix.platform.name }} - ${{ matrix.node-version }}
sha: ${{ inputs.check-sha }}
output: ${{ steps.check-output.outputs.result }}
- name: Checkout
uses: actions/checkout@v3
with:
ref: ${{ inputs.ref }}
- name: Setup Git User
run: |
git config --global user.email "npm-cli+bot@github.com"
git config --global user.name "npm CLI robot"
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- 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 --ignore-scripts --no-audit --no-fund
- name: Add Problem Matcher
run: echo "::add-matcher::.github/matchers/tap.json"
- name: Test
run: npm test --ignore-scripts
- name: Conclude Check
uses: LouisBrunner/checks-action@v1.3.1
if: always()
with:
token: ${{ secrets.GITHUB_TOKEN }}
conclusion: ${{ job.status }}
check_id: ${{ steps.check.outputs.check_id }}
143 changes: 107 additions & 36 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -5,66 +5,133 @@ name: CI
on:
workflow_dispatch:
pull_request:
branches:
- '*'
push:
branches:
- main
- latest
schedule:
# "At 02:00 on Monday" https://crontab.guru/#0_2_*_*_1
- cron: "0 2 * * 1"
# "At 09:00 UTC (02:00 PT) on Monday" https://crontab.guru/#0_9_*_*_1
- cron: "0 9 * * 1"

jobs:
engines:
name: Engines - ${{ 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:
- 14.17.0
- 16.13.0
- 18.0.0
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 "npm-cli+bot@github.com"
git config --global user.name "npm CLI robot"
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- 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 --ignore-scripts --no-audit --no-fund --engines-strict

lint:
name: Lint
if: github.repository_owner == 'npm'
runs-on: ubuntu-latest
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@v3
- name: Setup git user
- name: Checkout
uses: actions/checkout@v3
- name: Setup Git User
run: |
git config --global user.email "npm team"
git config --global user.name "ops+robot@npmjs.com"
- uses: actions/setup-node@v3
git config --global user.email "npm-cli+bot@github.com"
git config --global user.name "npm CLI robot"
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: 16.x
- name: Update npm to latest
node-version: 18.x
- name: Install npm@latest
run: npm i --prefer-online --no-fund --no-audit -g npm@latest
- run: npm -v
- run: npm i --ignore-scripts --no-audit --no-fund
- run: npm run lint
- name: npm Version
run: npm -v
- name: Install Dependencies
run: npm i --ignore-scripts --no-audit --no-fund
- name: Lint
run: npm run lint --ignore-scripts
- name: Post Lint
run: npm run postlint --ignore-scripts

test:
name: Test - ${{ matrix.platform.name }} - ${{ matrix.node-version }}
if: github.repository_owner == 'npm'
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
- name: Linux
os: ubuntu-latest
shell: bash
- os: macos-latest
- name: macOS
os: macos-latest
shell: bash
- os: windows-latest
- name: Windows
os: windows-latest
shell: cmd
node-version:
- 14.17.0
- 14.x
- 16.13.0
- 16.x
- 18.0.0
- 18.x
runs-on: ${{ matrix.platform.os }}
defaults:
run:
shell: ${{ matrix.platform.shell }}
steps:
- uses: actions/checkout@v3
- name: Setup git user
- name: Checkout
uses: actions/checkout@v3
- name: Setup Git User
run: |
git config --global user.email "npm team"
git config --global user.name "ops+robot@npmjs.com"
- uses: actions/setup-node@v3
git config --global user.email "npm-cli+bot@github.com"
git config --global user.name "npm CLI robot"
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- name: Update to workable npm (windows)
- 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: |
@@ -74,13 +141,17 @@ jobs:
node lib/npm.js install --no-fund --no-audit -g ..\npm-7.5.4.tgz
cd ..
rmdir /s /q package
- name: Update npm to 7
# If we do test on npm 10 it needs npm7
- name: Install npm@7
if: startsWith(matrix.node-version, '10.')
run: npm i --prefer-online --no-fund --no-audit -g npm@7
- name: Update npm to latest
- name: Install npm@latest
if: ${{ !startsWith(matrix.node-version, '10.') }}
run: npm i --prefer-online --no-fund --no-audit -g npm@latest
- run: npm -v
- run: npm i --ignore-scripts --no-audit --no-fund
- run: npm test --ignore-scripts
- name: npm Version
run: npm -v
- name: Install Dependencies
run: npm i --ignore-scripts --no-audit --no-fund
- name: Add Problem Matcher
run: echo "::add-matcher::.github/matchers/tap.json"
- name: Test
run: npm test --ignore-scripts
28 changes: 11 additions & 17 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
# This file is automatically added by @npmcli/template-oss. Do not edit.

name: "CodeQL"
name: CodeQL

on:
push:
branches:
- main
- latest
pull_request:
# The branches below must be a subset of the branches above
branches:
- main
- latest
schedule:
# "At 03:00 on Monday" https://crontab.guru/#0_3_*_*_1
- cron: "0 3 * * 1"
# "At 10:00 UTC (03:00 PT) on Monday" https://crontab.guru/#0_10_*_*_1
- cron: "0 10 * * 1"

jobs:
analyze:
@@ -24,21 +23,16 @@ jobs:
actions: read
contents: read
security-events: write

strategy:
fail-fast: false
matrix:
language: [ javascript ]

steps:
- uses: actions/checkout@v3
- name: Setup git user
- name: Checkout
uses: actions/checkout@v3
- name: Setup Git User
run: |
git config --global user.email "npm team"
git config --global user.name "ops+robot@npmjs.com"
git config --global user.email "npm-cli+bot@github.com"
git config --global user.name "npm CLI robot"
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
languages: javascript
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1
uses: github/codeql-action/analyze@v2
122 changes: 100 additions & 22 deletions .github/workflows/post-dependabot.yml
Original file line number Diff line number Diff line change
@@ -1,43 +1,121 @@
# This file is automatically added by @npmcli/template-oss. Do not edit.

name: Post Dependabot Actions
name: Post Dependabot

on: pull_request

# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions
permissions:
contents: write

jobs:
template-oss-apply:
template-oss:
name: template-oss
if: github.repository_owner == 'npm' && github.actor == 'dependabot[bot]'
runs-on: ubuntu-latest
if: github.actor == 'dependabot[bot]'
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@v3
- name: Setup git user
- name: Checkout
uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.ref }}
- name: Setup Git User
run: |
git config --global user.email "npm team"
git config --global user.name "ops+robot@npmjs.com"
- uses: actions/setup-node@v3
git config --global user.email "npm-cli+bot@github.com"
git config --global user.name "npm CLI robot"
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: 16.x
- name: Update npm to latest
node-version: 18.x
- name: Install npm@latest
run: npm i --prefer-online --no-fund --no-audit -g npm@latest
- run: npm -v
- name: Dependabot metadata
- name: npm Version
run: npm -v
- name: Install Dependencies
run: npm i --ignore-scripts --no-audit --no-fund
- name: Fetch Dependabot Metadata
id: metadata
uses: dependabot/fetch-metadata@v1.1.1
uses: dependabot/fetch-metadata@v1
with:
github-token: "${{ secrets.GITHUB_TOKEN }}"
- name: npm install and commit
github-token: ${{ secrets.GITHUB_TOKEN }}

# Dependabot can update multiple directories so we output which directory
# it is acting on so we can run the command for the correct root or workspace
- name: Get Dependabot Directory
if: contains(steps.metadata.outputs.dependency-names, '@npmcli/template-oss')
id: flags
run: |
dependabot_dir="${{ steps.metadata.outputs.directory }}"
if [[ "$dependabot_dir" == "/" ]]; then
echo "::set-output name=workspace::-iwr"
else
# strip leading slash from directory so it works as a
# a path to the workspace flag
echo "::set-output name=workspace::-w ${dependabot_dir#/}"
fi
- name: Apply Changes
if: steps.flags.outputs.workspace
id: apply
run: |
npm run template-oss-apply ${{ steps.flags.outputs.workspace }}
if [[ `git status --porcelain` ]]; then
echo "::set-output name=changes::true"
fi
# This only sets the conventional commit prefix. This workflow can't reliably determine
# what the breaking change is though. If a BREAKING CHANGE message is required then
# this PR check will fail and the commit will be amended with stafftools
if [[ "${{ steps.dependabot-metadata.outputs.update-type }}" == "version-update:semver-major" ]]; then
prefix='feat!'
else
prefix='chore!'
fi
echo "::set-output name=message::$prefix: postinstall for dependabot template-oss PR"
# This step will fail if template-oss has made any workflow updates. It is impossible
# for a workflow to update other workflows. In the case it does fail, we continue
# and then try to apply only a portion of the changes in the next step
- name: Push All Changes
if: steps.apply.outputs.changes
id: push
continue-on-error: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh pr checkout ${{ github.event.pull_request.number }}
npm install --ignore-scripts --no-audit --no-fund
npm run template-oss-apply
git add .
git commit -am "chore: postinstall for dependabot template-oss PR"
git commit -am "${{ steps.apply.outputs.message }}"
git push
npm run lint
# If the previous step failed, then reset the commit and remove any workflow changes
# and attempt to commit and push again. This is helpful because we will have a commit
# with the correct prefix that we can then --amend with @npmcli/stafftools later.
- name: Push All Changes Except Workflows
if: steps.apply.outputs.changes && steps.push-all.outcome == 'failure'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
git reset HEAD~
git checkout HEAD -- .github/workflows/
git clean -fd .github/workflows/
git commit -am "${{ steps.apply.outputs.message }}"
git push
# Check if all the necessary template-oss changes were applied. Since we continued
# on errors in one of the previous steps, this check will fail if our follow up
# only applied a portion of the changes and we need to followup manually.
#
# Note that this used to run `lint` and `postlint` but that will fail this action
# if we've also shipped any linting changes separate from template-oss. We do
# linting in another action, so we want to fail this one only if there are
# template-oss changes that could not be applied.
- name: Check Changes
if: steps.apply.outputs.changes
run: |
npm exec --offline ${{ steps.flags.outputs.workspace }} -- template-oss-check
- name: Fail on Breaking Change
if: steps.apply.outputs.changes && startsWith(steps.apply.outputs.message, 'feat!')
run: |
echo "This PR has a breaking change. Run 'npx -p @npmcli/stafftools gh template-oss-fix'"
echo "for more information on how to fix this with a BREAKING CHANGE footer."
exit 1
46 changes: 28 additions & 18 deletions .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This file is automatically added by @npmcli/template-oss. Do not edit.

name: Pull Request Linting
name: Pull Request

on:
pull_request:
@@ -11,28 +11,38 @@ on:
- synchronize

jobs:
check:
name: Check PR Title or Commits
commitlint:
name: Lint Commits
if: github.repository_owner == 'npm'
runs-on: ubuntu-latest
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@v3
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Setup git user
- name: Setup Git User
run: |
git config --global user.email "npm team"
git config --global user.name "ops+robot@npmjs.com"
- uses: actions/setup-node@v3
git config --global user.email "npm-cli+bot@github.com"
git config --global user.name "npm CLI robot"
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: 16.x
- name: Update npm to latest
node-version: 18.x
- name: Install npm@latest
run: npm i --prefer-online --no-fund --no-audit -g npm@latest
- run: npm -v
- name: Install deps
run: npm i -D @commitlint/cli @commitlint/config-conventional
- name: Check commits OR PR title
env:
PR_TITLE: ${{ github.event.pull_request.title }}
- name: npm Version
run: npm -v
- name: Install Dependencies
run: npm i --ignore-scripts --no-audit --no-fund
- name: Run Commitlint on Commits
id: commit
continue-on-error: true
run: |
npx --offline commitlint -V --from origin/main --to ${{ github.event.pull_request.head.sha }} \
|| echo $PR_TITLE | npx --offline commitlint -V
npx --offline commitlint -V --from origin/${{ github.base_ref }} --to ${{ github.event.pull_request.head.sha }}
- name: Run Commitlint on PR Title
if: steps.commit.outcome == 'failure'
run: |
echo ${{ github.event.pull_request.title }} | npx --offline commitlint -V
26 changes: 0 additions & 26 deletions .github/workflows/release-please.yml

This file was deleted.

298 changes: 298 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,298 @@
# This file is automatically added by @npmcli/template-oss. Do not edit.

name: Release

on:
workflow_dispatch:
push:
branches:
- main
- latest

permissions:
contents: write
pull-requests: write
checks: write

jobs:
release:
outputs:
pr: ${{ steps.release.outputs.pr }}
releases: ${{ steps.release.outputs.releases }}
release-flags: ${{ steps.release.outputs.release-flags }}
branch: ${{ steps.release.outputs.pr-branch }}
pr-number: ${{ steps.release.outputs.pr-number }}
comment-id: ${{ steps.pr-comment.outputs.result }}
check-id: ${{ steps.check.outputs.check_id }}
name: Release
if: github.repository_owner == 'npm'
runs-on: ubuntu-latest
defaults:
run:
shell: bash
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Git User
run: |
git config --global user.email "npm-cli+bot@github.com"
git config --global user.name "npm CLI robot"
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: 18.x
- name: Install npm@latest
run: npm i --prefer-online --no-fund --no-audit -g npm@latest
- name: npm Version
run: npm -v
- name: Install Dependencies
run: npm i --ignore-scripts --no-audit --no-fund
- name: Release Please
id: release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
npx --offline template-oss-release-please ${{ github.ref_name }} ${{ github.event_name }}
- name: Post Pull Request Comment
if: steps.release.outputs.pr-number
uses: actions/github-script@v6
id: pr-comment
env:
PR_NUMBER: ${{ steps.release.outputs.pr-number }}
REF_NAME: ${{ github.ref_name }}
with:
script: |
const { REF_NAME, PR_NUMBER } = process.env
const repo = { owner: context.repo.owner, repo: context.repo.repo }
const issue = { ...repo, issue_number: PR_NUMBER }
const { data: workflow } = await github.rest.actions.getWorkflowRun({ ...repo, run_id: context.runId })
let body = '## Release Manager\n\n'
const comments = await github.paginate(github.rest.issues.listComments, issue)
let commentId = comments?.find(c => c.user.login === 'github-actions[bot]' && c.body.startsWith(body))?.id
body += `Release workflow run: ${workflow.html_url}\n\n#### Force CI to Rerun for This Release\n\n`
body += `This PR will be updated and CI will run for every non-\`chore:\` commit that is pushed to \`main\`. `
body += `To force CI to rerun, run this command:\n\n`
body += `\`\`\`\ngh workflow run release.yml -r ${REF_NAME}\n\`\`\``
if (commentId) {
await github.rest.issues.updateComment({ ...repo, comment_id: commentId, body })
} else {
const { data: comment } = await github.rest.issues.createComment({ ...issue, body })
commentId = comment?.id
}
return commentId
- name: Get Workflow Job
uses: actions/github-script@v6
if: steps.release.outputs.pr-number
id: check-output
env:
JOB_NAME: "Release"
MATRIX_NAME: ""
with:
script: |
const { owner, repo } = context.repo
const { data } = await github.rest.actions.listJobsForWorkflowRun({
owner,
repo,
run_id: context.runId,
per_page: 100
})
const jobName = process.env.JOB_NAME + process.env.MATRIX_NAME
const job = data.jobs.find(j => j.name.endsWith(jobName))
const jobUrl = job?.html_url
const shaUrl = `${context.serverUrl}/${owner}/${repo}/commit/${{ steps.release.outputs.pr-sha }}`
let summary = `This check is assosciated with ${shaUrl}\n\n`
if (jobUrl) {
summary += `For run logs, click here: ${jobUrl}`
} else {
summary += `Run logs could not be found for a job with name: "${jobName}"`
}
return { summary }
- name: Create Check
uses: LouisBrunner/checks-action@v1.3.1
id: check
if: steps.release.outputs.pr-number
with:
token: ${{ secrets.GITHUB_TOKEN }}
status: in_progress
name: Release
sha: ${{ steps.release.outputs.pr-sha }}
output: ${{ steps.check-output.outputs.result }}

update:
needs: release
outputs:
sha: ${{ steps.commit.outputs.sha }}
check-id: ${{ steps.check.outputs.check_id }}
name: Update - Release
if: github.repository_owner == 'npm' && needs.release.outputs.pr
runs-on: ubuntu-latest
defaults:
run:
shell: bash
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
ref: ${{ needs.release.outputs.branch }}
- name: Setup Git User
run: |
git config --global user.email "npm-cli+bot@github.com"
git config --global user.name "npm CLI robot"
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: 18.x
- name: Install npm@latest
run: npm i --prefer-online --no-fund --no-audit -g npm@latest
- name: npm Version
run: npm -v
- name: Install Dependencies
run: npm i --ignore-scripts --no-audit --no-fund
- name: Run Post Pull Request Actions
env:
RELEASE_PR_NUMBER: ${{ needs.release.outputs.pr-number }}
RELEASE_COMMENT_ID: ${{ needs.release.outputs.comment-id }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
npm exec --offline -- template-oss-release-manager
npm run rp-pull-request --ignore-scripts --if-present
- name: Commit
id: commit
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
git commit --all --amend --no-edit || true
git push --force-with-lease
echo "::set-output name=sha::$(git rev-parse HEAD)"
- name: Get Workflow Job
uses: actions/github-script@v6

id: check-output
env:
JOB_NAME: "Update - Release"
MATRIX_NAME: ""
with:
script: |
const { owner, repo } = context.repo
const { data } = await github.rest.actions.listJobsForWorkflowRun({
owner,
repo,
run_id: context.runId,
per_page: 100
})
const jobName = process.env.JOB_NAME + process.env.MATRIX_NAME
const job = data.jobs.find(j => j.name.endsWith(jobName))
const jobUrl = job?.html_url
const shaUrl = `${context.serverUrl}/${owner}/${repo}/commit/${{ steps.commit.outputs.sha }}`
let summary = `This check is assosciated with ${shaUrl}\n\n`
if (jobUrl) {
summary += `For run logs, click here: ${jobUrl}`
} else {
summary += `Run logs could not be found for a job with name: "${jobName}"`
}
return { summary }
- name: Create Check
uses: LouisBrunner/checks-action@v1.3.1
id: check

with:
token: ${{ secrets.GITHUB_TOKEN }}
status: in_progress
name: Release
sha: ${{ steps.commit.outputs.sha }}
output: ${{ steps.check-output.outputs.result }}
- name: Conclude Check
uses: LouisBrunner/checks-action@v1.3.1
if: always()
with:
token: ${{ secrets.GITHUB_TOKEN }}
conclusion: ${{ job.status }}
check_id: ${{ needs.release.outputs.check-id }}

ci:
name: CI - Release
needs: [ release, update ]
if: needs.release.outputs.pr
uses: ./.github/workflows/ci-release.yml
with:
ref: ${{ needs.release.outputs.branch }}
check-sha: ${{ needs.update.outputs.sha }}

post-ci:
needs: [ release, update, ci ]
name: Post CI - Release
if: github.repository_owner == 'npm' && needs.release.outputs.pr && always()
runs-on: ubuntu-latest
defaults:
run:
shell: bash
steps:
- name: Get Needs Result
id: needs-result
run: |
result=""
if [[ "${{ contains(needs.*.result, 'failure') }}" == "true" ]]; then
result="failure"
elif [[ "${{ contains(needs.*.result, 'cancelled') }}" == "true" ]]; then
result="cancelled"
else
result="success"
fi
echo "::set-output name=result::$result"
- name: Conclude Check
uses: LouisBrunner/checks-action@v1.3.1
if: always()
with:
token: ${{ secrets.GITHUB_TOKEN }}
conclusion: ${{ steps.needs-result.outputs.result }}
check_id: ${{ needs.update.outputs.check-id }}

post-release:
needs: release
name: Post Release - Release
if: github.repository_owner == 'npm' && needs.release.outputs.releases
runs-on: ubuntu-latest
defaults:
run:
shell: bash
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Git User
run: |
git config --global user.email "npm-cli+bot@github.com"
git config --global user.name "npm CLI robot"
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: 18.x
- name: Install npm@latest
run: npm i --prefer-online --no-fund --no-audit -g npm@latest
- name: npm Version
run: npm -v
- name: Install Dependencies
run: npm i --ignore-scripts --no-audit --no-fund
- name: Run Post Release Actions
env:
RELEASES: ${{ needs.release.outputs.releases }}
run: |
npm run rp-release --ignore-scripts --if-present ${{ join(fromJSON(needs.release.outputs.release-flags), ' ') }}
23 changes: 13 additions & 10 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -4,22 +4,25 @@
/*

# keep these
!/.eslintrc.local.*
!**/.gitignore
!/docs/
!/tap-snapshots/
!/test/
!/map.js
!/scripts/
!/README*
!/LICENSE*
!/CHANGELOG*
!/.commitlintrc.js
!/.eslintrc.js
!/.eslintrc.local.*
!/.github/
!/.gitignore
!/.npmrc
!/SECURITY.md
!/.release-please-manifest.json
!/bin/
!/CHANGELOG*
!/CODE_OF_CONDUCT.md
!/docs/
!/lib/
!/LICENSE*
!/map.js
!/package.json
!/README*
!/release-please-config.json
!/scripts/
!/SECURITY.md
!/tap-snapshots/
!/test/
3 changes: 3 additions & 0 deletions .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
".": "4.6.0"
}
233 changes: 233 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,238 @@
# Changelog

## [4.6.0](https://github.com/npm/template-oss/compare/v4.5.1...v4.6.0) (2022-10-14)

### Features

* [`2175b67`](https://github.com/npm/template-oss/commit/2175b67268e56f8e1d2ceb1892d61c378883f606) [#237](https://github.com/npm/template-oss/pull/237) add workflow dispatch to rerun release ci (@lukekarrys)

### Bug Fixes

* [`09bcd64`](https://github.com/npm/template-oss/commit/09bcd6486133d4cb9ab5396868de839649de00be) [#236](https://github.com/npm/template-oss/pull/236) remove npmcli/fs dep (@lukekarrys)
* [`2fef1e8`](https://github.com/npm/template-oss/commit/2fef1e81c993646eaf903a7b8999c2bad124111b) [#235](https://github.com/npm/template-oss/pull/235) refactor audit command into a separate file for overriding (@lukekarrys)

### Dependencies

* [`47eae35`](https://github.com/npm/template-oss/commit/47eae35c2fe41b5445f7404fe7b6ce1eb6d97e40) [#242](https://github.com/npm/template-oss/pull/242) bump @npmcli/git from 3.0.2 to 4.0.0 (#242)
* [`243a23f`](https://github.com/npm/template-oss/commit/243a23f829b07530c5245096431d6776cf27e20b) [#241](https://github.com/npm/template-oss/pull/241) bump @npmcli/map-workspaces from 2.0.4 to 3.0.0 (#241)
* [`179f02a`](https://github.com/npm/template-oss/commit/179f02aa170671466df8f11656f64858f3c20b25) [#240](https://github.com/npm/template-oss/pull/240) bump proc-log from 2.0.1 to 3.0.0 (#240)
* [`faf1ba0`](https://github.com/npm/template-oss/commit/faf1ba0bd465d8ac118c61a412e7a68f795d016c) [#238](https://github.com/npm/template-oss/pull/238) bump @npmcli/package-json from 2.0.0 to 3.0.0 (#238)
* [`eaaf3d9`](https://github.com/npm/template-oss/commit/eaaf3d9f79ef4979f2495a806bd4f03f35a5d037) [#234](https://github.com/npm/template-oss/pull/234) bump hosted-git-info from 5.1.0 to 6.0.0
* [`f499ac5`](https://github.com/npm/template-oss/commit/f499ac5b4bf907d72421c0eebe3f62074412f40c) [#231](https://github.com/npm/template-oss/pull/231) bump json-parse-even-better-errors from 2.3.1 to 3.0.0

## [4.5.1](https://github.com/npm/template-oss/compare/v4.5.0...v4.5.1) (2022-10-08)

### Bug Fixes

* [`bc72b05`](https://github.com/npm/template-oss/commit/bc72b05884dc59cd5f45b6f29f3308aad0456e7a) [#230](https://github.com/npm/template-oss/pull/230) add individual workspace flag to lint step (@lukekarrys)

### Dependencies

* [`0ccfc17`](https://github.com/npm/template-oss/commit/0ccfc17f1c4033575cc66c67513baf85a9f2b047) [#228](https://github.com/npm/template-oss/pull/228) `@npmcli/release-please@14.2.6`

## [4.5.0](https://github.com/npm/template-oss/compare/v4.4.5...v4.5.0) (2022-10-05)

### Features

* [`aef199e`](https://github.com/npm/template-oss/commit/aef199e300b3bb00d7631b86ca09d6d3d1b86386) [#221](https://github.com/npm/template-oss/pull/221) add default release-manager script (#221) (@lukekarrys)

### Bug Fixes

* [`b313218`](https://github.com/npm/template-oss/commit/b313218153e55d83713c8d8830e74a1d0d412098) [#226](https://github.com/npm/template-oss/pull/226) dont use -ws flags in release workflow when not necessary (#226) (@lukekarrys)
* [`f6a0268`](https://github.com/npm/template-oss/commit/f6a02684cd5742274ac33efc6efa89707d013bcc) [#225](https://github.com/npm/template-oss/pull/225) bump workspace dev deps with a deps commit (#225) (@lukekarrys)
* [`298600d`](https://github.com/npm/template-oss/commit/298600db3509f5bab469caa95fd73ceedc42cde4) [#224](https://github.com/npm/template-oss/pull/224) use head.ref for post dependabot checkout (#224) (@lukekarrys)

## [4.4.5](https://github.com/npm/template-oss/compare/v4.4.4...v4.4.5) (2022-10-04)

### Bug Fixes

* [`6ecdea4`](https://github.com/npm/template-oss/commit/6ecdea4580e00bb3fe80ca4765f055521c51d4ce) [#222](https://github.com/npm/template-oss/pull/222) fallback to lower bound of range for engines check (@lukekarrys)

## [4.4.4](https://github.com/npm/template-oss/compare/v4.4.3...v4.4.4) (2022-09-30)

### Bug Fixes

* [`6a2b97b`](https://github.com/npm/template-oss/commit/6a2b97b2dafcef7d795c51d3b01830c4fcda7c25) use github.ref_name for post dependabot checkout (@lukekarrys)

## [4.4.3](https://github.com/npm/template-oss/compare/v4.4.2...v4.4.3) (2022-09-29)

### Bug Fixes

* [`e21239e`](https://github.com/npm/template-oss/commit/e21239e0dea2dae585102878a4fc13e8ae7cae7a) [#218](https://github.com/npm/template-oss/pull/218) checkout head ref name in post dependabot (@lukekarrys)

## [4.4.2](https://github.com/npm/template-oss/compare/v4.4.1...v4.4.2) (2022-09-23)

### Bug Fixes

* [`8e16dc7`](https://github.com/npm/template-oss/commit/8e16dc76d9a469dd9caa73062e0983bef6792c82) [#216](https://github.com/npm/template-oss/pull/216) remove leading slash from dependabot metadata dir (@lukekarrys)

### Dependencies

* [`53bb928`](https://github.com/npm/template-oss/commit/53bb928258aa271c65a9b6d77c8e4cf6d60bbebe) `@npmcli/release-please@14.2.5`

## [4.4.1](https://github.com/npm/template-oss/compare/v4.4.0...v4.4.1) (2022-09-22)

### Bug Fixes

* [`1649552`](https://github.com/npm/template-oss/commit/1649552c86016ae422407610f9be848b0dfd8bae) only extend underscore partial files (@lukekarrys)

## [4.4.0](https://github.com/npm/template-oss/compare/v4.3.2...v4.4.0) (2022-09-22)

### Features

* [`d4ddfca`](https://github.com/npm/template-oss/commit/d4ddfca7d1c9077dedbf0e751bb133b9c79ed1b6) [#213](https://github.com/npm/template-oss/pull/213) allow extending partials (#213) (@lukekarrys)
* [`88f8387`](https://github.com/npm/template-oss/commit/88f8387ee90d7ee964ad40b4b90570c18b602ce5) [#212](https://github.com/npm/template-oss/pull/212) add a strict engines check to ci (#212) (@lukekarrys)
* [`2fdcddd`](https://github.com/npm/template-oss/commit/2fdcddd615066178cd1e84e2cd2144e9b4c566ef) [#180](https://github.com/npm/template-oss/pull/180) make template-oss postinstall commit a breaking change for majors (#180) (@lukekarrys)

### Bug Fixes

* [`0e95298`](https://github.com/npm/template-oss/commit/0e952980f78b72097123b157cb220bd6c44b5199) [#214](https://github.com/npm/template-oss/pull/214) properly quote strings with exclamation marks (#214) (@lukekarrys)
* [`99f3945`](https://github.com/npm/template-oss/commit/99f394564552d43cd97becb5431daef0c3c0e464) [#210](https://github.com/npm/template-oss/pull/210) make tap test-ignore a regex instead of a glob (#210) (@lukekarrys)
* [`e19ebc3`](https://github.com/npm/template-oss/commit/e19ebc3270f3e563e206e474c9e0cff3c7dcd742) [#209](https://github.com/npm/template-oss/pull/209) properly ignore workspace paths from root during ci (#209) (@lukekarrys)

## [4.3.2](https://github.com/npm/template-oss/compare/v4.3.1...v4.3.2) (2022-09-19)

### Bug Fixes

* [`5fededb`](https://github.com/npm/template-oss/commit/5fededb16da81db88b56db663466d968471df973) [#207](https://github.com/npm/template-oss/pull/207) workspace can use only latest ci version of root (@lukekarrys)

## [4.3.1](https://github.com/npm/template-oss/compare/v4.3.0...v4.3.1) (2022-09-19)

### Bug Fixes

* [`817d49e`](https://github.com/npm/template-oss/commit/817d49e3d64f76ce2fd6d1d765044908bd2af022) [#205](https://github.com/npm/template-oss/pull/205) remove 'All' from regular test job name (@lukekarrys)

## [4.3.0](https://github.com/npm/template-oss/compare/v4.2.0...v4.3.0) (2022-09-19)

### Features

* [`3640080`](https://github.com/npm/template-oss/commit/36400808bf9da35e10aab0c6663fb284624b8dd6) add checks to release pull request (@lukekarrys)
* [`5b65537`](https://github.com/npm/template-oss/commit/5b655374771b62c572800dd56f44c102f863ba73) add names to all jobs and steps (@lukekarrys)
* [`caf393c`](https://github.com/npm/template-oss/commit/caf393c6d01b7608eeafe4503fb73fd47d21193c) add dependabot configuration for workspaces (@lukekarrys)
* [`e43ee70`](https://github.com/npm/template-oss/commit/e43ee70c03e41c6bc25b1938a360ccfc33a30319) [#198](https://github.com/npm/template-oss/pull/198) update codeql actions to v2 (@lukekarrys)

## [4.2.0](https://github.com/npm/template-oss/compare/v4.1.2...v4.2.0) (2022-09-15)

### Features

* [`849cecc`](https://github.com/npm/template-oss/commit/849cecce6851d644d8a0e1a153ce3d245d967d44) add `content` config option to allow a module to set own content (@lukekarrys)
* [`423450f`](https://github.com/npm/template-oss/commit/423450f9802a676a035143a1fd503403c305e79d) [#195](https://github.com/npm/template-oss/pull/195) remove postpublish from package.json (#195) (@lukekarrys)

### Bug Fixes

* [`ffa2c08`](https://github.com/npm/template-oss/commit/ffa2c08267d0807c1e341e907e1eef8b179d880b) [#189](https://github.com/npm/template-oss/pull/189) dont run workflows outside of npm org (#194) (@lukekarrys)

## [4.1.2](https://github.com/npm/template-oss/compare/v4.1.1...v4.1.2) (2022-09-14)

### Bug Fixes

* [`6bc355a`](https://github.com/npm/template-oss/commit/6bc355a2b313bdde0fd6fe7cdf0c290ebf747af9) [#192](https://github.com/npm/template-oss/pull/192) set package.json version from release please (#192) (@lukekarrys)

## [4.1.1](https://github.com/npm/template-oss/compare/v4.1.0...v4.1.1) (2022-09-13)

### Bug Fixes

* [`78a05fe`](https://github.com/npm/template-oss/commit/78a05fe8393dbf9e4d3bd43f2eff4db12921cde5) [#190](https://github.com/npm/template-oss/pull/190) pass current github ref to release please (#190) (@lukekarrys)

## [4.1.0](https://github.com/npm/template-oss/compare/v4.0.0...v4.1.0) (2022-09-13)

### Features

* [`352d332`](https://github.com/npm/template-oss/commit/352d33210a89deee6b85ce6e8d9650054177e10f) [#187](https://github.com/npm/template-oss/pull/187) add release branches config to release-please workflow (#187) (@lukekarrys)

### Bug Fixes

* [`b58d86a`](https://github.com/npm/template-oss/commit/b58d86adc26d3d6fc07c682391a597398dd3a5b3) [#183](https://github.com/npm/template-oss/pull/183) use conventional commits from release-please for changelog (#183) (@lukekarrys)

## [4.0.0](https://github.com/npm/template-oss/compare/v3.8.1...v4.0.0) (2022-09-08)

### ⚠ BREAKING CHANGES

* this updates this package and the templated engines for node to `^14.17.0 || ^16.13.0 || >=18.0.0`

### Features

* [`a72774a`](https://github.com/npm/template-oss/commit/a72774aa4cd4ad74df5f85b2793d8408688507da) [#184](https://github.com/npm/template-oss/pull/184) feat: update engines to `^14.17.0 || ^16.13.0 || >=18.0.0` (@lukekarrys)

## [3.8.1](https://github.com/npm/template-oss/compare/v3.8.0...v3.8.1) (2022-09-01)

### Bug Fixes

* [`70782b3`](https://github.com/npm/template-oss/commit/70782b3677e40472260853df92d3ca8b805af422) [#179](https://github.com/npm/template-oss/pull/179) fix: update a few release nits after trying it on the cli (@lukekarrys)

## [3.8.0](https://github.com/npm/template-oss/compare/v3.7.1...v3.8.0) (2022-08-31)

### Features

* [`7562777`](https://github.com/npm/template-oss/commit/75627773c0afd3e9dbe5c176a797f363d81208f3) [#174](https://github.com/npm/template-oss/pull/174) feat: use custom release please script (@lukekarrys)

### Bug Fixes

* [`0f44075`](https://github.com/npm/template-oss/commit/0f440750cbe55c02df5c2b8a479d51bd895ce17f) [#175](https://github.com/npm/template-oss/pull/175) fix: only add release please workspace plugins to monorepos (@lukekarrys)

## [3.7.1](https://github.com/npm/template-oss/compare/v3.7.0...v3.7.1) (2022-08-25)


### Bug Fixes

* add tap matcher to workspaces ([ce977c4](https://github.com/npm/template-oss/commit/ce977c4737476ed84d2d5c5f584daab7d1c780c6))
* remove unnecessary if statement in release please action ([678cb5a](https://github.com/npm/template-oss/commit/678cb5acb93206568a5b7e07d5bd41a669d7db8b))

## [3.7.0](https://github.com/npm/template-oss/compare/v3.6.0...v3.7.0) (2022-08-25)


### Features

* use release please manifest configuration ([#164](https://github.com/npm/template-oss/issues/164)) ([95118ec](https://github.com/npm/template-oss/commit/95118ec0704162c1c25f3ccc0099ac972bfd752a))


### Bug Fixes

* default root component to empty string to match previous behavior ([#166](https://github.com/npm/template-oss/issues/166)) ([0f2a89f](https://github.com/npm/template-oss/commit/0f2a89f6fa55e918cab151af11e96a256ecd5a7e))
* remove old release please files ([#170](https://github.com/npm/template-oss/issues/170)) ([09d955f](https://github.com/npm/template-oss/commit/09d955f3dbc68e16cbe34d018d6197a06bc66727))

## [3.6.0](https://github.com/npm/template-oss/compare/v3.5.0...v3.6.0) (2022-08-22)


### Features

* add a problem matcher for tap output ([#160](https://github.com/npm/template-oss/issues/160)) ([8176e44](https://github.com/npm/template-oss/commit/8176e44f9764e09e7d5c52c2aadfc1c0ca228af3))
* make cron workflows run early PT ([#159](https://github.com/npm/template-oss/issues/159)) ([6f571eb](https://github.com/npm/template-oss/commit/6f571eb93c2c101926a8dae7b7160e981c208ab7))


### Bug Fixes

* compare to \n instead of os.EOL ([#157](https://github.com/npm/template-oss/issues/157)) ([5517e9e](https://github.com/npm/template-oss/commit/5517e9eb0f081217423a2c193eabe2496c08eaab))
* pin yaml to 2.0.0-11 ([#161](https://github.com/npm/template-oss/issues/161)) ([e095275](https://github.com/npm/template-oss/commit/e095275f229c66d8820f4edc5b801ceee60538df))
* remove more usage of os.EOL ([#162](https://github.com/npm/template-oss/issues/162)) ([4dde648](https://github.com/npm/template-oss/commit/4dde648deb0d880d12f8810914309a9aa0947010))

## [3.5.0](https://github.com/npm/template-oss/compare/v3.4.3...v3.5.0) (2022-05-11)


### Features

* add CODE_OF_CONDUCT.md ([#146](https://github.com/npm/template-oss/issues/146)) ([ad8c6fc](https://github.com/npm/template-oss/commit/ad8c6fc7bd06bb9edb3b44619d9bf5fc306bcb0b))


### Bug Fixes

* update bot account information ([#147](https://github.com/npm/template-oss/issues/147)) ([f802204](https://github.com/npm/template-oss/commit/f802204efa59a30a138d2338c478e357562b7fb1))

### [3.4.3](https://github.com/npm/template-oss/compare/v3.4.2...v3.4.3) (2022-05-03)


### Bug Fixes

* add 'use strict' to .eslintrc.js ([#141](https://github.com/npm/template-oss/issues/141)) ([6486967](https://github.com/npm/template-oss/commit/64869675f597eaf96e491b19edb8718db9939352))

### [3.4.2](https://github.com/npm/template-oss/compare/v3.4.1...v3.4.2) (2022-04-22)


### Bug Fixes

* correctly set git user and email ([eb55928](https://github.com/npm/template-oss/commit/eb55928ada5db8657c57a568057aa886fa8dae4b))
* properly install and use glob ([9bf3126](https://github.com/npm/template-oss/commit/9bf3126b03c8fa8629004ceb0fe0de480fc451f9))

### [3.4.1](https://github.com/npm/template-oss/compare/v3.4.0...v3.4.1) (2022-04-15)


7 changes: 7 additions & 0 deletions CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<!-- This file is automatically added by @npmcli/template-oss. Do not edit. -->

All interactions in this repo are covered by the [npm Code of
Conduct](https://docs.npmjs.com/policies/conduct)

The npm cli team may, at its own discretion, moderate, remove, or edit
any interactions such as pull requests, issues, and comments.
260 changes: 260 additions & 0 deletions bin/release-manager.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,260 @@
#!/usr/bin/env node

const { Octokit } = require('@octokit/rest')
const semver = require('semver')
const mapWorkspaces = require('@npmcli/map-workspaces')
const { join } = require('path')

const log = (...logs) => console.error('LOG', ...logs)

const ROOT = process.cwd()
const pkg = require(join(ROOT, 'package.json'))

/* eslint-disable max-len */
const DEFAULT_RELEASE_PROCESS = `
1. Checkout the release branch and test
\`\`\`sh
gh pr checkout <PR-NUMBER> --force
npm i
npm test
gh pr checks --watch
\`\`\`
1. Publish workspaces
\`\`\`sh
npm publish -w <WS-PKG-N>
\`\`\`
1. Publish
\`\`\`sh
npm publish <PUBLISH-FLAGS>
\`\`\`
1. Merge release PR
\`\`\`sh
gh pr merge --rebase
git checkout <BASE-BRANCH>
git fetch
git reset --hard origin/<BASE-BRANCH>
\`\`\`
1. Check For Release Tags
Release Please will run on the just pushed release commit and create GitHub releases and tags for each package.
\`\`\`
gh run watch \`gh run list -w release -b <BASE-BRANCH> -L 1 --json databaseId -q ".[0].databaseId"\`
\`\`\`
` /* eslint-enable max-len */

const getReleaseProcess = async ({ owner, repo }) => {
const RELEASE_LIST_ITEM = /^\d+\.\s/gm

log(`Fetching release process from:`, owner, repo, 'wiki')

let releaseProcess = ''
try {
releaseProcess = await new Promise((resolve, reject) => {
require('https')
.get(`https://raw.githubusercontent.com/wiki/${owner}/${repo}/Release-Process.md`, resp => {
let d = ''
resp.on('data', c => (d += c))
resp.on('end', () => {
if (resp.statusCode !== 200) {
reject(new Error(`${resp.req.protocol + resp.req.host + resp.req.path}: ${d}`))
} else {
resolve(d)
}
})
})
.on('error', reject)
})
} catch (e) {
log('Release wiki not found', e.message)
log('Using default release process')
releaseProcess = DEFAULT_RELEASE_PROCESS.trim() + '\n'
}

// XXX: the release steps need to always be the last thing in the doc for this to work
const releaseLines = releaseProcess.split('\n')
const releaseStartLine = releaseLines.reduce((acc, line, index) =>
line.match(/^#+\s/) ? index : acc, 0)
const section = releaseLines.slice(releaseStartLine).join('\n')

return section.split({
[Symbol.split] (str) {
const [, ...matches] = str.split(RELEASE_LIST_ITEM)
log(`Found ${matches.length} release items`)
return matches.map((m) => `- [ ] <STEP_INDEX>. ${m}`.trim())
},
})
}

const getPrReleases = async (pr) => {
const RELEASE_SEPARATOR = /<details><summary>.*<\/summary>/g
const MONO_VERSIONS = /<details><summary>(?:(.*?):\s)?(.*?)<\/summary>/
const ROOT_VERSION = /\n##\s\[(.*?)\]/

const workspaces = [...await mapWorkspaces({ pkg: pkg, cwd: ROOT })].reduce((acc, [k]) => {
const wsComponentName = k.startsWith('@') ? k.split('/')[1] : k
acc[wsComponentName] = k
return acc
}, {})

const getReleaseInfo = ({ name, version: rawVersion }) => {
const version = semver.parse(rawVersion)
const prerelease = !!version.prerelease.length
const tag = `${name ? `${name}-` : ''}v${rawVersion}`
const workspace = workspaces[name]

return {
name,
tag,
prerelease,
version: rawVersion,
major: version.major,
url: `https://github.com/${pr.base.repo.full_name}/releases/tag/${tag}`,
flags: `${name ? `-w ${workspace}` : ''} ${prerelease ? `--tag prerelease` : ''}`.trim(),
}
}

const releases = pr.body.match(RELEASE_SEPARATOR)

if (!releases) {
log('Found no monorepo, checking for single root version')
const [, version] = pr.body.match(ROOT_VERSION) || []

if (!version) {
throw new Error('Could not find version with:', ROOT_VERSION)
}

log('Found version', version)
return [getReleaseInfo({ version })]
}

log(`Found ${releases.length} releases`)

return releases.reduce((acc, r) => {
const [, name, version] = r.match(MONO_VERSIONS)
const release = getReleaseInfo({ name, version })

if (!name) {
log('Found root', release)
acc[0] = release
} else {
log('Found workspace', release)
acc[1].push(release)
}

return acc
}, [null, []])
}

const appendToComment = async ({ github, commentId, title, body }) => {
if (!commentId) {
log(`No comment id, skipping append to comment`)
return
}

const { data: comment } = await github.rest.issues.getComment({
...github.repo,
comment_id: commentId,
})

const hasAppended = comment.body.includes(title)

log('Found comment with id:', commentId)
log(hasAppended ? 'Comment has aready been appended, replacing' : 'Appending to comment')

const prefix = hasAppended
? comment.body.split(title)[0]
: comment.body

return github.rest.issues.updateComment({
...github.repo,
comment_id: commentId,
body: [prefix, title, body].join('\n\n'),
})
}

const main = async (env) => {
// These env vars are set by the release.yml workflow from template-oss
const {
CI,
GITHUB_TOKEN,
GITHUB_REPOSITORY,
RELEASE_PR_NUMBER,
RELEASE_COMMENT_ID, // comment is optional for testing
} = env

if (!CI || !GITHUB_TOKEN || !GITHUB_REPOSITORY || !RELEASE_PR_NUMBER) {
throw new Error('This script is designed to run in CI. If you want to test it, set the ' +
`following env vars: \`CI, GITHUB_TOKEN, GITHUB_REPOSITORY, RELEASE_PR_NUMBER\``)
}

const [owner, repo] = GITHUB_REPOSITORY.split('/')
const github = new Octokit({ auth: GITHUB_TOKEN })
github.repo = { owner, repo }

const { data: pr } = await github.rest.pulls.get({
...github.repo,
pull_number: RELEASE_PR_NUMBER,
})

const [release, workspaces = []] = await getPrReleases(pr)

const RELEASE_OMIT_PRERELEASE = '> NOT FOR PRERELEASE'
const RELEASE_OMIT_WORKSPACES = 'Publish workspaces'
const releaseItems = (await getReleaseProcess({ owner, repo }))
.filter((item) => {
if (release.prerelease && item.includes(RELEASE_OMIT_PRERELEASE)) {
return false
}

if (!workspaces.length && item.includes(RELEASE_OMIT_WORKSPACES)) {
return false
}

return true
})
.map((item, index) => item.replace('<STEP_INDEX>', index + 1))

log(
`Filtered ${releaseItems.length} release process items:\n`,
releaseItems.map(r => r.split('\n')[0].replace('- [ ] ', '')).join(', ')
)

const releaseTitle = `### Release Checklist for ${release.tag}`
const releaseChecklist = releaseItems
.join('\n\n')
.replace(/<PR-NUMBER>/g, RELEASE_PR_NUMBER)
.replace(/<RELEASE-BRANCH>/g, pr.head.ref)
.replace(/<BASE-BRANCH>/g, pr.base.ref)
.replace(/<MAJOR>/g, release.major)
.replace(/<X\.Y\.Z>/g, release.version)
.replace(/<GITHUB-RELEASE-LINK>/g, release.url)
.replace(/<PUBLISH-FLAGS>/g, release.flags)
.replace(/^(\s*\S.*)(-w <WS-PKG-N>)$/gm, workspaces.map(w => `$1${w.flags}`).join('\n'))
.trim()

await appendToComment({
github,
commentId: RELEASE_COMMENT_ID,
title: releaseTitle,
body: releaseChecklist,
})

if (!RELEASE_COMMENT_ID) {
console.log(releaseChecklist)
}
}

main(process.env)
// This is part of the release CI and is for posting a release manager
// comment to the issue but we dont want it to ever fail the workflow so
// just log but dont set the error code
.catch(err => console.error(err))
68 changes: 68 additions & 0 deletions bin/release-please.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#!/usr/bin/env node

const core = require('@actions/core')
const main = require('../lib/release-please/index.js')

const dryRun = !process.env.CI
const [branch, eventName] = process.argv.slice(2)

const debugPr = (val) => {
if (dryRun) {
console.log('PR:', val.title.toString())
console.log('='.repeat(40))
console.log(val.body.toString())
console.log('='.repeat(40))
for (const update of val.updates.filter(u => u.updater.changelogEntry)) {
console.log('CHANGELOG:', update.path)
console.log('-'.repeat(40))
console.log(update.updater.changelogEntry)
console.log('-'.repeat(40))
}
for (const update of val.updates.filter(u => u.updater.rawContent)) {
console.log('package:', update.path)
console.log('-'.repeat(40))
console.log(JSON.parse(update.updater.rawContent).name)
console.log(JSON.parse(update.updater.rawContent).version)
console.log('-'.repeat(40))
}
}
}

main({
token: process.env.GITHUB_TOKEN,
repo: process.env.GITHUB_REPOSITORY,
dryRun,
branch,
force: eventName === 'workflow_dispatch',
}).then(({ pr, release, releases }) => {
if (pr) {
debugPr(pr)
core.setOutput('pr', JSON.stringify(pr))
core.setOutput('pr-branch', pr.headBranchName)
core.setOutput('pr-number', pr.number)
core.setOutput('pr-sha', pr.sha)
}

if (release) {
core.setOutput('release', JSON.stringify(release))
core.setOutput('release-path', release.path)
core.setOutput('release-version', release.version)
core.setOutput('release-tag', release.tagName)
core.setOutput('release-url', release.url)
}

if (releases) {
core.setOutput('releases', JSON.stringify(releases))
core.setOutput('release-flags', JSON.stringify(releases.map((r) => {
return r.path === '.' ? '-iwr' : `-w ${r.path}`
})))
}

return null
}).catch(err => {
if (dryRun) {
console.error(err)
} else {
core.setFailed(`failed: ${err}`)
}
})
4 changes: 2 additions & 2 deletions lib/apply/apply-files.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
const fs = require('@npmcli/fs')
const fs = require('fs/promises')
const log = require('proc-log')
const { rmEach, parseEach } = require('../util/files.js')

const run = async (dir, files, options) => {
const { rm = [], add = {} } = files
const { rm, add } = files

log.verbose('apply-files', 'rm', rm)
await rmEach(dir, rm, options, (f) => fs.rm(f))
2 changes: 1 addition & 1 deletion lib/apply/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const run = require('../index.js')

module.exports = (root, content) => run(root, content, [
module.exports = (root) => run(root, [
require('./apply-files.js'),
require('./apply-version.js'),
])
9 changes: 5 additions & 4 deletions lib/check/check-apply.js
Original file line number Diff line number Diff line change
@@ -2,13 +2,14 @@ const log = require('proc-log')
const { relative, basename } = require('path')
const { rmEach, parseEach } = require('../util/files.js')
const { partition } = require('lodash')
const localeCompare = require('@isaacs/string-locale-compare')('en')

const solution = 'npx template-oss-apply --force'

const run = async (type, dir, files, options) => {
const res = []
const rel = (f) => relative(options.root, f)
const { add: addFiles = {}, rm: rmFiles = [] } = files
const { add: addFiles, rm: rmFiles } = files

const rm = await rmEach(dir, rmFiles, options, (f) => rel(f))
const [add, update] = partition(await parseEach(dir, addFiles, options, async (p) => {
@@ -28,7 +29,7 @@ const run = async (type, dir, files, options) => {
if (rm.length) {
res.push({
title: `The following ${type} files need to be deleted:`,
body: rm,
body: rm.sort(localeCompare),
solution,
})
}
@@ -37,13 +38,13 @@ const run = async (type, dir, files, options) => {
if (add.length) {
res.push({
title: `The following ${type} files need to be added:`,
body: add,
body: add.sort(localeCompare),
solution,
})
}

log.verbose('check-apply', 'update', update)
res.push(...update.map(({ file, diff }) => ({
res.push(...update.sort((a, b) => localeCompare(a.file, b.file)).map(({ file, diff }) => ({
title: `The ${type} file ${basename(file)} needs to be updated:`,
body: [`${file}\n${'='.repeat(40)}\n${diff}`],
solution,
12 changes: 6 additions & 6 deletions lib/check/check-changelog.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const fs = require('@npmcli/fs')
const { EOL } = require('os')
const fs = require('fs/promises')
const { existsSync } = require('fs')
const { join, relative } = require('path')

const run = async ({ root, path }) => {
@@ -8,15 +8,15 @@ const run = async ({ root, path }) => {
// make this glob for possible matches
const changelog = join(path, 'CHANGELOG.md')

if (await fs.exists(changelog)) {
if (existsSync(changelog)) {
const content = await fs.readFile(changelog, { encoding: 'utf8' })
const mustStart = `# Changelog${EOL}${EOL}#`
if (!content.startsWith(mustStart)) {
const mustStart = /^#\s+Changelog\r?\n\r?\n#/
if (!mustStart.test(content)) {
return {
title: `The ${relative(root, changelog)} is incorrect:`,
body: [
'The changelog should start with',
`"${mustStart}"`,
`"# Changelog\n\n#"`,
],
solution: 'reformat the changelog to have the correct heading',
}
8 changes: 4 additions & 4 deletions lib/check/check-gitignore.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const log = require('proc-log')
const { EOL } = require('os')
const { resolve, relative, basename } = require('path')
const fs = require('@npmcli/fs')
const fs = require('fs/promises')
const { existsSync } = require('fs')
const git = require('@npmcli/git')

const NAME = 'check-gitignore'
@@ -18,7 +18,7 @@ const run = async ({ root, path, config }) => {
// use the root to detect a git repo but the project directory (path) for the
// ignore check
const ignoreFile = resolve(path, '.gitignore')
if (!await git.is({ cwd: root }) || !await fs.exists(ignoreFile)) {
if (!await git.is({ cwd: root }) || !existsSync(ignoreFile)) {
log.verbose(NAME, 'no git or no gitignore')
return null
}
@@ -48,7 +48,7 @@ const run = async ({ root, path, config }) => {

const ignores = (await fs.readFile(ignoreFile))
.toString()
.split(EOL)
.split(/\r?\n/)
.filter((l) => l && !l.trim().startsWith('#'))

const relIgnore = relativeToRoot(ignoreFile)
2 changes: 1 addition & 1 deletion lib/check/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const run = require('../index.js')

module.exports = (root, content) => run(root, content, [
module.exports = (root) => run(root, [
require('./check-apply.js'),
require('./check-required.js'),
require('./check-unwanted.js'),
319 changes: 202 additions & 117 deletions lib/config.js
Original file line number Diff line number Diff line change
@@ -1,106 +1,171 @@
const { relative, dirname, join, posix, win32 } = require('path')
const log = require('proc-log')
const { uniq, defaults } = require('lodash')
const { relative, dirname, join, extname, posix, win32 } = require('path')
const { defaults, pick, omit, uniq } = require('lodash')
const semver = require('semver')
const parseCIVersions = require('./util/parse-ci-versions.js')
const getGitUrl = require('./util/get-git-url.js')
const { name: NAME, version: LATEST_VERSION } = require('../package.json')
const gitignore = require('./util/gitignore.js')
const { withArrays } = require('./util/merge.js')
const { FILE_KEYS, parseConfig: parseFiles, getAddedFiles } = require('./util/files.js')

const CONFIG_KEY = 'templateOSS'
const getPkgConfig = (pkg) => pkg[CONFIG_KEY] || {}

const getContent = (contentPath) => {
if (typeof contentPath === 'string') {
return defaults(require(contentPath), {
sourceDir: dirname(require.resolve(contentPath)),
})
} else {
// allow passing in content directly for tests
return contentPath
const { name: NAME, version: LATEST_VERSION } = require('../package.json')
const MERGE_KEYS = [...FILE_KEYS, 'defaultContent', 'content']
const DEFAULT_CONTENT = require.resolve(NAME)

const merge = withArrays('branches', 'distPaths', 'allowPaths', 'ignorePaths')

const makePosix = (v) => v.split(win32.sep).join(posix.sep)
const deglob = (v) => makePosix(v).replace(/[/*]+$/, '')
const posixDir = (v) => `${v === '.' ? '' : deglob(v).replace(/\/$/, '')}${posix.sep}`
const posixGlob = (str) => `${posixDir(str)}**`

const getCmdPath = (key, { rootConfig, defaultConfig, isRoot, path, root }) => {
// Make a path relative from a workspace to the root if we are in a workspace
const wsToRoot = (p) => isRoot ? p : makePosix(join(relative(path, root), p))

const rootPath = rootConfig[key]
const defaultPath = defaultConfig[key]
const isLocal = rootPath && rootPath !== defaultPath

return {
isLocal,
root: !isLocal ? defaultPath : `node ${rootPath}`,
local: !isLocal ? defaultPath : `node ${wsToRoot(rootPath)}`,
}
}

// falsy means no content of this type
const getFiles = (config, content) => config ? content : null
const getFileKeys = (files) => files ? Object.keys(files.add || {}) : []
const negatePath = (p) => {
// XXX: this negates the first part of each path for the gitignore
// files. it might make sense to negate more specific portions of the
// path for some paths like workspaces. so instead of ignoring !/workspaces
// it would only ignore !/workspaces/a, !/workspaces/b, etc
const [first, ...parts] = p.split(posix.sep)
const isDir = parts.length > 0
return `!${posix.sep}${first}${isDir ? posix.sep : ''}`
const mergeConfigs = (...configs) => {
const mergedConfig = merge(...configs.map(c => pick(c, MERGE_KEYS)))
return defaults(mergedConfig, {
defaultContent: DEFAULT_CONTENT,
// allow all file types by default
...FILE_KEYS.reduce((acc, key) => {
acc[key] = true
return acc
}, {}),
})
}

const makePosix = (str) => str.split(win32.sep).join(posix.sep)
const readContentPath = (path) => {
if (!path) {
return {}
}

const getConfig = async ({
pkgs,
workspaces,
let content = {}
const index = extname(path) === '.js' ? path : join(path, 'index.js')
const dir = dirname(index)

try {
content = require(index)
} catch {
// its ok if this fails since the content dir
// might only be to provide other files. the
// index.js is optional
}

return { content, dir }
}

const getConfig = (path, rawConfig) => {
const config = omit(readContentPath(path).content, FILE_KEYS)
return merge(config, rawConfig ? omit(rawConfig, FILE_KEYS) : {})
}

const getFiles = (path, rawConfig) => {
const { content, dir } = readContentPath(path)
if (!dir) {
return []
}
return [parseFiles(pick(content, FILE_KEYS), dir, pick(rawConfig, FILE_KEYS)), dir]
}

const getFullConfig = async ({
// the path to the root of the repo
root,
// the path to the package being operated on
// this is the same as root when operating on the root
path,
pkg,
// default content path is looked up via require.resolve
// so use the name of this module since package.json#main
// points to the content dir
content: contentPath = NAME,
config: {
rootRepo,
rootModule,
workspaceRepo,
workspaceModule,
version,
...pkgConfig // this includes config merged in from root
},
// the full contents of the package.json for this package
pkgJson,
// an array of all package info {pkgJson,path,config}[]
pkgs,
// an array of all workspaces in this repo
workspaces,
// the config from the package.json in the root
rootConfig: _rootConfig,
// the config from the package.json being operated on
pkgConfig: _pkgConfig,
}) => {
const isRoot = root === path
const isLatest = version === LATEST_VERSION
const isDogFood = pkg.name === NAME
const isWorkspace = !isRoot
const isMono = !!workspaces.length
const isRootMono = isRoot && isMono

const isLatest = _pkgConfig.version === LATEST_VERSION
const isDogFood = pkgJson.name === NAME
const isForce = process.argv.includes('--force')
const rawPkgConfig = getPkgConfig(pkg)

// this is written to ci yml files so it needs to always use posix
const pkgRelPath = makePosix(relative(root, path))
const gitUrl = await getGitUrl(root)
// 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(_rootConfig, _pkgConfig)

const {
rootRepo: rootRepoContent,
rootModule: rootModuleContent,
workspaceRepo: workspaceRepoContent,
workspaceModule: workspaceModuleContent,
...baseContent
} = getContent(contentPath)

let repoFiles, moduleFiles
const ignorePaths = []

if (isRoot) {
repoFiles = getFiles(rootRepo, rootRepoContent)
moduleFiles = getFiles(rootModule, rootModuleContent)
ignorePaths.push(
// allow workspace paths if they are set, this is directly from
// map-workspaces so normalize to posix paths for gitignore
...workspaces.map((p) => makePosix(relative(root, p))),
// allow both the repo and module files since this is the root
...getFileKeys(repoFiles),
...getFileKeys(moduleFiles),
// allow all workspace repo level files
...pkgs.filter((p) => p.path !== path).flatMap((p) =>
getFileKeys(getFiles(p.config.workspaceRepo, workspaceRepoContent))
)
)
} else {
repoFiles = getFiles(workspaceRepo, workspaceRepoContent)
moduleFiles = getFiles(workspaceModule, workspaceModuleContent)
// In a workspace gitignores are relative to the workspace dir
// so we should only allow added module files
ignorePaths.push(...getFileKeys(moduleFiles))
}
const defaultConfig = getConfig(DEFAULT_CONTENT)
const [defaultFiles, defaultDir] = getFiles(DEFAULT_CONTENT, mergedConfig)
const useDefault = mergedConfig.defaultContent && defaultConfig

const rootConfig = getConfig(_rootConfig.content, _rootConfig)
const [rootFiles, rootDir] = getFiles(_rootConfig.content, mergedConfig)

// The content config only gets set from the package we are in, it doesn't inherit
// anything from the root
const rootPkgConfig = merge(useDefault, rootConfig)
const pkgConfig = merge(useDefault, getConfig(_pkgConfig.content, _pkgConfig))
const [pkgFiles, pkgDir] = getFiles(mergedConfig.content, mergedConfig)

// Files get merged in from the default content (that template-oss provides) as well
// as any content paths provided from the root or the workspace
const fileDirs = uniq([useDefault && defaultDir, rootDir, pkgDir].filter(Boolean))
const files = merge(useDefault && defaultFiles, rootFiles, pkgFiles)
const repoFiles = isRoot ? files.rootRepo : files.workspaceRepo
const moduleFiles = isRoot ? files.rootModule : files.workspaceModule

const allowRootDirs = [
// Allways allow module files in root or workspaces
...getAddedFiles(moduleFiles),
...isRoot ? [
// in the root allow all repo files
...getAddedFiles(repoFiles),
// and allow all workspace repo level files in the root
...pkgs
.filter(p => p.path !== root && p.config.workspaceRepo !== false)
.flatMap(() => getAddedFiles(files.workspaceRepo)),
] : [],
]

// root only configs
const npmPath = getCmdPath('npm', { rootConfig, defaultConfig, isRoot, path, root })
const npxPath = getCmdPath('npx', { rootConfig, defaultConfig, isRoot, path, root })

// these are written to ci yml files so it needs to always use posix
const pkgPath = makePosix(relative(root, path)) || '.'

// we use the raw paths from the package.json workspaces as ignore patterns in
// some cases. the workspaces passed in have already been run through map workspaces
const workspacePaths = (pkgJson.workspaces || []).map(deglob)

// all derived keys
const derived = {
isRoot,
isWorkspace: !isRoot,
isWorkspace,
// Some files are written to the base of a repo but will
// include configuration for all packages within a monorepo
// For these cases it is helpful to know if we are in a
// monorepo since template-oss might be used only for
// workspaces and not the root or vice versa.
isRootMono,
isMono,
// repo
repoDir: root,
repoFiles,
@@ -110,70 +175,90 @@ const getConfig = async ({
moduleFiles,
applyModule: !!moduleFiles,
// package
pkgName: pkg.name,
pkgNameFs: pkg.name.replace(/\//g, '-').replace(/@/g, ''),
pkgRelPath: pkgRelPath,
pkgPrivate: !!pkg.private,
pkgName: pkgJson.name,
pkgNameFs: pkgJson.name.replace(/\//g, '-').replace(/@/g, ''),
// paths
pkgPath,
pkgDir: posixDir(pkgPath),
pkgGlob: posixGlob(pkgPath),
pkgFlags: isWorkspace ? `-w ${pkgJson.name}` : '',
allFlags: isMono ? '-ws -iwr --if-present' : '',
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,
rootNpmPath: npmPath.root,
localNpmPath: npmPath.local,
rootNpxPath: npxPath.root,
// lockfiles are only present at the root, so this only should be set for
// all workspaces based on the root
lockfile: rootPkgConfig.lockfile,
// gitignore
ignorePaths: [
...gitignore.sort([
...gitignore.allowRootDir(allowRootDirs),
...isRoot && pkgConfig.lockfile ? ['!/package-lock.json'] : [],
...(pkgConfig.allowPaths || []).map((p) => `!${p}`),
...(pkgConfig.ignorePaths || []),
]),
// these cant be sorted since they rely on order
// to allow a previously ignored directoy
...isRoot ? gitignore.allowDir(workspaces.map((p) => makePosix(relative(root, p)))) : [],
],
// 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,
}

// merge the rest of base and pkg content to make the
// full content object
const content = { ...baseContent, ...pkgConfig }
if (pkgConfig.ciVersions) {
let versions = pkgConfig.ciVersions
if (versions === 'latest') {
const defaultVersions = [rootPkgConfig, defaultConfig].find(c => Array.isArray(c.ciVersions))
versions = defaultVersions.ciVersions.slice(-1)
}

// set some defaults on content that can be overwritten unlike
// derived values which are calculated from other config
const contentDefaults = {}
const { targets, engines } = parseCIVersions(versions)

if (content.npmBin && content.npmBin !== baseContent.npmBin) {
// make it relative to each workspace if they did not set the config themselves
if (!rawPkgConfig.npmBin) {
content.npmBin = makePosix(join(relative(path, root), content.npmBin))
}
// a bit of a hack but allow custom node paths or no node path at all
// checks if the first thing has node somewhere in it and if it doesnt
// puts a system node in front of the script
const execPaths = content.npmBin.split(' ')[0].split(posix.sep)
if (execPaths.every(p => p !== 'node')) {
content.npmBin = `node ${content.npmBin}`
// get just a list of the target versions (not ranges)
// these are used for the node version when doing engines checks
// since we want to test in the lowest version of each major
let targetVersions = targets.filter(t => semver.valid(t))
// if the versions are all ranges then convert them to the lower bound of each range
if (!targetVersions.length) {
targetVersions = targets.filter(t => semver.validRange(t)).map(t => {
return new semver.Range(t).set[0][0].semver.version
})
}
}
if (Array.isArray(content.ciVersions)) {
const parsed = parseCIVersions(content.ciVersions)
contentDefaults.engines = parsed.engines
content.ciVersions = parsed.targets
log.verbose('config ci', parsed)

derived.ciVersions = targets
derived.baseCiVersions = targetVersions
derived.engines = pkgConfig.engines || engines
}

const gitUrl = await getGitUrl(root)
if (gitUrl) {
contentDefaults.repository = {
derived.repository = {
type: 'git',
url: gitUrl,
...(pkgRelPath ? { directory: pkgRelPath } : {}),
...(!isRoot ? { directory: pkgPath } : {}),
}
}

contentDefaults.ignorePaths = uniq(
[...ignorePaths, ...(content.distPaths || [])].map(negatePath)
).sort()

log.verbose('config', 'defaults', contentDefaults)

return {
...defaults(content, contentDefaults),
...pkgConfig,
...derived,
}
}

module.exports = getConfig
module.exports = getFullConfig
module.exports.getPkgConfig = getPkgConfig
5 changes: 5 additions & 0 deletions lib/content/CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
All interactions in this repo are covered by the [npm Code of
Conduct](https://docs.npmjs.com/policies/conduct)

The npm cli team may, at its own discretion, moderate, remove, or edit
any interactions such as pull requests, issues, and comments.
29 changes: 29 additions & 0 deletions lib/content/_job-matrix.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: {{ jobName }} - $\{{ matrix.platform.name }} - $\{{ matrix.node-version }}
if: github.repository_owner == 'npm'
strategy:
fail-fast: false
matrix:
platform:
- name: Linux
os: ubuntu-latest
shell: bash
{{#if macCI}}
- name: macOS
os: macos-latest
shell: bash
{{/if}}
{{#if windowsCI}}
- name: Windows
os: windows-latest
shell: cmd
{{/if}}
node-version:
{{#each ciVersions}}
- {{ . }}
{{/each}}
runs-on: $\{{ matrix.platform.os }}
defaults:
run:
shell: $\{{ matrix.platform.shell }}
steps:
{{> stepsSetup jobIsMatrix=true }}
8 changes: 8 additions & 0 deletions lib/content/_job.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
name: {{ jobName }}
if: github.repository_owner == 'npm' {{~#if jobIf}} && {{{ jobIf }}}{{/if}}
runs-on: ubuntu-latest
defaults:
run:
shell: bash
steps:
{{> stepsSetup }}
30 changes: 30 additions & 0 deletions lib/content/_on-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
workflow_dispatch:
pull_request:
{{#if isWorkspace}}
paths:
- {{ pkgGlob }}
{{/if}}
{{#if isRootMono}}
paths-ignore:
{{#each workspaceGlobs}}
- {{ . }}
{{/each}}
{{/if}}
push:
branches:
{{#each branches}}
- {{ . }}
{{/each}}
{{#if isWorkspace}}
paths:
- {{ pkgGlob }}
{{/if}}
{{#if isRootMono}}
paths-ignore:
{{#each workspaceGlobs}}
- {{ . }}
{{/each}}
{{/if}}
schedule:
# "At 09:00 UTC (02:00 PT) on Monday" https://crontab.guru/#0_9_*_*_1
- cron: "0 9 * * 1"
2 changes: 2 additions & 0 deletions lib/content/_step-audit.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- name: Run Audit
run: {{ rootNpmPath }} audit
54 changes: 54 additions & 0 deletions lib/content/_step-checks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{{#if jobCheck.sha}}
- name: Get Workflow Job
uses: actions/github-script@v6
{{#if jobCheck.if}}if: {{ jobCheck.if }}{{/if}}
id: check-output
env:
JOB_NAME: "{{#if jobName}}{{ jobName }}{{else}}{{ jobCheck.name }}{{/if}}"
MATRIX_NAME: "{{#if jobIsMatrix}} - $\{{ matrix.platform.name }} - $\{{ matrix.node-version }}{{/if}}"
with:
script: |
const { owner, repo } = context.repo
const { data } = await github.rest.actions.listJobsForWorkflowRun({
owner,
repo,
run_id: context.runId,
per_page: 100
})
const jobName = process.env.JOB_NAME + process.env.MATRIX_NAME
const job = data.jobs.find(j => j.name.endsWith(jobName))
const jobUrl = job?.html_url
const shaUrl = `${context.serverUrl}/${owner}/${repo}/commit/{{ jobCheck.sha }}`
let summary = `This check is assosciated with ${shaUrl}\n\n`
if (jobUrl) {
summary += `For run logs, click here: ${jobUrl}`
} else {
summary += `Run logs could not be found for a job with name: "${jobName}"`
}
return { summary }
{{/if}}
- name: {{#if jobCheck.sha}}Create{{else}}Conclude{{/if}} Check
uses: LouisBrunner/checks-action@v1.3.1
{{#if jobCheck.sha}}
id: check
{{#if jobCheck.if}}if: {{ jobCheck.if }}{{/if}}
{{else}}
if: always()
{{/if}}
with:
token: $\{{ secrets.GITHUB_TOKEN }}
{{#if jobCheck.sha}}
status: {{#if jobCheck.status}}{{ jobCheck.status }}{{else}}in_progress{{/if}}
name: {{#if jobCheck.name}}{{ jobCheck.name }}{{else}}{{ jobName }}{{/if}}{{#if jobIsMatrix}} - $\{{ matrix.platform.name }} - $\{{ matrix.node-version }}{{/if}}
sha: {{ jobCheck.sha }}
output: $\{{ steps.check-output.outputs.result }}
{{else}}
conclusion: {{#if jobCheck.status}}{{ jobCheck.status }}{{else}}$\{{ job.status }}{{/if}}
check_id: {{#if jobCheck.id}}{{ jobCheck.id }}{{else}}$\{{ steps.check.outputs.check_id }}{{/if}}
{{/if}}
2 changes: 2 additions & 0 deletions lib/content/_step-deps.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- name: Install Dependencies
run: {{ rootNpmPath }} i --ignore-scripts --no-audit --no-fund {{~#if jobDepFlags}} {{ jobDepFlags }}{{/if}}
12 changes: 12 additions & 0 deletions lib/content/_step-git.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
- name: Checkout
uses: actions/checkout@v3
{{#if jobCheckout}}
with:
{{#each jobCheckout}}
{{ @key }}: {{ this }}
{{/each}}
{{/if}}
- name: Setup Git User
run: |
git config --global user.email "npm-cli+bot@github.com"
git config --global user.name "npm CLI robot"
4 changes: 4 additions & 0 deletions lib/content/_step-lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
- name: Lint
run: {{ rootNpmPath }} run lint --ignore-scripts {{~#if jobRunFlags}} {{ jobRunFlags }}{{/if}}
- name: Post Lint
run: {{ rootNpmPath }} run postlint --ignore-scripts {{~#if jobRunFlags}} {{ jobRunFlags }}{{/if}}
21 changes: 12 additions & 9 deletions lib/content/setup-node.yml → lib/content/_step-node.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
- uses: actions/setup-node@v3
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: {{#if useMatrix}}$\{{ matrix.node-version }}{{else}}{{#each ciVersions}}{{#if @last}}{{.}}{{/if}}{{/each}}{{/if}}
node-version: {{#if jobIsMatrix}}$\{{ matrix.node-version }}{{else}}{{ last ciVersions }}{{/if}}
{{#if lockfile}}
cache: npm
{{/if}}
{{#if useMatrix}}
- name: Update to workable npm (windows)
{{#if updateNpm}}
{{#if jobIsMatrix}}
- 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: |
@@ -15,14 +17,15 @@
node lib/npm.js install --no-fund --no-audit -g ..\npm-7.5.4.tgz
cd ..
rmdir /s /q package
- name: Update npm to 7
# If we do test on npm 10 it needs npm7
- name: Install npm@7
if: startsWith(matrix.node-version, '10.')
run: npm i --prefer-online --no-fund --no-audit -g npm@7
- name: Update npm to latest
- name: Install npm@latest
if: $\{{ !startsWith(matrix.node-version, '10.') }}
{{else}}
- name: Update npm to latest
- name: Install npm@latest
{{/if}}
run: npm i --prefer-online --no-fund --no-audit -g npm@latest
- run: npm -v
- name: npm Version
run: npm -v
{{/if}}
4 changes: 4 additions & 0 deletions lib/content/_step-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
- name: Add Problem Matcher
run: echo "::add-matcher::.github/matchers/tap.json"
- name: Test
run: {{ rootNpmPath }} test --ignore-scripts {{~#if jobRunFlags}} {{ jobRunFlags }}{{/if}}
6 changes: 6 additions & 0 deletions lib/content/_steps-setup.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{{~#if jobCheck}}{{> stepChecks }}{{/if}}
{{~#unless jobSkipSetup}}
{{> stepGit }}
{{> stepNode }}
{{> stepDeps }}
{{/unless}}
12 changes: 4 additions & 8 deletions lib/content/audit.yml
Original file line number Diff line number Diff line change
@@ -3,14 +3,10 @@ name: Audit
on:
workflow_dispatch:
schedule:
# "At 01:00 on Monday" https://crontab.guru/#0_1_*_*_1
- cron: "0 1 * * 1"
# "At 08:00 UTC (01:00 PT) on Monday" https://crontab.guru/#0_8_*_*_1
- cron: "0 8 * * 1"

jobs:
audit:
runs-on: ubuntu-latest
steps:
{{> setupGit}}
{{> setupNode}}
- run: npm i --ignore-scripts --no-audit --no-fund --package-lock
- run: npm audit
{{> job jobName="Audit Dependencies" jobDepFlags="--package-lock" }}
{{> stepAudit }}
31 changes: 31 additions & 0 deletions lib/content/ci-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@

name: CI - Release

on:
workflow_call:
inputs:
ref:
required: true
type: string
check-sha:
required: true
type: string

jobs:
lint-all:
{{> job
jobName="Lint All"
jobCheck=(obj sha="${{ inputs.check-sha }}")
jobCheckout=(obj ref="${{ inputs.ref }}")
}}
{{> stepLint jobRunFlags=allFlags }}
{{> stepChecks jobCheck=true }}

test-all:
{{> jobMatrix
jobName="Test All"
jobCheck=(obj sha="${{ inputs.check-sha }}")
jobCheckout=(obj ref="${{ inputs.ref }}")
}}
{{> stepTest jobRunFlags=allFlags }}
{{> stepChecks jobCheck=true }}
67 changes: 15 additions & 52 deletions lib/content/ci.yml
Original file line number Diff line number Diff line change
@@ -1,59 +1,22 @@
name: CI {{~#if isWorkspace}} - {{pkgName}}{{/if}}
name: CI {{~#if isWorkspace}} - {{ pkgName }}{{/if}}

on:
workflow_dispatch:
pull_request:
branches:
- '*'
{{#if pkgRelPath}}
paths:
- {{pkgRelPath}}/**
{{/if}}
push:
branches:
{{#each branches}}
- {{.}}
{{/each}}
{{#if pkgRelPath}}
paths:
- {{pkgRelPath}}/**
{{/if}}
schedule:
# "At 02:00 on Monday" https://crontab.guru/#0_2_*_*_1
- cron: "0 2 * * 1"
{{> onCi }}

jobs:
engines:
{{> jobMatrix
jobName="Engines"
jobDepFlags="--engines-strict"
macCI=false
windowsCI=false
ciVersions=baseCiVersions
}}

lint:
runs-on: ubuntu-latest
steps:
{{> setupGit}}
{{> setupNode}}
- run: npm i --ignore-scripts --no-audit --no-fund
- run: npm run lint {{~#if isWorkspace}} -w {{pkgName}}{{/if}}
{{> job jobName="Lint" }}
{{> stepLint jobRunFlags=pkgFlags }}

test:
strategy:
fail-fast: false
matrix:
node-version:
{{#each ciVersions}}
- {{.}}
{{/each}}
platform:
- os: ubuntu-latest
shell: bash
- os: macos-latest
shell: bash
{{#if windowsCI}}
- os: windows-latest
shell: cmd
{{/if}}
runs-on: $\{{ matrix.platform.os }}
defaults:
run:
shell: $\{{ matrix.platform.shell }}
steps:
{{> setupGit}}
{{> setupNode useMatrix=true}}
- run: npm i --ignore-scripts --no-audit --no-fund
- run: npm test --ignore-scripts {{~#if isWorkspace}} -w {{pkgName}}{{/if}}
{{> jobMatrix jobName="Test" }}
{{> stepTest jobRunFlags=pkgFlags }}
31 changes: 12 additions & 19 deletions lib/content/codeql-analysis.yml
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
name: "CodeQL"
name: CodeQL

on:
push:
branches:
{{#each branches}}
- {{.}}
- {{ . }}
{{/each}}
pull_request:
# The branches below must be a subset of the branches above
branches:
{{#each branches}}
- {{.}}
- {{ . }}
{{/each}}
schedule:
# "At 03:00 on Monday" https://crontab.guru/#0_3_*_*_1
- cron: "0 3 * * 1"
# "At 10:00 UTC (03:00 PT) on Monday" https://crontab.guru/#0_10_*_*_1
- cron: "0 10 * * 1"

jobs:
analyze:
@@ -24,17 +23,11 @@ jobs:
actions: read
contents: read
security-events: write

strategy:
fail-fast: false
matrix:
language: [javascript]

steps:
{{> setupGit}}
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
with:
languages: $\{{ matrix.language }}
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1
{{> stepGit }}
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: javascript
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
2 changes: 1 addition & 1 deletion lib/content/commitlintrc.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
'type-enum': [2, 'always', [{{#each changelogTypes}}'{{type}}'{{#unless @last}}, {{/unless}}{{/each}}]],
'type-enum': [2, 'always', [{{{ join (quote (pluck changelogTypes "type")) }}}]],
'header-max-length': [2, 'always', 80],
'subject-case': [0, 'always', ['lower-case', 'sentence-case', 'start-case']],
},
4 changes: 2 additions & 2 deletions lib/content/dependabot.yml
Original file line number Diff line number Diff line change
@@ -2,12 +2,12 @@ version: 2

updates:
- package-ecosystem: npm
directory: "/"
directory: {{ pkgDir }}
schedule:
interval: daily
allow:
- dependency-type: direct
versioning-strategy: increase-if-necessary
versioning-strategy: {{ dependabot }}
commit-message:
prefix: deps
prefix-development: chore
9 changes: 9 additions & 0 deletions lib/content/eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
'use strict'

const { readdirSync: readdir } = require('fs')

const localConfigs = readdir(__dirname)
@@ -6,6 +8,13 @@ const localConfigs = readdir(__dirname)

module.exports = {
root: true,
{{#if workspaceGlobs}}
ignorePatterns: [
{{#each workspaceGlobs}}
'{{ . }}',
{{/each}}
],
{{/if}}
extends: [
'@npmcli',
...localConfigs,
15 changes: 1 addition & 14 deletions lib/content/gitignore
Original file line number Diff line number Diff line change
@@ -2,19 +2,6 @@
/*

# keep these
!/.eslintrc.local.*
!**/.gitignore
!/docs/
!/tap-snapshots/
!/test/
!/map.js
!/scripts/
!/README*
!/LICENSE*
!/CHANGELOG*
{{#each ignorePaths}}
{{.}}
{{ . }}
{{/each}}
{{#if lockfile}}
!/package-lock.json
{{/if}}
97 changes: 82 additions & 15 deletions lib/content/index.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,67 @@
const { name: NAME, version: LATEST_VERSION } = require('../../package.json')

const isPublic = (p) => !p.pkg.private

const sharedRoot = (name) => ({
// release
'.github/workflows/release.yml': {
file: 'release.yml',
filter: isPublic,
},
'.github/workflows/ci-release.yml': {
file: 'ci-release.yml',
filter: isPublic,
},
'.release-please-manifest.json': {
file: 'release-please-manifest.json',
filter: isPublic,
parser: (p) => class extends p.JsonMerge {
comment = null
},
},
'release-please-config.json': {
file: 'release-please-config.json',
filter: isPublic,
parser: (p) => class extends p.JsonMerge {
comment = null
},
},
// ci
'.github/matchers/tap.json': 'tap.json',
[`.github/workflows/ci${name ? `-${name}` : ''}.yml`]: 'ci.yml',
// dependabot
'.github/dependabot.yml': {
file: 'dependabot.yml',
clean: (p) => p.config.isRoot,
// dependabot takes a single top level config file. this parser
// will run for all configured packages and each one will have
// its item replaced in the updates array based on the directory
parser: (p) => class extends p.YmlMerge {
key = 'updates'
id = 'directory'
},
},
'.github/workflows/post-dependabot.yml': {
file: 'post-dependabot.yml',
},
})

// Changes applied to the root of the repo
const rootRepo = {
add: {
'.commitlintrc.js': 'commitlintrc.js',
'.github/workflows/ci.yml': 'ci.yml',
'.github/ISSUE_TEMPLATE/bug.yml': 'bug.yml',
'.github/ISSUE_TEMPLATE/config.yml': 'config.yml',
'.github/CODEOWNERS': 'CODEOWNERS',
'.github/dependabot.yml': 'dependabot.yml',
'.github/workflows/audit.yml': 'audit.yml',
'.github/workflows/codeql-analysis.yml': 'codeql-analysis.yml',
'.github/workflows/post-dependabot.yml': 'post-dependabot.yml',
'.github/workflows/pull-request.yml': 'pull-request.yml',
'.github/workflows/release-please.yml': {
file: 'release-please.yml',
filter: (o) => !o.pkg.private,
},
...sharedRoot(),
},
rm: [
'.github/workflows/release-test.yml',
'.github/workflows/release-please.yml',
],
}

// These are also applied to the root of the repo
@@ -31,6 +75,7 @@ const rootModule = {
'.gitignore': 'gitignore',
'.npmrc': 'npmrc',
'SECURITY.md': 'SECURITY.md',
'CODE_OF_CONDUCT.md': 'CODE_OF_CONDUCT.md',
'package.json': 'pkg.json',
},
rm: [
@@ -41,12 +86,12 @@ const rootModule = {
// Changes for each workspace but applied to the root of the repo
const workspaceRepo = {
add: {
'.github/workflows/release-please-{{pkgNameFs}}.yml': {
file: 'release-please.yml',
filter: (o) => !o.pkg.private,
},
'.github/workflows/ci-{{pkgNameFs}}.yml': 'ci.yml',
...sharedRoot('{{ pkgNameFs }}'),
},
rm: [
// These are the old release please files that should be removed now
'.github/workflows/release-please-{{ pkgNameFs }}.yml',
],
}

// Changes for each workspace but applied to the relative workspace dir
@@ -69,11 +114,33 @@ module.exports = {
workspaceRepo,
workspaceModule,
windowsCI: true,
macCI: true,
branches: ['main', 'latest'],
distPaths: ['bin/', 'lib/'],
ciVersions: ['12.13.0', '12.x', '14.15.0', '14.x', '16.0.0', '16.x'],
releaseBranches: [],
distPaths: [
'bin/',
'lib/',
],
allowPaths: [
'/bin/',
'/lib/',
'/.eslintrc.local.*',
'**/.gitignore',
'/docs/',
'/tap-snapshots/',
'/test/',
'/map.js',
'/scripts/',
'/README*',
'/LICENSE*',
'/CHANGELOG*',
],
ignorePaths: [],
ciVersions: ['14.17.0', '14.x', '16.13.0', '16.x', '18.0.0', '18.x'],
lockfile: false,
npmBin: 'npm',
npm: 'npm',
npx: 'npx',
dependabot: 'increase-if-necessary',
unwantedPackages: [
'eslint',
'eslint-plugin-node',
2 changes: 1 addition & 1 deletion lib/content/npmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
package-lock={{lockfile}}
package-lock={{ lockfile }}
52 changes: 34 additions & 18 deletions lib/content/pkg.json
Original file line number Diff line number Diff line change
@@ -1,31 +1,47 @@
{
"author": "GitHub Inc.",
"files": {{{json distPaths}}},
"files": {{{ json distPaths }}},
"scripts": {
"lint": "eslint \"**/*.js\"",
"postlint": "template-oss-check",
"template-oss-apply": "template-oss-apply --force",
"lintfix": "{{npmBin}} run lint -- --fix",
"preversion": "{{npmBin}} test",
{{#if pkgPrivate}}
"postversion": "git push origin --follow-tags",
{{else}}
"postversion": "{{npmBin}} publish",
"prepublishOnly": "git push origin --follow-tags",
{{/if}}
"lintfix": "{{ localNpmPath }} run lint -- --fix",
"snap": "tap",
"test": "tap",
"posttest": "{{npmBin}} run lint",
"template-copy": {{{del}}},
"lint:fix": {{{del}}}
"posttest": "{{ localNpmPath }} run lint",
{{#if isRootMono}}
"test-all": "{{ localNpmPath }} run test {{ allFlags }}",
"lint-all": "{{ localNpmPath }} run lint {{ allFlags }}",
{{/if}}
"template-copy": {{{ del }}},
"lint:fix": {{{ del }}},
"preversion": {{{ del }}},
"postversion": {{{ del }}},
"prepublishOnly": {{{ del }}},
"postpublish": {{{ del }}}
},
"repository": {{#if repository}}{{{json repository}}}{{else}}{{{del}}}{{/if}},
"repository": {{#if repository}}{{{ json repository }}}{{else}}{{{ del }}}{{/if}},
"engines": {
"node": {{{json engines}}}
{{#if engines}}
"node": {{{ json engines }}}
{{/if}}
},
{{{json __CONFIG_KEY__}}}: {
"version": {{#if isDogFood}}{{{del}}}{{else}}{{{json __VERSION__}}}{{/if}}
{{{ json __CONFIG_KEY__ }}}: {
"version": {{#if isDogFood}}{{{ del }}}{{else}}{{{ json __VERSION__ }}}{{/if}}
},
"templateVersion": {{{del}}},
"standard": {{{del}}}
"templateVersion": {{{ del }}},
"standard": {{{ del }}},
"tap": {
{{#if workspacePaths}}
"test-ignore": "^({{ join workspacePaths "|" }})/",
{{/if}}
"nyc-arg": [
{{#each workspaceGlobs}}
"--exclude",
"{{ . }}",
{{/each}}
"--exclude",
"tap-snapshots/**"
]
}
}
106 changes: 87 additions & 19 deletions lib/content/post-dependabot.yml
Original file line number Diff line number Diff line change
@@ -1,33 +1,101 @@
name: Post Dependabot Actions
name: Post Dependabot

on:
pull_request

# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions
permissions:
contents: write

jobs:
template-oss-apply:
runs-on: ubuntu-latest
if: github.actor == 'dependabot[bot]'
steps:
{{> setupGit}}
{{> setupNode}}
- name: Dependabot metadata
template-oss:
{{> job
jobName="template-oss"
jobIf="github.actor == 'dependabot[bot]'"
jobCheckout=(obj ref="${{ github.event.pull_request.head.ref }}")
}}
- name: Fetch Dependabot Metadata
id: metadata
uses: dependabot/fetch-metadata@v1.1.1
uses: dependabot/fetch-metadata@v1
with:
github-token: "$\{{ secrets.GITHUB_TOKEN }}"
- name: npm install and commit
if: contains(steps.metadata.outputs.dependency-names, '{{__NAME__}}')
github-token: $\{{ secrets.GITHUB_TOKEN }}

# Dependabot can update multiple directories so we output which directory
# it is acting on so we can run the command for the correct root or workspace
- name: Get Dependabot Directory
if: contains(steps.metadata.outputs.dependency-names, '{{ __NAME__ }}')
id: flags
run: |
dependabot_dir="$\{{ steps.metadata.outputs.directory }}"
if [[ "$dependabot_dir" == "/" ]]; then
echo "::set-output name=workspace::-iwr"
else
# strip leading slash from directory so it works as a
# a path to the workspace flag
echo "::set-output name=workspace::-w ${dependabot_dir#/}"
fi
- name: Apply Changes
if: steps.flags.outputs.workspace
id: apply
run: |
{{ rootNpmPath }} run template-oss-apply $\{{ steps.flags.outputs.workspace }}
if [[ `git status --porcelain` ]]; then
echo "::set-output name=changes::true"
fi
# This only sets the conventional commit prefix. This workflow can't reliably determine
# what the breaking change is though. If a BREAKING CHANGE message is required then
# this PR check will fail and the commit will be amended with stafftools
if [[ "$\{{ steps.dependabot-metadata.outputs.update-type }}" == "version-update:semver-major" ]]; then
prefix='feat!'
else
prefix='chore!'
fi
echo "::set-output name=message::$prefix: postinstall for dependabot template-oss PR"
# This step will fail if template-oss has made any workflow updates. It is impossible
# for a workflow to update other workflows. In the case it does fail, we continue
# and then try to apply only a portion of the changes in the next step
- name: Push All Changes
if: steps.apply.outputs.changes
id: push
continue-on-error: true
env:
GITHUB_TOKEN: $\{{ secrets.GITHUB_TOKEN }}
run: |
gh pr checkout $\{{ github.event.pull_request.number }}
npm install --ignore-scripts --no-audit --no-fund
npm run template-oss-apply
git add .
git commit -am "chore: postinstall for dependabot template-oss PR"
git commit -am "$\{{ steps.apply.outputs.message }}"
git push
npm run lint
# If the previous step failed, then reset the commit and remove any workflow changes
# and attempt to commit and push again. This is helpful because we will have a commit
# with the correct prefix that we can then --amend with @npmcli/stafftools later.
- name: Push All Changes Except Workflows
if: steps.apply.outputs.changes && steps.push-all.outcome == 'failure'
env:
GITHUB_TOKEN: $\{{ secrets.GITHUB_TOKEN }}
run: |
git reset HEAD~
git checkout HEAD -- .github/workflows/
git clean -fd .github/workflows/
git commit -am "$\{{ steps.apply.outputs.message }}"
git push
# Check if all the necessary template-oss changes were applied. Since we continued
# on errors in one of the previous steps, this check will fail if our follow up
# only applied a portion of the changes and we need to followup manually.
#
# Note that this used to run `lint` and `postlint` but that will fail this action
# if we've also shipped any linting changes separate from template-oss. We do
# linting in another action, so we want to fail this one only if there are
# template-oss changes that could not be applied.
- name: Check Changes
if: steps.apply.outputs.changes
run: |
{{ rootNpmPath }} exec --offline $\{{ steps.flags.outputs.workspace }} -- template-oss-check
- name: Fail on Breaking Change
if: steps.apply.outputs.changes && startsWith(steps.apply.outputs.message, 'feat!')
run: |
echo "This PR has a breaking change. Run 'npx -p @npmcli/stafftools gh template-oss-fix'"
echo "for more information on how to fix this with a BREAKING CHANGE footer."
exit 1
25 changes: 11 additions & 14 deletions lib/content/pull-request.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Pull Request Linting
name: Pull Request

on:
pull_request:
@@ -9,17 +9,14 @@ on:
- synchronize

jobs:
check:
name: Check PR Title or Commits
runs-on: ubuntu-latest
steps:
{{> setupGit with=(obj fetch-depth=0)}}
{{> setupNode}}
- name: Install deps
run: npm i -D @commitlint/cli @commitlint/config-conventional
- name: Check commits OR PR title
env:
PR_TITLE: $\{{ github.event.pull_request.title }}
commitlint:
{{> job jobName="Lint Commits" jobCheckout=(obj fetch-depth=0) }}
- name: Run Commitlint on Commits
id: commit
continue-on-error: true
run: |
npx --offline commitlint -V --from origin/main --to $\{{ github.event.pull_request.head.sha }} \
|| echo $PR_TITLE | npx --offline commitlint -V
{{ rootNpxPath }} --offline commitlint -V --from origin/$\{{ github.base_ref }} --to $\{{ github.event.pull_request.head.sha }}
- name: Run Commitlint on PR Title
if: steps.commit.outcome == 'failure'
run: |
echo $\{{ github.event.pull_request.title }} | {{ rootNpxPath }} --offline commitlint -V
13 changes: 13 additions & 0 deletions lib/content/release-please-config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"separate-pull-requests": {{{ del }}},
"plugins": {{#if isMono }}["node-workspace"]{{ else }}{{{ del }}}{{/if}},
"exclude-packages-from-root": true,
"group-pull-request-title-pattern": "chore: release ${version}",
"pull-request-title-pattern": "chore: release${component} ${version}",
"changelog-sections": {{{ json changelogTypes }}},
"packages": {
"{{ pkgPath }}": {
{{#if isRoot}}"package-name": ""{{/if}}
}
}
}
3 changes: 3 additions & 0 deletions lib/content/release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"{{ pkgPath }}": "{{ pkg.version }}"
}
56 changes: 0 additions & 56 deletions lib/content/release-please.yml

This file was deleted.

Loading