@npmcli/template-oss 4.2.0 → 4.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/bin/release-please.js +42 -28
  2. package/lib/config.js +44 -26
  3. package/lib/content/{_setup-job-matrix.yml → _job-matrix.yml} +12 -10
  4. package/lib/content/_job.yml +8 -0
  5. package/lib/content/{_setup-ci-on.yml → _on-ci.yml} +11 -13
  6. package/lib/content/_step-checks.yml +24 -0
  7. package/lib/content/_step-deps.yml +2 -0
  8. package/lib/content/_step-git.yml +12 -0
  9. package/lib/content/_step-lint.yml +4 -0
  10. package/lib/content/{_setup-node.yml → _step-node.yml} +10 -9
  11. package/lib/content/_step-test.yml +4 -0
  12. package/lib/content/_steps-setup.yml +6 -0
  13. package/lib/content/audit.yml +3 -2
  14. package/lib/content/ci-release.yml +31 -0
  15. package/lib/content/ci.yml +6 -8
  16. package/lib/content/codeql-analysis.yml +10 -17
  17. package/lib/content/commitlintrc.js +1 -1
  18. package/lib/content/dependabot.yml +2 -20
  19. package/lib/content/eslintrc.js +3 -3
  20. package/lib/content/gitignore +1 -1
  21. package/lib/content/index.js +34 -21
  22. package/lib/content/npmrc +1 -1
  23. package/lib/content/pkg.json +25 -23
  24. package/lib/content/post-dependabot.yml +55 -11
  25. package/lib/content/pull-request.yml +11 -9
  26. package/lib/content/release-please-config.json +5 -5
  27. package/lib/content/release-please-manifest.json +1 -1
  28. package/lib/content/release.yml +120 -15
  29. package/lib/index.js +9 -12
  30. package/lib/release-please/index.js +26 -5
  31. package/lib/util/files.js +5 -3
  32. package/lib/util/parser.js +73 -16
  33. package/lib/util/template.js +8 -1
  34. package/package.json +1 -1
  35. package/lib/content/_setup-deps.yml +0 -1
  36. package/lib/content/_setup-git.yml +0 -11
  37. package/lib/content/_setup-job.yml +0 -6
  38. package/lib/content/release-please.yml +0 -64
@@ -1,33 +1,49 @@
1
1
  const { name: NAME, version: LATEST_VERSION } = require('../../package.json')
2
2
 
