@docupace/pipeline 1.0.46 → 1.0.47-monorepo.0
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/README.md +136 -0
- package/next/execute.sh +8 -2
- package/package.json +7 -2
- package/src/auth0/configure.js +4 -4
- package/src/auth0/metadata.js +1 -2
- package/src/changeset/cli.js +80 -224
- package/src/changeset/create.js +205 -0
- package/src/changeset/package-util.js +86 -0
- package/src/changeset/util.js +43 -0
- package/src/changeset/validate.js +38 -1
- package/src/changeset/version.js +94 -0
- package/src/jenkins/setParams.groovy +1 -2
- package/src/next/cli.js +22 -12
- package/src/next/config.js +36 -0
- package/src/next/copy.js +9 -3
- package/src/next/deploy.js +18 -5
- package/src/next/jira.js +4 -7
- package/src/next/logger.js +17 -0
- package/src/next/publish.js +53 -30
- package/src/next/util.js +93 -0
- package/src/next/vault.js +7 -5
- package/commit-message +0 -41
- package/pull-request-sum +0 -42
- package/pull-request-summary +0 -34
- package/pull-request-title +0 -66
package/README.md
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# Pipeline Shared Scripts
|
|
2
|
+
|
|
3
|
+
A collection of CLI tools for Docupace's CI/CD pipelines and deployment workflows.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This package provides a set of command-line interfaces (CLIs) to facilitate various DevOps operations in the Docupace ecosystem:
|
|
8
|
+
|
|
9
|
+
- `dp-next-cli`: Deployment and pipeline management for Next applications
|
|
10
|
+
- `dp-changeset-cli`: Versioning and changeset management
|
|
11
|
+
- `dp-auth0-cli`: Auth0 tenant configuration and management
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install @docupace/pipeline
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Or with pnpm:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pnpm add @docupace/pipeline
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Command Line Interfaces
|
|
26
|
+
|
|
27
|
+
### dp-next-cli
|
|
28
|
+
|
|
29
|
+
Manages deployment, Docker image handling, and infrastructure configuration.
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
dp-next-cli [command] [options]
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
**Commands:**
|
|
36
|
+
|
|
37
|
+
- `pull <imageName>`: Pull a Docker image from the registry
|
|
38
|
+
- `sonar`: Run Sonar analysis
|
|
39
|
+
- `addApacheSite`: Add site to apache
|
|
40
|
+
- `connectClone`: Clone connect site
|
|
41
|
+
- `haproxySync`: Sync haproxy config
|
|
42
|
+
- `vaultAddSiteData`: Add m2m auth0 data to vault
|
|
43
|
+
- `-s, --site-name <siteName>`: Site name
|
|
44
|
+
- `-p, --site-config-remote-path <path>`: Site config remote path
|
|
45
|
+
- `publish`: Publish a Docker image
|
|
46
|
+
- `deploy-from-site`: Deploy an application for a specific site
|
|
47
|
+
- `-f, --from-env <fromEnv>`: Source environment
|
|
48
|
+
- `-t, --to-env <toEnv>`: Target environment
|
|
49
|
+
- `-F, --from-site <fromSite>`: Source site
|
|
50
|
+
- `-T, --to-site <toSite>`: Target site
|
|
51
|
+
- `-c, --deploy-core <deployCore>`: Deploy Core (default: "false")
|
|
52
|
+
- `-C, --deploy-connect <deployConnect>`: Deploy Connect (default: "false")
|
|
53
|
+
- `deploy-template`: Deploy an application for a specific site
|
|
54
|
+
- `deploy-app <application>`: Deploy an application for a specific site
|
|
55
|
+
- `deploy-core <env> <site>`: Deploy Core
|
|
56
|
+
- `-l, --liquibase <liquibase>`: Application name (default: "true")
|
|
57
|
+
- `-b, --branch <branch>`: Branch (default: "master")
|
|
58
|
+
- `deploy-connect <env> <site>`: Deploy Connect
|
|
59
|
+
- `-l, --liquibase <liquibase>`: Application name (default: "true")
|
|
60
|
+
- `-b, --branch <branch>`: Branch (default: "master")
|
|
61
|
+
- `deploy-core-pipeline <env> <site>`: Deploy Core via pipeline
|
|
62
|
+
- `-l, --liquibase <liquibase>`: Application name (default: "true")
|
|
63
|
+
- `-b, --branch <branch>`: Branch (default: "master")
|
|
64
|
+
- `copy`: Copy a Docker image between registries
|
|
65
|
+
- `-a, --application <application>`: Application name
|
|
66
|
+
- `-f, --from-env <fromEnv>`: Source environment
|
|
67
|
+
- `-t, --to-env <toEnv>`: Target environment
|
|
68
|
+
- `-g, --tag <tag>`: Image tag
|
|
69
|
+
- `run-pipeline`: Trigger a pipeline by name
|
|
70
|
+
- `-r, --repository <repository>`: Repository name
|
|
71
|
+
- `-p, --pipeline-name <pipelineName>`: Pipeline name
|
|
72
|
+
- `-b, --branch <branch>`: Branch name
|
|
73
|
+
- `-v, --variables <key=value>`: Pipeline variable as key=value pair
|
|
74
|
+
- `-w, --wait`: Wait for the pipeline to complete (default: false)
|
|
75
|
+
|
|
76
|
+
### dp-changeset-cli
|
|
77
|
+
|
|
78
|
+
Manages versioning and changesets for mono-repos and single-package repos.
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
dp-changeset-cli [command] [options]
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**Commands:**
|
|
85
|
+
|
|
86
|
+
- `validate`: Validate changesets for the provided PR
|
|
87
|
+
- `version`: Run Changeset versioning
|
|
88
|
+
- `commit-tag`: Commit and tag the new version
|
|
89
|
+
- `version-commit-tag`: Run versioning and commit-and-tag in sequence
|
|
90
|
+
- `close-version`: Close a version and create a release branch
|
|
91
|
+
- `create-changeset`: Create a changeset based on the current branch and Jira ticket information
|
|
92
|
+
|
|
93
|
+
### dp-auth0-cli
|
|
94
|
+
|
|
95
|
+
Manages Auth0 tenant configuration across environments.
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
dp-auth0-cli [command] [options]
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
**Commands:**
|
|
102
|
+
|
|
103
|
+
- `configureFromSite <fromSite> <toSite> <fromEnv> <toEnv> <deployUI> <deployGraphQLServer> <useNewDomain> <useS3>`: Configure Auth0 tenants
|
|
104
|
+
- `getVaultSecrets <vaultPath>`: Get secrets from Vault
|
|
105
|
+
- `configureAlias <site> <env> <username> <password> <realm>`: Configure Core Alias for the given site
|
|
106
|
+
- `exportConf <site> <env>`: Export Auth0 configuration for the given site
|
|
107
|
+
- `getAuth0Metadata <site> <env>`: Get Auth0 metadata for the given site
|
|
108
|
+
|
|
109
|
+
## Environment Configuration
|
|
110
|
+
|
|
111
|
+
The CLI tools look for environment configuration in the following locations:
|
|
112
|
+
- `.env.pipeline.local`
|
|
113
|
+
- `config/.env.pipeline.local`
|
|
114
|
+
|
|
115
|
+
## Examples
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
# Deploy from one site to another
|
|
119
|
+
dp-next-cli deploy-from-site --from-env dev --to-env dev --from-site financialdev --to-site template --deploy-core true
|
|
120
|
+
|
|
121
|
+
# Run a pipeline
|
|
122
|
+
dp-next-cli run-pipeline -r docupace-next-e2e -b master -p run-tests-qa
|
|
123
|
+
|
|
124
|
+
# Validate changesets
|
|
125
|
+
dp-changeset-cli validate
|
|
126
|
+
|
|
127
|
+
# Create a new changeset
|
|
128
|
+
dp-changeset-cli create-changeset
|
|
129
|
+
|
|
130
|
+
# Configure Auth0 for a site
|
|
131
|
+
dp-auth0-cli configureFromSite sourceSite targetSite dev prod true true true false
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## License
|
|
135
|
+
|
|
136
|
+
ISC
|
package/next/execute.sh
CHANGED
|
@@ -53,8 +53,14 @@ copy() {
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
publish() {
|
|
56
|
-
|
|
57
|
-
|
|
56
|
+
SLUG_SUFFIX=""
|
|
57
|
+
if [ -n "$APP_NAME" ]; then
|
|
58
|
+
SLUG_SUFFIX="-${APP_NAME}"
|
|
59
|
+
fi
|
|
60
|
+
|
|
61
|
+
BUILD_IMAGE_NAME="${BITBUCKET_REPO_SLUG}${SLUG_SUFFIX}:build-${BITBUCKET_BUILD_NUMBER}"
|
|
62
|
+
IMAGE_NAME="${BITBUCKET_REPO_SLUG}${SLUG_SUFFIX}:sha-${GIT_SHA}"
|
|
63
|
+
|
|
58
64
|
export DOCKER_HOST=""
|
|
59
65
|
|
|
60
66
|
echo "Publishing Docker image ${IMAGE_NAME}..."
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@docupace/pipeline",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.47-monorepo.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -22,9 +22,12 @@
|
|
|
22
22
|
"axios": "^1.7.9",
|
|
23
23
|
"commander": "^12.1.0",
|
|
24
24
|
"dotenv": "^16.4.7",
|
|
25
|
+
"fs-extra": "^11.3.0",
|
|
26
|
+
"inquirer": "^12.6.1",
|
|
25
27
|
"js-yaml": "^4.1.0",
|
|
26
28
|
"lodash": "^4.17.21",
|
|
27
29
|
"openai": "^4.76.3",
|
|
30
|
+
"semver": "^7.7.2",
|
|
28
31
|
"zod": "^3.24.1",
|
|
29
32
|
"zx": "^8.3.0"
|
|
30
33
|
},
|
|
@@ -40,6 +43,8 @@
|
|
|
40
43
|
"scripts": {
|
|
41
44
|
"test-deploy-core": "dp-next-cli deploy-core-pipeline dev template",
|
|
42
45
|
"test-deploy-from-site": "dp-next-cli deploy-from-site --from-env dev --to-env dev --from-site financialdev --to-site template --deploy-core true",
|
|
43
|
-
"test-run-pipline": "dp-next-cli run-pipeline -r docupace-next-e2e -b master -p run-tests-qa"
|
|
46
|
+
"test-run-pipline": "dp-next-cli run-pipeline -r docupace-next-e2e -b master -p run-tests-qa",
|
|
47
|
+
"test-validate": "dp-changset-cli validate",
|
|
48
|
+
"test-create": "dp-changset-cli create-changeset"
|
|
44
49
|
}
|
|
45
50
|
}
|
package/src/auth0/configure.js
CHANGED
|
@@ -5,16 +5,16 @@ import crypto from 'crypto';
|
|
|
5
5
|
|
|
6
6
|
import {
|
|
7
7
|
cloneEnvRepository,
|
|
8
|
-
readDeployConfig,
|
|
9
|
-
pushDeployConfig,
|
|
10
8
|
cloneRepository,
|
|
9
|
+
pushDeployConfig,
|
|
10
|
+
readDeployConfig,
|
|
11
11
|
} from '../next/deploy.js';
|
|
12
12
|
|
|
13
13
|
import { getVaultSecrets, updateVaultSecrets } from './vault.js';
|
|
14
14
|
import {
|
|
15
|
-
getVaultSecretsConfigs,
|
|
16
|
-
environmentConfig,
|
|
17
15
|
coreSiteEnvMap,
|
|
16
|
+
environmentConfig,
|
|
17
|
+
getVaultSecretsConfigs,
|
|
18
18
|
} from '../next/config.js';
|
|
19
19
|
|
|
20
20
|
async function ensureDirectoryExists(dirPath) {
|
package/src/auth0/metadata.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import fs from 'fs-extra';
|
|
2
2
|
import axios from 'axios';
|
|
3
3
|
import path from 'path';
|
|
4
|
-
import { cloneRepository } from '../next/deploy.js';
|
|
4
|
+
import { cloneRepository, pushDeployConfig } from '../next/deploy.js';
|
|
5
5
|
import { getAuth0AuthToken } from './configure.js';
|
|
6
6
|
import { getVaultSecrets } from './vault.js';
|
|
7
7
|
import { getVaultSecretsConfigs } from '../next/config.js';
|
|
8
|
-
import { pushDeployConfig } from '../next/deploy.js';
|
|
9
8
|
|
|
10
9
|
export async function getAuth0Metadata(site, env) {
|
|
11
10
|
try {
|
package/src/changeset/cli.js
CHANGED
|
@@ -1,157 +1,100 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { Command } from 'commander';
|
|
3
3
|
import { $ } from 'zx';
|
|
4
|
-
import path from 'path';
|
|
5
4
|
import { validateChangesets } from './validate.js';
|
|
6
|
-
import fs from 'fs';
|
|
7
|
-
import OpenAI from 'openai';
|
|
8
|
-
import { zodResponseFormat } from 'openai/helpers/zod';
|
|
9
|
-
import z from 'zod';
|
|
10
5
|
import dotenv from 'dotenv';
|
|
11
|
-
import {
|
|
6
|
+
import { isMonoRepo, setGitInfo } from '../next/util.js';
|
|
7
|
+
import { updateJiraWithVersion, versionCommand } from './version.js';
|
|
8
|
+
import { createChangeset } from './create.js';
|
|
9
|
+
|
|
12
10
|
dotenv.config({ path: ['.env.pipeline.local', 'config/.env.pipeline.local'] });
|
|
13
11
|
|
|
14
12
|
const program = new Command();
|
|
15
13
|
|
|
16
14
|
const args = process.argv;
|
|
17
15
|
|
|
18
|
-
async function
|
|
19
|
-
|
|
20
|
-
// Use path.join to build a safe path to `.changeset`
|
|
21
|
-
const targetDir = path.join(process.cwd(), '.changeset');
|
|
16
|
+
async function commitTagCommand(releases) {
|
|
17
|
+
console.log('📌 Checking for updates to commit...');
|
|
22
18
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
console.
|
|
19
|
+
// Check if there are changes to commit
|
|
20
|
+
const status = (await $`git status --porcelain`).stdout.trim();
|
|
21
|
+
if (!status) {
|
|
22
|
+
console.log('✅ No changes to commit. Exiting.');
|
|
23
|
+
return;
|
|
27
24
|
}
|
|
28
|
-
}
|
|
29
25
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
if (error) {
|
|
34
|
-
reject(error);
|
|
35
|
-
} else {
|
|
36
|
-
resolve({ stdout, stderr });
|
|
37
|
-
}
|
|
38
|
-
});
|
|
39
|
-
});
|
|
40
|
-
}
|
|
26
|
+
console.log('📌 Committing and tagging the new version...');
|
|
27
|
+
await setGitInfo();
|
|
28
|
+
await $`git add .`;
|
|
41
29
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
} catch {
|
|
47
|
-
return false;
|
|
30
|
+
if (isMonoRepo()) {
|
|
31
|
+
await commitTagMono(releases);
|
|
32
|
+
} else {
|
|
33
|
+
await commitTag();
|
|
48
34
|
}
|
|
49
35
|
}
|
|
50
36
|
|
|
51
|
-
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
const packageJson = JSON.parse(fileContent);
|
|
58
|
-
return packageJson;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
throw new Error('Main package.json not found');
|
|
37
|
+
export function getAppReleases(releases) {
|
|
38
|
+
const appReleases = releases.filter(
|
|
39
|
+
(release) =>
|
|
40
|
+
release.name.endsWith('-app') || release.name.endsWith('-template'),
|
|
41
|
+
);
|
|
42
|
+
return appReleases;
|
|
62
43
|
}
|
|
63
44
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
await $`git remote set-url origin https://${process.env.THIS_REP_TOKEN}@bitbucket.org/${process.env.BITBUCKET_REPO_FULL_NAME}.git`;
|
|
69
|
-
}
|
|
45
|
+
function getAppNameFromPackageName(packageName) {
|
|
46
|
+
const appName = packageName.includes('/')
|
|
47
|
+
? packageName.split('/')[1]
|
|
48
|
+
: packageName;
|
|
70
49
|
|
|
71
|
-
|
|
72
|
-
"name": "changeset-package",
|
|
73
|
-
"version": "1.0.0",
|
|
74
|
-
"description": "",
|
|
75
|
-
"scripts": {
|
|
76
|
-
},
|
|
77
|
-
"type": "module",
|
|
78
|
-
"keywords": [],
|
|
79
|
-
"author": "",
|
|
80
|
-
"license": "ISC",
|
|
81
|
-
"dependencies": {},
|
|
82
|
-
"devDependencies": {
|
|
83
|
-
"@changesets/cli": "^2.27.10"
|
|
84
|
-
}
|
|
50
|
+
return appName;
|
|
85
51
|
}
|
|
86
|
-
`;
|
|
87
52
|
|
|
88
|
-
async function
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
await $`pnpm install`;
|
|
95
|
-
await $`rm package.json pnpm-lock.yaml`;
|
|
96
|
-
await $`mv package.json.bak package.json`;
|
|
97
|
-
await $`mv pnpm-lock.yaml.bak pnpm-lock.yaml`;
|
|
98
|
-
if (closeVersion) {
|
|
99
|
-
await $`pnpm changeset pre exit`;
|
|
53
|
+
async function commitTagMono(releases) {
|
|
54
|
+
let versions = [];
|
|
55
|
+
for (const release of getAppReleases(releases)) {
|
|
56
|
+
const newVersion = release.newVersion;
|
|
57
|
+
const appName = getAppNameFromPackageName(release.name);
|
|
58
|
+
versions.push(`${appName}@${newVersion}`);
|
|
100
59
|
}
|
|
101
60
|
|
|
102
|
-
await $`
|
|
61
|
+
const { stdout } = await $`git symbolic-ref refs/remotes/origin/HEAD`;
|
|
62
|
+
const defaultBranch = stdout.trim().replace('refs/remotes/origin/', '');
|
|
103
63
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
await
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
const packageName = packageJson.name;
|
|
110
|
-
|
|
111
|
-
if (closeVersion) {
|
|
112
|
-
return { version, packageName };
|
|
64
|
+
if (!process.env.IS_DEV) {
|
|
65
|
+
await $`git commit -m "Version bump to ${versions.join(',')} and changelog"`;
|
|
66
|
+
await $`git push origin ${defaultBranch}`;
|
|
67
|
+
} else {
|
|
68
|
+
console.log(`Simulate Version bump to ${versions.join(',')} and changelog`);
|
|
113
69
|
}
|
|
114
70
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
// If we have all the necessary data, update the component version in Jira
|
|
123
|
-
if (jiraTicketId && version && packageName) {
|
|
124
|
-
try {
|
|
125
|
-
await updateComponentVersion(jiraTicketId, packageName, version);
|
|
126
|
-
} catch (error) {
|
|
127
|
-
console.error(
|
|
128
|
-
`Failed to update Jira component version: ${error.message}`,
|
|
129
|
-
);
|
|
71
|
+
for (const newVersion of versions) {
|
|
72
|
+
if (!process.env.IS_DEV) {
|
|
73
|
+
await $`git tag ${newVersion}`;
|
|
74
|
+
console.log(`✅ Version ${newVersion} tagged.`);
|
|
75
|
+
} else {
|
|
76
|
+
console.log(`✅ Simulate Version ${newVersion} tagged.`);
|
|
130
77
|
}
|
|
131
78
|
}
|
|
132
79
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
console.log('📌 Checking for updates to commit...');
|
|
139
|
-
|
|
140
|
-
// Check if there are changes to commit
|
|
141
|
-
const status = (await $`git status --porcelain`).stdout.trim();
|
|
142
|
-
if (!status) {
|
|
143
|
-
console.log('✅ No changes to commit. Exiting.');
|
|
144
|
-
return;
|
|
80
|
+
if (!process.env.IS_DEV) {
|
|
81
|
+
await $`git push origin --tags`;
|
|
82
|
+
console.log(`✅ Version pushed.`);
|
|
83
|
+
} else {
|
|
84
|
+
console.log(`✅ Simulate Version pushed.`);
|
|
145
85
|
}
|
|
86
|
+
}
|
|
146
87
|
|
|
147
|
-
|
|
148
|
-
await setGitInfo();
|
|
149
|
-
await $`git add .`;
|
|
88
|
+
async function commitTag() {
|
|
150
89
|
const newVersion = (
|
|
151
90
|
await $`node -p "require('./package.json').version"`
|
|
152
91
|
).stdout.trim();
|
|
92
|
+
|
|
93
|
+
const { stdout } = await $`git symbolic-ref refs/remotes/origin/HEAD`;
|
|
94
|
+
const defaultBranch = stdout.trim().replace('refs/remotes/origin/', '');
|
|
95
|
+
|
|
153
96
|
await $`git commit -m "Version bump to ${newVersion} and changelog"`;
|
|
154
|
-
await $`git push origin`;
|
|
97
|
+
await $`git push origin ${defaultBranch}`;
|
|
155
98
|
await $`git tag v${newVersion}`;
|
|
156
99
|
await $`git push origin --tags`;
|
|
157
100
|
console.log(`✅ Version ${newVersion} tagged and pushed.`);
|
|
@@ -159,17 +102,17 @@ async function commitTagCommand() {
|
|
|
159
102
|
|
|
160
103
|
// Command: validate
|
|
161
104
|
program
|
|
162
|
-
.command('validate
|
|
105
|
+
.command('validate')
|
|
163
106
|
.description('Validate changesets for the provided PR')
|
|
164
|
-
.action(async (
|
|
107
|
+
.action(async () => {
|
|
165
108
|
if (!process.env.BITBUCKET_PR_ID) {
|
|
166
109
|
return;
|
|
167
110
|
}
|
|
168
111
|
console.log('🔍 Validating changesets...');
|
|
169
112
|
try {
|
|
170
|
-
await validateChangesets(
|
|
113
|
+
await validateChangesets();
|
|
171
114
|
console.log('✅ Changeset validation passed.');
|
|
172
|
-
} catch
|
|
115
|
+
} catch {
|
|
173
116
|
console.error(
|
|
174
117
|
'❌ 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',
|
|
175
118
|
);
|
|
@@ -198,8 +141,9 @@ program
|
|
|
198
141
|
.description('Run versioning and commit-and-tag in sequence')
|
|
199
142
|
.action(async () => {
|
|
200
143
|
console.log('📦 Running all steps...');
|
|
201
|
-
await versionCommand();
|
|
202
|
-
await
|
|
144
|
+
const releases = await versionCommand();
|
|
145
|
+
await updateJiraWithVersion(releases);
|
|
146
|
+
await commitTagCommand(releases);
|
|
203
147
|
});
|
|
204
148
|
|
|
205
149
|
program
|
|
@@ -207,15 +151,21 @@ program
|
|
|
207
151
|
.description('Closes a version')
|
|
208
152
|
.action(async () => {
|
|
209
153
|
console.log('📦 Running all steps...');
|
|
210
|
-
const
|
|
211
|
-
await commitTagCommand();
|
|
154
|
+
const releases = await versionCommand(true);
|
|
155
|
+
await commitTagCommand(releases);
|
|
212
156
|
|
|
213
|
-
// Get current branch
|
|
214
157
|
const { stdout: currentBranch } = await $`git rev-parse --abbrev-ref HEAD`;
|
|
215
158
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
159
|
+
if (isMonoRepo()) {
|
|
160
|
+
for (const release of getAppReleases(releases)) {
|
|
161
|
+
const appName = getAppNameFromPackageName(release.name);
|
|
162
|
+
await $`git checkout -b release/${appName}/${release.newVersion}`;
|
|
163
|
+
await $`git push origin release/${appName}/${release.newVersion}`;
|
|
164
|
+
}
|
|
165
|
+
} else {
|
|
166
|
+
await $`git checkout -b release/${releases[0].newVersion}`;
|
|
167
|
+
await $`git push origin release/${releases[0].newVersion}`;
|
|
168
|
+
}
|
|
219
169
|
|
|
220
170
|
// Return to original branch
|
|
221
171
|
await $`git checkout ${currentBranch.trim()}`;
|
|
@@ -225,7 +175,6 @@ program
|
|
|
225
175
|
await $`git add .`;
|
|
226
176
|
await $`git commit -m "Open next alpha version"`;
|
|
227
177
|
await $`git push origin`;
|
|
228
|
-
|
|
229
178
|
});
|
|
230
179
|
|
|
231
180
|
program
|
|
@@ -234,100 +183,7 @@ program
|
|
|
234
183
|
'Creates a changeset based on the current branch and Jira ticket information',
|
|
235
184
|
)
|
|
236
185
|
.action(async () => {
|
|
237
|
-
|
|
238
|
-
const componentName = mainPackage.name;
|
|
239
|
-
|
|
240
|
-
try {
|
|
241
|
-
// Step 1: Get the current branch name
|
|
242
|
-
const branchName = (await $`git branch --show-current`).stdout.trim();
|
|
243
|
-
console.log(`Current branch: ${branchName}`);
|
|
244
|
-
|
|
245
|
-
// Step 2: Extract Jira ticket number (e.g., matching JIRA-1234 pattern)
|
|
246
|
-
const jiraTicketMatch = branchName.match(/([A-Z]+-\d+)/);
|
|
247
|
-
if (!jiraTicketMatch) {
|
|
248
|
-
throw new Error('No Jira ticket found in the branch name.');
|
|
249
|
-
}
|
|
250
|
-
const jiraTicketId = jiraTicketMatch[0];
|
|
251
|
-
|
|
252
|
-
const jiraBaseUrl = 'https://docupacellc.atlassian.net';
|
|
253
|
-
const jiraEmail = process.env.JIRA_API_EMAIL;
|
|
254
|
-
const jiraApiKey = process.env.JIRA_API_KEY;
|
|
255
|
-
const jiraFullApiKey = `${jiraEmail}:${jiraApiKey}`;
|
|
256
|
-
const jiraUrl = `${jiraBaseUrl}/rest/api/2/issue/${jiraTicketId}`;
|
|
257
|
-
const jiraResponse = await fetch(jiraUrl, {
|
|
258
|
-
headers: {
|
|
259
|
-
Authorization: `Basic ${Buffer.from(jiraFullApiKey).toString('base64')}`,
|
|
260
|
-
'Content-Type': 'application/json',
|
|
261
|
-
},
|
|
262
|
-
});
|
|
263
|
-
|
|
264
|
-
if (!jiraResponse.ok) {
|
|
265
|
-
throw new Error(
|
|
266
|
-
`Failed to fetch Jira ticket. Status: ${jiraResponse.status}`,
|
|
267
|
-
);
|
|
268
|
-
}
|
|
269
|
-
const jiraTicketData = await jiraResponse.json();
|
|
270
|
-
|
|
271
|
-
const jiraSummary = jiraTicketData.fields.summary;
|
|
272
|
-
|
|
273
|
-
console.log(
|
|
274
|
-
`Generating release notes for ${jiraTicketId} - ${jiraSummary}`,
|
|
275
|
-
);
|
|
276
|
-
|
|
277
|
-
const openaiClient = new OpenAI({
|
|
278
|
-
apiKey: process.env['OPENAI_API_KEY'],
|
|
279
|
-
});
|
|
280
|
-
|
|
281
|
-
const ChangeRequestSchema = z.object({
|
|
282
|
-
change_type: z.enum(['patch', 'minor']),
|
|
283
|
-
summary: z.string(),
|
|
284
|
-
jira_ticket_id: z.string(),
|
|
285
|
-
});
|
|
286
|
-
|
|
287
|
-
const openAiResponse = await openaiClient.chat.completions.create({
|
|
288
|
-
model: 'gpt-4o-mini',
|
|
289
|
-
messages: [
|
|
290
|
-
{
|
|
291
|
-
role: 'system',
|
|
292
|
-
content: `Process JSON from a Jira ticket to generate simple maximum 2 sentence release note for the ticket and determine the change type for bug it should be a patch for new feature it should be a minor change`,
|
|
293
|
-
},
|
|
294
|
-
{
|
|
295
|
-
role: 'user',
|
|
296
|
-
content: JSON.stringify(jiraTicketData),
|
|
297
|
-
},
|
|
298
|
-
],
|
|
299
|
-
response_format: zodResponseFormat(
|
|
300
|
-
ChangeRequestSchema,
|
|
301
|
-
'changeset_schema',
|
|
302
|
-
),
|
|
303
|
-
temperature: 0,
|
|
304
|
-
});
|
|
305
|
-
|
|
306
|
-
const assistantResponse = openAiResponse.choices[0].message.content;
|
|
307
|
-
const parsedResponse = JSON.parse(assistantResponse);
|
|
308
|
-
|
|
309
|
-
const { change_type, summary } = parsedResponse;
|
|
310
|
-
console.log(`Change type: ${change_type}`);
|
|
311
|
-
console.log(`Release note: ${summary}`);
|
|
312
|
-
|
|
313
|
-
// Step 5: Create a changeset .md file
|
|
314
|
-
const changesetContent = `---
|
|
315
|
-
"${componentName}": ${change_type}
|
|
316
|
-
---
|
|
317
|
-
|
|
318
|
-
${summary} [${jiraTicketId}]
|
|
319
|
-
`;
|
|
320
|
-
const changesetFile = `./.changeset/${jiraTicketId}.md`;
|
|
321
|
-
|
|
322
|
-
await createChangesetDirectory();
|
|
323
|
-
await fs.promises.writeFile(changesetFile, changesetContent);
|
|
324
|
-
console.log(`Created changeset file at ${changesetFile}`);
|
|
325
|
-
|
|
326
|
-
console.log('Done!');
|
|
327
|
-
} catch (err) {
|
|
328
|
-
console.error(`Error: ${err.message}`);
|
|
329
|
-
process.exit(1);
|
|
330
|
-
}
|
|
186
|
+
await createChangeset();
|
|
331
187
|
});
|
|
332
188
|
|
|
333
189
|
// Parse arguments
|