@docupace/pipeline 1.1.5 → 1.1.8
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.
- package/.changeset/validate-changeset-bin-fallback.md +5 -0
- package/CHANGELOG.md +8 -0
- package/package.json +2 -1
- package/src/auth0/cli.js +2 -0
- package/src/changeset/cli.js +2 -0
- package/src/changeset/validate.js +13 -2
- package/src/changeset/validate.test.js +79 -0
- package/src/changeset/version.js +38 -12
- package/src/lib/pipeline-version.js +25 -0
- package/src/merge/cli.js +2 -0
- package/src/micro/cli.js +2 -0
- package/src/next/cli.js +2 -0
- package/src/tenable/cli.js +2 -0
- package/src/veracode/cli.js +2 -0
- package/src/xray/cli.js +2 -0
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
---
|
|
2
|
+
'@docupace/pipeline': patch
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Fix changeset validation failing with "No changeset found" on pull-request builds. Validation ran `./node_modules/.bin/changeset status` (since 1.1.6), but the validate step has no install, so the binary did not exist (exit 127). It now reads the release plan in-process with `@changesets/get-release-plan`, which needs neither the repo's `node_modules` nor a `changeset-output.json` file.
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# @docupace/pipeline
|
|
2
2
|
|
|
3
|
+
## 1.1.7
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 82e71f0: Run the changeset binary installed by the CLI directly instead of via `pnpm changeset`, so pnpm cannot re-sync node_modules to the repo lockfile and swap the changelog hook to an older pinned @docupace/pipeline.
|
|
8
|
+
|
|
9
|
+
Log the @docupace/pipeline version (to stderr) before every command of every dp-\*-cli, and log the CLI and changelog hook versions during changeset versioning.
|
|
10
|
+
|
|
3
11
|
## 1.1.4
|
|
4
12
|
|
|
5
13
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@docupace/pipeline",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.8",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"@aws-sdk/client-secrets-manager": "^3.600.0",
|
|
27
27
|
"@changesets/cli": "2.27.12",
|
|
28
|
+
"@changesets/get-release-plan": "^4.0.16",
|
|
28
29
|
"@docupace/core-client": "^1.0.1",
|
|
29
30
|
"@jest/globals": "^30.1.2",
|
|
30
31
|
"auth0-deploy-cli": "^8.8.0",
|
package/src/auth0/cli.js
CHANGED
|
@@ -19,10 +19,12 @@ import dotenv from 'dotenv';
|
|
|
19
19
|
import { configureAlias } from './alias.js';
|
|
20
20
|
import { exportConf } from './export.js';
|
|
21
21
|
import { getAuth0Metadata } from './metadata.js';
|
|
22
|
+
import { logVersionBeforeCommands } from '../lib/pipeline-version.js';
|
|
22
23
|
|
|
23
24
|
dotenv.config({ path: ['.env.pipeline.local', 'config/.env.pipeline.local'] });
|
|
24
25
|
|
|
25
26
|
const program = new Command();
|
|
27
|
+
logVersionBeforeCommands(program);
|
|
26
28
|
|
|
27
29
|
program
|
|
28
30
|
.command(
|
package/src/changeset/cli.js
CHANGED
|
@@ -13,10 +13,12 @@ import {
|
|
|
13
13
|
import { createChangeset } from './create.js';
|
|
14
14
|
import { updateWikiWithVersion } from './changelog-wiki.js';
|
|
15
15
|
import { convertPrepare, convertComplete } from './convert.js';
|
|
16
|
+
import { logVersionBeforeCommands } from '../lib/pipeline-version.js';
|
|
16
17
|
|
|
17
18
|
dotenv.config({ path: ['.env.pipeline.local', 'config/.env.pipeline.local'] });
|
|
18
19
|
|
|
19
20
|
const program = new Command();
|
|
21
|
+
logVersionBeforeCommands(program);
|
|
20
22
|
|
|
21
23
|
const args = process.argv;
|
|
22
24
|
|
|
@@ -5,7 +5,7 @@ import { $ } from 'zx';
|
|
|
5
5
|
|
|
6
6
|
import { setGitInfo } from '../next/util.js';
|
|
7
7
|
import { getPackageNames } from './package-util.js';
|
|
8
|
-
import
|
|
8
|
+
import getReleasePlan from '@changesets/get-release-plan';
|
|
9
9
|
|
|
10
10
|
const PACKAGE_ROOT = path.resolve(
|
|
11
11
|
path.dirname(fileURLToPath(import.meta.url)),
|
|
@@ -16,6 +16,17 @@ const PACKAGE_VERSION = JSON.parse(
|
|
|
16
16
|
fs.readFileSync(path.join(PACKAGE_ROOT, 'package.json'), 'utf8'),
|
|
17
17
|
).version;
|
|
18
18
|
|
|
19
|
+
// Reads the release plan in-process with the changesets library instead of
|
|
20
|
+
// running `changeset status`, so validation needs neither the repo's
|
|
21
|
+
// node_modules (no install step runs before validate) nor an output file.
|
|
22
|
+
export async function getValidationReleases(sinceBranch) {
|
|
23
|
+
const releasePlan = await getReleasePlan(process.cwd(), sinceBranch);
|
|
24
|
+
if (releasePlan.changesets.length === 0) {
|
|
25
|
+
throw new Error(`No changesets found since ${sinceBranch}`);
|
|
26
|
+
}
|
|
27
|
+
return releasePlan.releases;
|
|
28
|
+
}
|
|
29
|
+
|
|
19
30
|
export async function validateChangesets() {
|
|
20
31
|
console.log(
|
|
21
32
|
`validateChangesets: @docupace/pipeline version = ${PACKAGE_VERSION}`,
|
|
@@ -32,7 +43,7 @@ export async function validateChangesets() {
|
|
|
32
43
|
|
|
33
44
|
try {
|
|
34
45
|
console.log('🔍 Validating changesets...');
|
|
35
|
-
releases = await
|
|
46
|
+
releases = await getValidationReleases(destBranch);
|
|
36
47
|
} catch (e) {
|
|
37
48
|
console.error(
|
|
38
49
|
'❌ No changeset found. Please add a changeset to this PR. Please see more information at https://docupacellc.atlassian.net/wiki/spaces/PM/pages/1350893571/Creating+changesets+for+Docupace+Next',
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, test } from '@jest/globals';
|
|
2
|
+
import { execFileSync } from 'child_process';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import os from 'os';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
import { getValidationReleases } from './validate.js';
|
|
7
|
+
|
|
8
|
+
const git = (cwd, ...args) =>
|
|
9
|
+
execFileSync('git', args, { cwd, stdio: 'pipe' }).toString();
|
|
10
|
+
|
|
11
|
+
// A real repo with no node_modules, like the pipeline's validate step.
|
|
12
|
+
function makeRepo() {
|
|
13
|
+
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'validate-changeset-'));
|
|
14
|
+
git(dir, 'init', '-q', '-b', 'master');
|
|
15
|
+
git(dir, 'config', 'user.email', 't@example.com');
|
|
16
|
+
git(dir, 'config', 'user.name', 'test');
|
|
17
|
+
fs.writeFileSync(
|
|
18
|
+
path.join(dir, 'package.json'),
|
|
19
|
+
JSON.stringify({ name: 'sample', version: '1.0.0' }),
|
|
20
|
+
);
|
|
21
|
+
fs.mkdirSync(path.join(dir, '.changeset'));
|
|
22
|
+
fs.writeFileSync(
|
|
23
|
+
path.join(dir, '.changeset', 'config.json'),
|
|
24
|
+
JSON.stringify({
|
|
25
|
+
changelog: false,
|
|
26
|
+
baseBranch: 'master',
|
|
27
|
+
access: 'restricted',
|
|
28
|
+
}),
|
|
29
|
+
);
|
|
30
|
+
git(dir, 'add', '-A');
|
|
31
|
+
git(dir, 'commit', '-q', '-m', 'base');
|
|
32
|
+
git(dir, 'checkout', '-q', '-b', 'feature');
|
|
33
|
+
fs.writeFileSync(path.join(dir, 'file.txt'), 'change');
|
|
34
|
+
return dir;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
describe('getValidationReleases', () => {
|
|
38
|
+
let dir;
|
|
39
|
+
let originalCwd;
|
|
40
|
+
|
|
41
|
+
beforeEach(() => {
|
|
42
|
+
originalCwd = process.cwd();
|
|
43
|
+
dir = makeRepo();
|
|
44
|
+
process.chdir(dir);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
afterEach(() => {
|
|
48
|
+
process.chdir(originalCwd);
|
|
49
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
test('returns the releases when the branch adds a changeset', async () => {
|
|
53
|
+
fs.writeFileSync(
|
|
54
|
+
path.join(dir, '.changeset', 'DC-1.md'),
|
|
55
|
+
"---\n'sample': patch\n---\n\nA change\n",
|
|
56
|
+
);
|
|
57
|
+
git(dir, 'add', '-A');
|
|
58
|
+
git(dir, 'commit', '-q', '-m', 'feature');
|
|
59
|
+
|
|
60
|
+
const releases = await getValidationReleases('master');
|
|
61
|
+
|
|
62
|
+
expect(releases).toEqual([
|
|
63
|
+
expect.objectContaining({
|
|
64
|
+
name: 'sample',
|
|
65
|
+
type: 'patch',
|
|
66
|
+
newVersion: '1.0.1',
|
|
67
|
+
}),
|
|
68
|
+
]);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
test('throws when the branch has no changeset', async () => {
|
|
72
|
+
git(dir, 'add', '-A');
|
|
73
|
+
git(dir, 'commit', '-q', '-m', 'feature');
|
|
74
|
+
|
|
75
|
+
await expect(getValidationReleases('master')).rejects.toThrow(
|
|
76
|
+
'No changesets found since master',
|
|
77
|
+
);
|
|
78
|
+
});
|
|
79
|
+
});
|
package/src/changeset/version.js
CHANGED
|
@@ -5,14 +5,37 @@ import { updateComponentVersion } from '../next/jira.js';
|
|
|
5
5
|
import { findJiraTicketId } from './util.js';
|
|
6
6
|
import { revertBaseBranch, updateBaseBranch } from './changeset-config.js';
|
|
7
7
|
import semver from 'semver';
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
8
|
+
import { join } from 'path';
|
|
9
|
+
import { getPipelineVersion as getPackageVersion } from '../lib/pipeline-version.js';
|
|
10
|
+
|
|
11
|
+
// Run the changeset binary installed by the temporary install below rather than
|
|
12
|
+
// `pnpm changeset`. Going through pnpm lets it re-sync node_modules with the
|
|
13
|
+
// repo's own lockfile before the command runs, which swaps the pinned
|
|
14
|
+
// @docupace/pipeline (used by the changelog hook) for whatever version the repo
|
|
15
|
+
// lockfile holds instead of the version of this CLI.
|
|
16
|
+
const CHANGESET_BIN = './node_modules/.bin/changeset';
|
|
17
|
+
|
|
18
|
+
// Version of @docupace/pipeline the changelog hook will be loaded from (the
|
|
19
|
+
// copy in the current directory's node_modules, not the one running this CLI).
|
|
20
|
+
const getInstalledPipelineVersion = () => {
|
|
21
|
+
try {
|
|
22
|
+
const pkgPath = join(
|
|
23
|
+
process.cwd(),
|
|
24
|
+
'node_modules',
|
|
25
|
+
'@docupace',
|
|
26
|
+
'pipeline',
|
|
27
|
+
'package.json',
|
|
28
|
+
);
|
|
29
|
+
return JSON.parse(readFileSync(pkgPath, 'utf8')).version;
|
|
30
|
+
} catch (error) {
|
|
31
|
+
return `unknown (${error.message})`;
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const logPipelineVersions = (stage) => {
|
|
36
|
+
console.log(
|
|
37
|
+
`🔎 @docupace/pipeline ${stage}: running CLI ${getPackageVersion()}, changelog hook ${getInstalledPipelineVersion()}`,
|
|
38
|
+
);
|
|
16
39
|
};
|
|
17
40
|
|
|
18
41
|
const getChangeSetPackage = (installLatest = false) => `{
|
|
@@ -61,9 +84,9 @@ export async function versionStatus(sinceBranch) {
|
|
|
61
84
|
const outputPath = './changeset-output.json';
|
|
62
85
|
|
|
63
86
|
if (sinceBranch) {
|
|
64
|
-
await
|
|
87
|
+
await $`${CHANGESET_BIN} status --output=${outputPath} --since=${sinceBranch}`;
|
|
65
88
|
} else {
|
|
66
|
-
await
|
|
89
|
+
await $`${CHANGESET_BIN} status --output=${outputPath}`;
|
|
67
90
|
}
|
|
68
91
|
|
|
69
92
|
// Read the file and parse JSON
|
|
@@ -77,6 +100,7 @@ export async function versionCommand(
|
|
|
77
100
|
installLatest = false,
|
|
78
101
|
) {
|
|
79
102
|
console.log('📦 Running Changeset versioning...');
|
|
103
|
+
logPipelineVersions('at start');
|
|
80
104
|
if (!process.env.IS_DEV) {
|
|
81
105
|
await setGitInfo();
|
|
82
106
|
await $`mv package.json package.json.bak`;
|
|
@@ -98,9 +122,10 @@ export async function versionCommand(
|
|
|
98
122
|
}
|
|
99
123
|
await $`mv package.json.bak package.json`;
|
|
100
124
|
await $`mv pnpm-lock.yaml.bak pnpm-lock.yaml`;
|
|
125
|
+
logPipelineVersions('after install');
|
|
101
126
|
}
|
|
102
127
|
if (closeVersion) {
|
|
103
|
-
await
|
|
128
|
+
await $`${CHANGESET_BIN} pre exit`;
|
|
104
129
|
}
|
|
105
130
|
|
|
106
131
|
let originalBaseBranch;
|
|
@@ -117,7 +142,8 @@ export async function versionCommand(
|
|
|
117
142
|
|
|
118
143
|
// Intentionally outside the try/catch above: a failure here (e.g. release
|
|
119
144
|
// notes processing) must fail the build, not be swallowed as "no releases".
|
|
120
|
-
|
|
145
|
+
logPipelineVersions('before changeset version');
|
|
146
|
+
await $`${CHANGESET_BIN} version`;
|
|
121
147
|
|
|
122
148
|
await removeChangesetOutput();
|
|
123
149
|
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { readFileSync } from 'fs';
|
|
2
|
+
import { dirname, join } from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Version of the @docupace/pipeline package this code is running from.
|
|
7
|
+
*/
|
|
8
|
+
export function getPipelineVersion() {
|
|
9
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
10
|
+
const packageJsonPath = join(__dirname, '../../package.json');
|
|
11
|
+
return JSON.parse(readFileSync(packageJsonPath, 'utf8')).version;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Registers a commander hook that logs the @docupace/pipeline version before
|
|
16
|
+
* any command of the given program runs. Written to stderr so it never mixes
|
|
17
|
+
* with output that callers parse from stdout.
|
|
18
|
+
*/
|
|
19
|
+
export function logVersionBeforeCommands(program) {
|
|
20
|
+
program.hook('preAction', (_thisCommand, actionCommand) => {
|
|
21
|
+
console.error(
|
|
22
|
+
`🔎 @docupace/pipeline ${getPipelineVersion()} (${program.name() || 'cli'} ${actionCommand.name()})`,
|
|
23
|
+
);
|
|
24
|
+
});
|
|
25
|
+
}
|
package/src/merge/cli.js
CHANGED
|
@@ -6,9 +6,11 @@ import { Command } from 'commander';
|
|
|
6
6
|
import { setupMerge } from './cli-merge.js';
|
|
7
7
|
import { setupResolve } from './cli-resolve.js';
|
|
8
8
|
import { setupMergeAll } from './cli-merge-all.js';
|
|
9
|
+
import { logVersionBeforeCommands } from '../lib/pipeline-version.js';
|
|
9
10
|
|
|
10
11
|
const args = process.argv;
|
|
11
12
|
const program = new Command();
|
|
13
|
+
logVersionBeforeCommands(program);
|
|
12
14
|
|
|
13
15
|
/**
|
|
14
16
|
* Reusable auto-resolve function
|
package/src/micro/cli.js
CHANGED
|
@@ -9,10 +9,12 @@ import {
|
|
|
9
9
|
microserviceCopyImageToEnv,
|
|
10
10
|
microserviceBuildPushImage,
|
|
11
11
|
} from './ms-deploy.js';
|
|
12
|
+
import { logVersionBeforeCommands } from '../lib/pipeline-version.js';
|
|
12
13
|
|
|
13
14
|
dotenv.config({ path: ['.env.pipeline.local', 'config/.env.pipeline.local'] });
|
|
14
15
|
|
|
15
16
|
const program = new Command();
|
|
17
|
+
logVersionBeforeCommands(program);
|
|
16
18
|
|
|
17
19
|
//const GIT_SHA = (await $`git log --pretty=format:'%h' -n 1`).stdout.trim();
|
|
18
20
|
|
package/src/next/cli.js
CHANGED
|
@@ -23,10 +23,12 @@ import { deployConnect, deployCore } from './jenkins.js';
|
|
|
23
23
|
import { deployConnectAws, runPipelineChecked } from './connect-aws.js';
|
|
24
24
|
import { registerConnectAwsCommands } from './connect-aws-cli.js';
|
|
25
25
|
import { runPipeline } from './pipline.js';
|
|
26
|
+
import { logVersionBeforeCommands } from '../lib/pipeline-version.js';
|
|
26
27
|
|
|
27
28
|
dotenv.config({ path: ['.env.pipeline.local', 'config/.env.pipeline.local'] });
|
|
28
29
|
|
|
29
30
|
const program = new Command();
|
|
31
|
+
logVersionBeforeCommands(program);
|
|
30
32
|
|
|
31
33
|
const GIT_SHA = (await $`git log --pretty=format:'%h' -n 1`).stdout.trim();
|
|
32
34
|
|
package/src/tenable/cli.js
CHANGED
|
@@ -3,8 +3,10 @@
|
|
|
3
3
|
import { Command } from 'commander';
|
|
4
4
|
import { $ } from 'zx';
|
|
5
5
|
import { runTenableScan } from './scan.js';
|
|
6
|
+
import { logVersionBeforeCommands } from '../lib/pipeline-version.js';
|
|
6
7
|
|
|
7
8
|
const program = new Command();
|
|
9
|
+
logVersionBeforeCommands(program);
|
|
8
10
|
|
|
9
11
|
program
|
|
10
12
|
.command('scan')
|
package/src/veracode/cli.js
CHANGED
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
import { Command } from 'commander';
|
|
4
4
|
import { runVeracodeScan } from './scan.js';
|
|
5
|
+
import { logVersionBeforeCommands } from '../lib/pipeline-version.js';
|
|
5
6
|
|
|
6
7
|
const program = new Command();
|
|
8
|
+
logVersionBeforeCommands(program);
|
|
7
9
|
|
|
8
10
|
program
|
|
9
11
|
.command('scan')
|
package/src/xray/cli.js
CHANGED