3
- const releasePlease = () => ({
4
- '.github/workflows/release-please.yml': {
5
- file: 'release-please.yml',
6
- filter: (o) => !o.pkg.private,
7
- },
3
+ const isPublic = (p) => !p.pkg.private
4
+
5
+ const sharedRoot = (name) => ({
6
+ // release
8
7
  '.github/workflows/release.yml': {
9
8
  file: 'release.yml',
10
- filter: (o) => !o.pkg.private,
9
+ filter: isPublic,
10
+ },
11
+ '.github/workflows/ci-release.yml': {
12
+ file: 'ci-release.yml',
13
+ filter: isPublic,
11
14
  },
12
15
  '.release-please-manifest.json': {
13
16
  file: 'release-please-manifest.json',
14
- filter: (o) => !o.pkg.private,
15
- parser: (p) => class NoCommentJson extends p.JsonMerge {
17
+ filter: isPublic,
18
+ parser: (p) => class extends p.JsonMerge {
16
19
  comment = null
17
20
  },
18
21
  },
19
22
  'release-please-config.json': {
20
23
  file: 'release-please-config.json',
21
- filter: (o) => !o.pkg.private,
22
- parser: (p) => class NoCommentJson extends p.JsonMerge {
24
+ filter: isPublic,
25
+ parser: (p) => class extends p.JsonMerge {
23
26
  comment = null
24
27
  },
25
28
  },
26
- })
27
-
28
- const tap = (name) => ({
29
+ // ci
29
30
  '.github/matchers/tap.json': 'tap.json',
30
31
  [`.github/workflows/ci${name ? `-${name}` : ''}.yml`]: 'ci.yml',
32
+ // dependabot
33
+ '.github/dependabot.yml': {
34
+ file: 'dependabot.yml',
35
+ clean: (p) => p.config.isRoot,
36
+ // dependabot takes a single top level config file. this parser
37
+ // will run for all configured packages and each one will have
38
+ // its item replaced in the updates array based on the directory
39
+ parser: (p) => class extends p.YmlMerge {
40
+ key = 'updates'
41
+ id = 'directory'
42
+ },
43
+ },
44
+ '.github/workflows/post-dependabot.yml': {
45
+ file: 'post-dependabot.yml',
46
+ },
31
47
  })
32
48
 
33
49
  // Changes applied to the root of the repo
@@ -37,16 +53,14 @@ const rootRepo = {
37
53
  '.github/ISSUE_TEMPLATE/bug.yml': 'bug.yml',
38
54
  '.github/ISSUE_TEMPLATE/config.yml': 'config.yml',
39
55
  '.github/CODEOWNERS': 'CODEOWNERS',
40
- '.github/dependabot.yml': 'dependabot.yml',
41
56
  '.github/workflows/audit.yml': 'audit.yml',
42
57
  '.github/workflows/codeql-analysis.yml': 'codeql-analysis.yml',
43
- '.github/workflows/post-dependabot.yml': 'post-dependabot.yml',
44
58
  '.github/workflows/pull-request.yml': 'pull-request.yml',
45
- ...releasePlease(),
46
- ...tap(),
59
+ ...sharedRoot(),
47
60
  },
48
61
  rm: [
49
62
  '.github/workflows/release-test.yml',
63
+ '.github/workflows/release-please.yml',
50
64
  ],
51
65
  }
52
66
 
@@ -72,12 +86,11 @@ const rootModule = {
72
86
  // Changes for each workspace but applied to the root of the repo
73
87
  const workspaceRepo = {
74
88
  add: {
75
- ...releasePlease(),
76
- ...tap('{{pkgNameFs}}'),
89
+ ...sharedRoot('{{ pkgNameFs }}'),
77
90
  },
78
91
  rm: [
79
92
  // These are the old release please files that should be removed now
80
- '.github/workflows/release-please-{{pkgNameFs}}.yml',
93
+ '.github/workflows/release-please-{{ pkgNameFs }}.yml',
81
94
  ],
82
95
  }
83
96
 
@@ -104,7 +117,6 @@ module.exports = {
104
117
  macCI: true,
105
118
  branches: ['main', 'latest'],
106
119
  releaseBranches: [],
107
- defaultBranch: 'main',
108
120
  distPaths: [
109
121
  'bin/',
110
122
  'lib/',
@@ -128,6 +140,7 @@ module.exports = {
128
140
  lockfile: false,
129
141
  npm: 'npm',
130
142
  npx: 'npx',
143
+ dependabot: 'increase-if-necessary',
131
144
  unwantedPackages: [
132
145
  'eslint',
133
146
  'eslint-plugin-node',
package/lib/content/npmrc CHANGED
@@ -1 +1 @@
1
- package-lock={{lockfile}}
1
+ package-lock={{ lockfile }}
@@ -1,45 +1,47 @@
1
1
  {
2
2
  "author": "GitHub Inc.",
3
- "files": {{{json distPaths}}},
3
+ "files": {{{ json distPaths }}},
4
4
  "scripts": {
5
5
  "lint": "eslint \"**/*.js\"",
6
6
  "postlint": "template-oss-check",
7
7
  "template-oss-apply": "template-oss-apply --force",
8
- "lintfix": "{{localNpmPath}} run lint -- --fix",
9
- "preversion": {{{del}}},
10
- "postversion": {{{del}}},
11
- "prepublishOnly": {{{del}}},
12
- "postpublish": {{{del}}},
8
+ "lintfix": "{{ localNpmPath }} run lint -- --fix",
13
9
  "snap": "tap",
14
10
  "test": "tap",
15
- "posttest": "{{localNpmPath}} run lint",
11
+ "posttest": "{{ localNpmPath }} run lint",
16
12
  {{#if isRootMono}}
17
- "test-all": "{{localNpmPath}} run test -ws -iwr --if-present",
18
- "lint-all": "{{localNpmPath}} run lint -ws -iwr --if-present",
13
+ "test-all": "{{ localNpmPath }} run test {{ allFlags }}",
14
+ "lint-all": "{{ localNpmPath }} run lint {{ allFlags }}",
19
15
  {{/if}}
20
- "template-copy": {{{del}}},
21
- "lint:fix": {{{del}}}
16
+ "template-copy": {{{ del }}},
17
+ "lint:fix": {{{ del }}},
18
+ "preversion": {{{ del }}},
19
+ "postversion": {{{ del }}},
20
+ "prepublishOnly": {{{ del }}},
21
+ "postpublish": {{{ del }}}
22
22
  },
23
- "repository": {{#if repository}}{{{json repository}}}{{else}}{{{del}}}{{/if}},
23
+ "repository": {{#if repository}}{{{ json repository }}}{{else}}{{{ del }}}{{/if}},
24
24
  "engines": {
25
25
  {{#if engines}}
26
- "node": {{{json engines}}}
26
+ "node": {{{ json engines }}}
27
27
  {{/if}}
28
28
  },
29
- {{{json __CONFIG_KEY__}}}: {
30
- "version": {{#if isDogFood}}{{{del}}}{{else}}{{{json __VERSION__}}}{{/if}}
29
+ {{{ json __CONFIG_KEY__ }}}: {
30
+ "version": {{#if isDogFood}}{{{ del }}}{{else}}{{{ json __VERSION__ }}}{{/if}}
31
31
  },
32
- "templateVersion": {{{del}}},
33
- "standard": {{{del}}},
32
+ "templateVersion": {{{ del }}},
33
+ "standard": {{{ del }}},
34
34
  "tap": {
35
- {{#if isRootMono}}
36
- "test-ignore": "^({{#each workspaceGlobs}}{{this}}{{#unless @last}}|{{/unless}}{{/each}})/",
35
+ {{#if workspacePaths}}
36
+ "test-ignore": "^({{ join workspacePaths "|" }})/**",
37
37
  {{/if}}
38
38
  "nyc-arg": [
39
- {{#if isRootMono}}
40
- {{#each workspaceGlobs}}"--exclude", "{{this}}/**",{{/each}}
41
- {{/if}}
42
- "--exclude", "tap-snapshots/**"
39
+ {{#each workspaceGlobs}}
40
+ "--exclude",
41
+ "{{ . }}",
42
+ {{/each}}
43
+ "--exclude",
44
+ "tap-snapshots/**"
43
45
  ]
44
46
  }
45
47
  }
@@ -1,26 +1,70 @@
1
- name: Post Dependabot Actions
1
+ name: Post Dependabot
2
2
 
3
3
  on:
4
4
  pull_request
5
5
 
6
- # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions
7
6
  permissions:
8
7
  contents: write
9
8
 
10
9
  jobs:
11
- template-oss-apply:
12
- {{> setupJob jobIf="github.actor == 'dependabot[bot]'" checkout=(obj ref="${{ github.event.pull_request.head_ref }}")}}
13
- - name: Dependabot metadata
10
+ template-oss:
11
+ {{> job
12
+ jobName="template-oss"
13
+ jobIf="github.actor == 'dependabot[bot]'"
14
+ jobCheckout=(obj ref="${{ github.event.pull_request.head_ref }}")
15
+ }}
16
+ - name: Fetch Dependabot Metadata
14
17
  id: metadata
15
- uses: dependabot/fetch-metadata@v1.1.1
18
+ uses: dependabot/fetch-metadata@v1
16
19
  with:
17
- github-token: "$\{{ secrets.GITHUB_TOKEN }}"
18
- - name: Apply {{__NAME__}} changes and lint
19
- if: contains(steps.metadata.outputs.dependency-names, '{{__NAME__}}')
20
+ github-token: $\{{ secrets.GITHUB_TOKEN }}
21
+
22
+ # Dependabot can update multiple directories so we output which directory
23
+ # it is acting on so we can run the command for the correct root or workspace
24
+ - name: Get Dependabot Directory
25
+ if: contains(steps.metadata.outputs.dependency-names, '{{ __NAME__ }}')
26
+ id: flags
27
+ run: |
28
+ if [[ "$\{{ steps.metadata.outputs.directory }}" == "/" ]]; then
29
+ echo "::set-output name=workspace::-iwr"
30
+ else
31
+ echo "::set-output name=workspace::-w $\{{ steps.metadata.outputs.directory }}"
32
+ fi
33
+
34
+ - name: Apply Changes
35
+ if: steps.flags.outputs.workspace
36
+ id: apply
37
+ run: |
38
+ {{ rootNpmPath }} run template-oss-apply $\{{ steps.flags.outputs.workspace }}
39
+ if [[ `git status --porcelain` ]]; then
40
+ echo "::set-output name=changes::true"
41
+ fi
42
+
43
+ # This step will fail if template-oss has made any workflow updates. It is impossible
44
+ # for a workflow to update other workflows. In the case it does fail, we continue
45
+ # and then try to apply only a portion of the changes in the next step
46
+ - name: Push All Changes
47
+ if: steps.apply.outputs.changes
48
+ id: push
49
+ continue-on-error: true
20
50
  env:
21
51
  GITHUB_TOKEN: $\{{ secrets.GITHUB_TOKEN }}
22
52
  run: |
23
- {{rootNpmPath}} run template-oss-apply
24
53
  git commit -am "chore: postinstall for dependabot template-oss PR"
25
54
  git push
26
- {{rootNpmPath}} run lint
55
+
56
+ - name: Push All Changes Except Workflows
57
+ if: steps.push.outcome == 'failure'
58
+ env:
59
+ GITHUB_TOKEN: $\{{ secrets.GITHUB_TOKEN }}
60
+ run: |
61
+ git reset HEAD~
62
+ git checkout HEAD -- .github/workflows/
63
+ git clean -fd .github/workflows/
64
+ git commit -am "chore: postinstall for dependabot template-oss PR"
65
+ git push
66
+
67
+ - name: Check Changes
68
+ if: steps.apply.outputs.changes
69
+ run: |
70
+ {{ rootNpmPath }} exec --offline $\{{ steps.flags.outputs.workspace }} -- template-oss-check
@@ -1,4 +1,4 @@
1
- name: Pull Request Linting
1
+ name: Pull Request
2
2
 
3
3
  on:
4
4
  pull_request:
@@ -9,12 +9,14 @@ on:
9
9
  - synchronize
10
10
 
11
11
  jobs:
12
- check:
13
- name: Check PR Title or Commits
14
- {{> setupJob checkout=(obj fetch-depth=0)}}
15
- - name: Check commits or PR title
16
- env:
17
- PR_TITLE: $\{{ github.event.pull_request.title }}
12
+ commitlint:
13
+ {{> job jobName="Lint Commits" jobCheckout=(obj fetch-depth=0) }}
14
+ - name: Run Commitlint on Commits
15
+ id: commit
16
+ continue-on-error: true
18
17
  run: |
19
- {{rootNpxPath}} --offline commitlint -V --from origin/{{defaultBranch}} --to $\{{ github.event.pull_request.head.sha }} \
20
- || echo $PR_TITLE | npx --offline commitlint -V
18
+ {{ rootNpxPath }} --offline commitlint -V --from origin/$\{{ github.base_ref }} --to $\{{ github.event.pull_request.head.sha }}
19
+ - name: Run Commitlint on PR Title
20
+ if: steps.commit.outcome == 'failure'
21
+ run: |
22
+ echo $\{{ github.event.pull_request.title }} | {{ rootNpxPath }} --offline commitlint -V
@@ -1,13 +1,13 @@
1
1
  {
2
- "separate-pull-requests": {{{del}}},
3
- "plugins": {{#if isMono}}["node-workspace"]{{else}}{{{del}}}{{/if}},
2
+ "separate-pull-requests": {{{ del }}},
3
+ "plugins": {{#if isMono }}["node-workspace"]{{ else }}{{{ del }}}{{/if}},
4
4
  "exclude-packages-from-root": true,
5
5
  "group-pull-request-title-pattern": "chore: release ${version}",
6
6
  "pull-request-title-pattern": "chore: release${component} ${version}",
7
- "changelog-sections": {{{json changelogTypes}}},
7
+ "changelog-sections": {{{ json changelogTypes }}},
8
8
  "packages": {
9
- "{{#unless pkgRelPath}}.{{/unless}}{{pkgRelPath}}": {
10
- {{#unless pkgRelPath}}"package-name": ""{{/unless}}
9
+ "{{ pkgPath }}": {
10
+ {{#if isRoot}}"package-name": ""{{/if}}
11
11
  }
12
12
  }
13
13
  }
@@ -1,3 +1,3 @@
1
1
  {
2
- "{{#unless pkgRelPath}}.{{/unless}}{{pkgRelPath}}": "{{pkg.version}}"
2
+ "{{ pkgPath }}": "{{ pkg.version }}"
3
3
  }
@@ -1,20 +1,125 @@
1
-
2
1
  name: Release
3
2
 
4
3
  on:
5
- workflow_call:
6
- inputs:
7
- ref:
8
- required: true
9
- type: string
4
+ push:
5
+ branches:
6
+ {{#each branches}}
7
+ - {{ . }}
8
+ {{/each}}
9
+ {{#each releaseBranches }}
10
+ - {{ . }}
11
+ {{/each}}
12
+
13
+ permissions:
14
+ contents: write
15
+ pull-requests: write
16
+ checks: write
10
17
 
11
18
  jobs:
12
- lint-all:
13
- {{> setupJob checkout=(obj ref="${{ inputs.ref }}")}}
14
- - run: {{rootNpmPath}} run lint -ws -iwr --if-present
15
-
16
- test-all:
17
- {{> setupJobMatrix checkout=(obj ref="${{ inputs.ref }}")}}
18
- - name: add tap problem matcher
19
- run: echo "::add-matcher::.github/matchers/tap.json"
20
- - run: {{rootNpmPath}} run test -ws -iwr --if-present
19
+ release:
20
+ outputs:
21
+ pr: $\{{ steps.release.outputs.pr }}
22
+ releases: $\{{ steps.release.outputs.releases }}
23
+ release-flags: $\{{ steps.release.outputs.release-flags }}
24
+ branch: $\{{ steps.release.outputs.pr-branch }}
25
+ pr-number: $\{{ steps.release.outputs.pr-number }}
26
+ comment-id: $\{{ steps.pr-comment.outputs.result }}
27
+ check-id: $\{{ steps.check.outputs.check_id }}
28
+ {{> job jobName="Release" }}
29
+ - name: Release Please
30
+ id: release
31
+ env:
32
+ GITHUB_TOKEN: $\{{ secrets.GITHUB_TOKEN }}
33
+ run: |
34
+ {{ rootNpxPath }} --offline template-oss-release-please $\{{ github.ref_name }}
35
+ - name: Post Pull Request Comment
36
+ if: steps.release.outputs.pr-number
37
+ uses: actions/github-script@v6
38
+ id: pr-comment
39
+ env:
40
+ PR_NUMBER: $\{{ steps.release.outputs.pr-number }}
41
+ with:
42
+ script: |
43
+ const repo = { owner: context.repo.owner, repo: context.repo.repo }
44
+ const issue = { ...repo, issue_number: process.env.PR_NUMBER }
45
+
46
+ const { data: workflow } = await github.rest.actions.getWorkflowRun({ ...repo, run_id: context.runId })
47
+
48
+ let body = '## Release Manager\n\n'
49
+
50
+ const comments = await github.paginate(github.rest.issues.listComments, issue)
51
+ let commentId = comments?.find(c => c.user.login === 'github-actions[bot]' && c.body.startsWith(body))?.id
52
+
53
+ body += `- Release workflow run: ${workflow.html_url}`
54
+ if (commentId) {
55
+ await github.rest.issues.updateComment({ ...repo, comment_id: commentId, body })
56
+ } else {
57
+ const { data: comment } = await github.rest.issues.createComment({ ...issue, body })
58
+ commentId = comment?.id
59
+ }
60
+
61
+ return commentId
62
+ {{> stepChecks jobCheck=(obj name="Release" sha="${{ steps.release.outputs.pr-sha }}" if="steps.release.outputs.pr-number") }}
63
+
64
+ update:
65
+ needs: release
66
+ outputs:
67
+ sha: $\{{ steps.commit.outputs.sha }}
68
+ check-id: $\{{ steps.check.outputs.check_id }}
69
+ {{> job
70
+ jobName="Update - Release"
71
+ jobIf="needs.release.outputs.pr"
72
+ jobCheckout=(obj ref="${{ needs.release.outputs.branch }}" fetch-depth=0)
73
+ }}
74
+ - name: Run Post Pull Request Actions
75
+ env:
76
+ RELEASE_PR_NUMBER: $\{{ needs.release.outputs.pr-number }}
77
+ RELEASE_COMMENT_ID: $\{{ needs.release.outputs.comment-id }}
78
+ GITHUB_TOKEN: $\{{ secrets.GITHUB_TOKEN }}
79
+ run: |
80
+ {{ rootNpmPath }} run rp-pull-request --ignore-scripts {{ allFlags }}
81
+ - name: Commit
82
+ id: commit
83
+ env:
84
+ GITHUB_TOKEN: $\{{ secrets.GITHUB_TOKEN }}
85
+ run: |
86
+ git commit --all --amend --no-edit || true
87
+ git push --force-with-lease
88
+ echo "::set-output name=sha::$(git rev-parse HEAD)"
89
+ {{> stepChecks jobCheck=(obj sha="${{ steps.commit.outputs.sha }}" name="Release" )}}
90
+ {{> stepChecks jobCheck=(obj id="${{ needs.release.outputs.check-id }}" )}}
91
+
92
+ ci:
93
+ name: CI - Release
94
+ needs: [release, update]
95
+ if: needs.release.outputs.pr
96
+ uses: ./.github/workflows/ci-release.yml
97
+ with:
98
+ ref: $\{{ needs.release.outputs.branch }}
99
+ check-sha: $\{{ needs.update.outputs.sha }}
100
+
101
+ post-ci:
102
+ needs: [release, update, ci]
103
+ {{> job jobName="Post CI - Release" jobIf="needs.release.outputs.pr && always()" jobSkipSetup=true }}
104
+ - name: Get Needs Result
105
+ id: needs-result
106
+ run: |
107
+ result=""
108
+ if [[ "$\{{ contains(needs.*.result, 'failure') }}" == "true" ]]; then
109
+ result="failure"
110
+ elif [[ "$\{{ contains(needs.*.result, 'cancelled') }}" == "true" ]]; then
111
+ result="cancelled"
112
+ else
113
+ result="success"
114
+ fi
115
+ echo "::set-output name=result::$result"
116
+ {{> stepChecks jobCheck=(obj id="${{ needs.update.outputs.check-id }}" status="${{ steps.needs-result.outputs.result }}") }}
117
+
118
+ post-release:
119
+ needs: release
120
+ {{> job jobName="Post Release - Release" jobIf="needs.release.outputs.releases" }}
121
+ - name: Run Post Release Actions
122
+ env:
123
+ RELEASES: $\{{ needs.release.outputs.releases }}
124
+ run: |
125
+ {{ rootNpmPath }} run rp-release --ignore-scripts --if-present $\{{ join(fromJSON(needs.release.outputs.release-flags), ' ') }}
package/lib/index.js CHANGED
@@ -7,8 +7,8 @@ const mapWorkspaces = require('@npmcli/map-workspaces')
7
7
  const getPkg = async (path) => {
8
8
  log.verbose('get-pkg', path)
9
9
 
10
- const pkg = (await PackageJson.load(path)).content
11
- const pkgConfig = getConfig.getPkgConfig(pkg)
10
+ const pkgJson = (await PackageJson.load(path)).content
11
+ const pkgConfig = getConfig.getPkgConfig(pkgJson)
12
12
  log.verbose('get-pkg', pkgConfig)
13
13
 
14
14
  if (pkgConfig.content) {
@@ -16,7 +16,7 @@ const getPkg = async (path) => {
16
16
  }
17
17
 
18
18
  return {
19
- pkg,
19
+ pkgJson,
20
20
  path,
21
21
  config: pkgConfig,
22
22
  }
@@ -25,21 +25,18 @@ const getPkg = async (path) => {
25
25
  const getWsPkgs = async (root, rootPkg) => {
26
26
  const wsPkgs = []
27
27
 
28
- // workspaces are only used to filter paths and control changes to workspaces
29
- // so dont pass it along with the rest of the config
30
- const { workspaces, ...baseConfig } = rootPkg.config
31
-
32
28
  // Include all by default
29
+ const { workspaces } = rootPkg.config
33
30
  const include = (name) => Array.isArray(workspaces) ? workspaces.includes(name) : true
34
31
 
35
32
  // Look through all workspaces on the root pkg
36
- const rootWorkspaces = await mapWorkspaces({ pkg: rootPkg.pkg, cwd: root })
33
+ const rootWorkspaces = await mapWorkspaces({ pkg: rootPkg.pkgJson, cwd: root })
37
34
 
38
35
  for (const [wsName, wsPath] of rootWorkspaces.entries()) {
39
36
  if (include(wsName)) {
40
37
  // A workspace can control its own workspaceRepo and workspaceModule settings
41
38
  // which are true by default on the root config
42
- wsPkgs.push(await getPkg(wsPath, baseConfig))
39
+ wsPkgs.push(await getPkg(wsPath))
43
40
  }
44
41
  }
45
42
 
@@ -67,19 +64,19 @@ const runAll = async (root, checks) => {
67
64
  const results = []
68
65
  const { pkgs, workspaces, rootPkg: { config: rootConfig } } = await getPkgs(root)
69
66
 
70
- for (const { pkg, path, config: pkgConfig } of pkgs) {
67
+ for (const { pkgJson, path, config: pkgConfig } of pkgs) {
71
68
  // full config includes original config values
72
69
  const fullConfig = await getConfig({
73
70
  root,
74
71
  path,
75
- pkg,
72
+ pkgJson,
76
73
  pkgs,
77
74
  workspaces,
78
75
  rootConfig,
79
76
  pkgConfig,
80
77
  })
81
78
 
82
- const options = { root, pkg, path, config: fullConfig }
79
+ const options = { root, path, pkg: pkgJson, config: fullConfig }
83
80
  log.verbose('run-all', options)
84
81
 
85
82
  // files can export multiple checks so flatten first
@@ -26,13 +26,34 @@ const main = async ({ repo: fullRepo, token, dryRun, branch }) => {
26
26
  )
27
27
 
28
28
  const pullRequests = await (dryRun ? manifest.buildPullRequests() : manifest.createPullRequests())
29
- const releases = await (dryRun ? manifest.buildReleases() : manifest.createReleases())
29
+ const allReleases = await (dryRun ? manifest.buildReleases() : manifest.createReleases())
30
+
31
+ // We only ever get a single pull request with our current release-please settings
32
+ const rootPr = pullRequests.filter(Boolean)[0]
33
+ if (rootPr?.number) {
34
+ const commits = await github.octokit.paginate(github.octokit.rest.pulls.listCommits, {
35
+ owner: github.repository.owner,
36
+ repo: github.repository.repo,
37
+ pull_number: rootPr.number,
38
+ })
39
+ rootPr.sha = commits?.[commits.length - 1]?.sha
40
+ }
41
+
42
+ const releases = allReleases.filter(Boolean)
43
+ const [rootRelease, workspaceReleases] = releases.reduce((acc, r) => {
44
+ if (r.path === '.') {
45
+ acc[0] = r
46
+ } else {
47
+ acc[1].push(r)
48
+ }
49
+ return acc
50
+ }, [null, []])
30
51
 
31
52
  return {
32
- // We only ever get a single pull request with our current release-please settings
33
- pr: pullRequests.filter(Boolean)[0],
34
- releases: releases.filter(Boolean),
35
- release: releases.find(r => r.path === '.'),
53
+ pr: rootPr,
54
+ release: rootRelease,
55
+ releases: releases.length ? releases : null,
56
+ workspaceReleases: workspaceReleases.length ? workspaceReleases : null,
36
57
  }
37
58
  }
38
59
 
package/lib/util/files.js CHANGED
@@ -23,18 +23,20 @@ const fileEntries = (dir, files, options) => Object.entries(files)
23
23
  // given an obj of files, return the full target/source paths and associated parser
24
24
  const getParsers = (dir, files, options) => {
25
25
  const parsers = fileEntries(dir, files, options).map(([target, source]) => {
26
- const { file, parser, filter } = source
26
+ const { file, parser, filter, clean: shouldClean } = source
27
27
 
28
28
  if (typeof filter === 'function' && !filter(options)) {
29
29
  return null
30
30
  }
31
31
 
32
+ const clean = typeof shouldClean === 'function' ? shouldClean(options) : false
33
+
32
34
  if (parser) {
33
35
  // allow files to extend base parsers or create new ones
34
- return new (parser(Parser.Parsers))(target, file, options)
36
+ return new (parser(Parser.Parsers))(target, file, options, { clean })
35
37
  }
36
38
 
37
- return new (Parser(file))(target, file, options)
39
+ return new (Parser(file))(target, file, options, { clean })
38
40
  })
39
41
 
40
42
  return parsers.filter(Boolean)