@docupace/pipeline 1.0.86 → 1.0.87
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/designs/convert-to-canny.md +20 -0
- package/package.json +10 -4
- package/src/auth0/configure.js +1 -3
- package/src/changeset/canny.js +119 -0
- package/src/changeset/changelog-module.cjs +37 -0
- package/src/changeset/changelog.js +210 -0
- package/src/changeset/cli.js +27 -42
- package/src/changeset/config.js +20 -0
- package/src/changeset/convert.js +461 -0
- package/src/changeset/create-canny.js +86 -0
- package/src/changeset/create-simple.js +131 -0
- package/src/changeset/create.js +41 -123
- package/src/changeset/openai.js +567 -0
- package/src/changeset/validate.js +1 -12
- package/src/changeset/version.js +25 -3
- package/src/index.mjs +2 -0
- package/src/lib/merge-driver.js +1 -5
- package/src/merge/cli-merge-all.js +1 -2
- package/src/merge/cli-merge.js +4 -4
- package/src/merge/merge-changelog.js +1 -1
- package/src/merge/pr.js +3 -3
- package/src/next/connect.js +0 -9
- package/src/next/deploy.js +2 -2
- package/src/next/jira.js +51 -0
- package/src/next/util.js +1 -1
- package/testCanny.sh +4 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#Overview
|
|
2
|
+
|
|
3
|
+
Implement support for converting release notes to canny approach. This requires us to reprocess release notes from a specified version and up and generate via AI using existing functions the yaml files and then using those same yaml files upload to canny. This process is split into to parts convert-prepare, convert-complete
|
|
4
|
+
|
|
5
|
+
# Implementation
|
|
6
|
+
|
|
7
|
+
## convert-prepare
|
|
8
|
+
|
|
9
|
+
Add to src/changeset/cli.js convert-prepare with input parameter version id which will include major and minor version
|
|
10
|
+
In a new file convert.js add function convertPrepare which will perform the following logic:
|
|
11
|
+
- Process changelog MD to extract list of Jira tickets from the version specified up to the latest version. Please see example changelog /Users/fielm/Documents/Docupace/GraphQL/docupace-graphql-server/CHANGELOG.md
|
|
12
|
+
- For each Jira ticket call const { enhancedNotes, yamlFilePath, mainTicketId, summary } = await getReleaseNotes(jiraTicketId);
|
|
13
|
+
- Replace in CHANGELOG.md file the Jira ticket id [DC-XXXX] with [[${taskTicketId}]](${JIRA_BASE_URL}/browse/${taskTicketId}) [[details]](${relYamlFilePath})`;
|
|
14
|
+
- Note: do not use the summary returned by getReleaseNotes we will leave the existing summary
|
|
15
|
+
|
|
16
|
+
## convert-complete
|
|
17
|
+
- Create new function similar to updateDetailsLinkInText in src/changeset/changelog.js to support multiple links
|
|
18
|
+
- Call this function passing passing fetchNewLink and contents of the changelog.md file
|
|
19
|
+
- Update the changelog.md file with the results which should have now links to canny
|
|
20
|
+
|
package/package.json
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@docupace/pipeline",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.87",
|
|
4
|
+
"description": "",
|
|
4
5
|
"main": "index.js",
|
|
5
6
|
"type": "module",
|
|
7
|
+
"exports": {
|
|
8
|
+
"./changelogCanny": "./src/changeset/changelog-module.cjs"
|
|
9
|
+
},
|
|
6
10
|
"bin": {
|
|
7
11
|
"dp-changeset-cli": "src/changeset/cli.js",
|
|
8
12
|
"dp-next-cli": "src/next/cli.js",
|
|
@@ -17,9 +21,9 @@
|
|
|
17
21
|
"license": "ISC",
|
|
18
22
|
"dependencies": {
|
|
19
23
|
"@changesets/cli": "^2.27.10",
|
|
20
|
-
"@docupace/
|
|
21
|
-
"@docupace/pipeline": "^1.0.12",
|
|
24
|
+
"@docupace/pipeline": "^1.0.86",
|
|
22
25
|
"@jest/globals": "^30.1.2",
|
|
26
|
+
"@docupace/core-client": "^0.1.59",
|
|
23
27
|
"auth0-deploy-cli": "^8.8.0",
|
|
24
28
|
"axios": "^1.7.9",
|
|
25
29
|
"commander": "^12.1.0",
|
|
@@ -29,6 +33,7 @@
|
|
|
29
33
|
"inquirer": "^12.6.1",
|
|
30
34
|
"js-yaml": "^4.1.0",
|
|
31
35
|
"lodash": "^4.17.21",
|
|
36
|
+
"node-fetch": "^3.3.2",
|
|
32
37
|
"openai": "^4.76.3",
|
|
33
38
|
"semver": "^7.7.2",
|
|
34
39
|
"zod": "^3.24.1",
|
|
@@ -52,6 +57,7 @@
|
|
|
52
57
|
"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",
|
|
53
58
|
"test-run-pipline": "dp-next-cli run-pipeline -r docupace-next-e2e -b master -p run-tests-qa",
|
|
54
59
|
"test-validate": "dp-changset-cli validate",
|
|
55
|
-
"test-create": "dp-changset-cli create-changeset"
|
|
60
|
+
"test-create": "dp-changset-cli create-changeset",
|
|
61
|
+
"lint:fix": "eslint --fix \"src/**/*.{js,jsx,ts,tsx}\""
|
|
56
62
|
}
|
|
57
63
|
}
|
package/src/auth0/configure.js
CHANGED
|
@@ -812,7 +812,7 @@ export async function configureFromSite(
|
|
|
812
812
|
|
|
813
813
|
const envConfig = environmentConfig[toEnv];
|
|
814
814
|
|
|
815
|
-
let CORE_URL, SITE_HOST,
|
|
815
|
+
let CORE_URL, SITE_HOST, CONNECT_URL, DOCUPACE_HOST;
|
|
816
816
|
const newUrl = envConfig.newUrl(toSite);
|
|
817
817
|
const ccUrl = envConfig.ccUrl(toSite);
|
|
818
818
|
|
|
@@ -822,14 +822,12 @@ export async function configureFromSite(
|
|
|
822
822
|
const newUrl = envConfig.newUrl(toSite);
|
|
823
823
|
CORE_URL = `${newUrl}/core`;
|
|
824
824
|
// SITE_HOST = newUrl;
|
|
825
|
-
CORE_API_CONTEXT = 'core';
|
|
826
825
|
CONNECT_URL = `${newUrl}/connect`;
|
|
827
826
|
DOCUPACE_HOST = envConfig.docupaceHost();
|
|
828
827
|
} else {
|
|
829
828
|
const oldUrl = envConfig.oldUrl(toSite);
|
|
830
829
|
CORE_URL = oldUrl;
|
|
831
830
|
// SITE_HOST = oldUrl;
|
|
832
|
-
CORE_API_CONTEXT = toSite;
|
|
833
831
|
CONNECT_URL = `${oldUrl}_ui`;
|
|
834
832
|
}
|
|
835
833
|
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fetch from 'node-fetch';
|
|
3
|
+
|
|
4
|
+
// Configuration
|
|
5
|
+
const CANNY_API_KEY = process.env.CANNY_API_KEY;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Upload release notes to Canny
|
|
9
|
+
* @param {Object} releaseNote - The release note data
|
|
10
|
+
* @returns {Promise<Object>} - The full Canny entry object
|
|
11
|
+
*/
|
|
12
|
+
export async function uploadToCanny(releaseNote, labelIDs) {
|
|
13
|
+
if (!CANNY_API_KEY) {
|
|
14
|
+
console.warn('Canny API key not provided. Skipping upload.');
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
// Prepare the content for Canny based on the release notes
|
|
20
|
+
const title = releaseNote.title;
|
|
21
|
+
let content = '';
|
|
22
|
+
|
|
23
|
+
// Include user-facing description if available
|
|
24
|
+
if (
|
|
25
|
+
releaseNote.userFacingDescription &&
|
|
26
|
+
releaseNote.userFacingDescription.__line.trim()
|
|
27
|
+
) {
|
|
28
|
+
content += `${releaseNote.summary}\n\n`;
|
|
29
|
+
content += `${releaseNote.userFacingDescription.__line}\n\n`;
|
|
30
|
+
} else {
|
|
31
|
+
content += `${releaseNote.summary}\n\n`;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Include technical details if available
|
|
35
|
+
if (
|
|
36
|
+
releaseNote.technicalDescription &&
|
|
37
|
+
releaseNote.technicalDescription.__line.trim()
|
|
38
|
+
) {
|
|
39
|
+
content += `**Technical Details**\n\n${releaseNote.technicalDescription.__line}\n\n`;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Add JIRA reference
|
|
43
|
+
content += `**Reference**: JIRA ticket [${releaseNote.ticketId}]`;
|
|
44
|
+
|
|
45
|
+
// Map our changeType to Canny's type parameter
|
|
46
|
+
let entryType;
|
|
47
|
+
if (releaseNote.changeType === 'New') {
|
|
48
|
+
entryType = 'new';
|
|
49
|
+
} else if (releaseNote.changeType === 'Improved') {
|
|
50
|
+
entryType = 'improved';
|
|
51
|
+
} else if (releaseNote.changeType === 'Fixed') {
|
|
52
|
+
entryType = 'fixed';
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const body = JSON.stringify({
|
|
56
|
+
apiKey: CANNY_API_KEY,
|
|
57
|
+
title: title,
|
|
58
|
+
details: content,
|
|
59
|
+
type: entryType,
|
|
60
|
+
published: false, // Keep as draft initially
|
|
61
|
+
labelIDs,
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// Create a new changelog entry in Canny
|
|
65
|
+
const createResponse = await fetch(
|
|
66
|
+
'https://canny.io/api/v1/entries/create',
|
|
67
|
+
{
|
|
68
|
+
method: 'POST',
|
|
69
|
+
headers: {
|
|
70
|
+
'Content-Type': 'application/json',
|
|
71
|
+
},
|
|
72
|
+
body,
|
|
73
|
+
},
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
if (!createResponse.ok) {
|
|
77
|
+
console.error(`Error from Canny API: ${createResponse.statusText}`);
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const createData = await createResponse.json();
|
|
82
|
+
const entryId = createData.id;
|
|
83
|
+
|
|
84
|
+
// Fetch the complete entry details using the entries/list endpoint
|
|
85
|
+
const listResponse = await fetch('https://canny.io/api/v1/entries/list', {
|
|
86
|
+
method: 'POST',
|
|
87
|
+
headers: {
|
|
88
|
+
'Content-Type': 'application/json',
|
|
89
|
+
},
|
|
90
|
+
body: JSON.stringify({
|
|
91
|
+
apiKey: CANNY_API_KEY,
|
|
92
|
+
}),
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
if (!listResponse.ok) {
|
|
96
|
+
console.error(
|
|
97
|
+
`Error fetching entries list from Canny API: ${listResponse.statusText}`,
|
|
98
|
+
);
|
|
99
|
+
return createData; // Return just the create response as fallback
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const listData = await listResponse.json();
|
|
103
|
+
|
|
104
|
+
// Find the entry we just created in the list
|
|
105
|
+
const fullEntry = listData.entries.find((entry) => entry.id === entryId);
|
|
106
|
+
|
|
107
|
+
if (!fullEntry) {
|
|
108
|
+
console.warn(
|
|
109
|
+
`Created entry with ID ${entryId} not found in entries list. Returning partial data.`,
|
|
110
|
+
);
|
|
111
|
+
return createData;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return fullEntry;
|
|
115
|
+
} catch (error) {
|
|
116
|
+
console.error(`Error uploading to Canny: ${error.message}`);
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
async function getReleaseLine(changeset, type, changelogOpts) {
|
|
2
|
+
return (async () => {
|
|
3
|
+
try {
|
|
4
|
+
const { default: changelog } = await import('./changelog.js');
|
|
5
|
+
return await changelog.getReleaseLine(changeset, type, changelogOpts);
|
|
6
|
+
} catch (e) {
|
|
7
|
+
console.error(e);
|
|
8
|
+
process.exit(1);
|
|
9
|
+
}
|
|
10
|
+
// Now you can use `changelog` here
|
|
11
|
+
})();
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
async function getDependencyReleaseLine(
|
|
15
|
+
changesets,
|
|
16
|
+
dependenciesUpdated,
|
|
17
|
+
changelogOpts,
|
|
18
|
+
) {
|
|
19
|
+
return (async () => {
|
|
20
|
+
try {
|
|
21
|
+
const { default: changelog } = await import('./changelog.js');
|
|
22
|
+
return await changelog.getDependenciesReleaseLine(
|
|
23
|
+
changesets,
|
|
24
|
+
dependenciesUpdated,
|
|
25
|
+
changelogOpts,
|
|
26
|
+
); // Now you can use `changelog` here
|
|
27
|
+
} catch (e) {
|
|
28
|
+
console.error(e);
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
})();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
module.exports = {
|
|
35
|
+
getReleaseLine,
|
|
36
|
+
getDependencyReleaseLine,
|
|
37
|
+
};
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import defaultChangeLog from '@changesets/cli/changelog';
|
|
2
|
+
import { loadChangesetOutput } from './version.js';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import yaml from 'js-yaml';
|
|
5
|
+
import { getJiraReleaseNotes, updateJiraReleaseNotes } from '../next/jira.js';
|
|
6
|
+
import { uploadToCanny } from './canny.js';
|
|
7
|
+
import fs from 'fs';
|
|
8
|
+
import semver from 'semver';
|
|
9
|
+
import { componentConfig, labelIDMap } from './config.js';
|
|
10
|
+
import { findJiraTicketId } from './util.js';
|
|
11
|
+
|
|
12
|
+
async function updateDetailsLinkInText(text, processDetailsLink, params) {
|
|
13
|
+
const detailsLinkRegex = /\[\[details\]\]\((.*?)\)/;
|
|
14
|
+
|
|
15
|
+
const match = text.match(detailsLinkRegex);
|
|
16
|
+
if (!match) {
|
|
17
|
+
return text; // No details link found
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const originalLink = match[1];
|
|
21
|
+
const newLink = await processDetailsLink(originalLink, params);
|
|
22
|
+
|
|
23
|
+
const updatedText = text.replace(detailsLinkRegex, `[[details]](${newLink})`);
|
|
24
|
+
return updatedText;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Update multiple details links in text
|
|
29
|
+
* Similar to updateDetailsLinkInText but supports multiple [[details]](...) links
|
|
30
|
+
* @param {string} text - Text containing [[details]](link) patterns
|
|
31
|
+
* @param {Function} processDetailsLink - Function to process each link
|
|
32
|
+
* @param {Object} params - Parameters to pass to processDetailsLink
|
|
33
|
+
* @returns {Promise<string>} - Updated text with processed links
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
function getChanges(params) {
|
|
37
|
+
const changes = params.changeset.releases.map((release) => {
|
|
38
|
+
const matchingRelease = params.output.releases.find(
|
|
39
|
+
(r) => r.name === release.name,
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
const version = matchingRelease ? matchingRelease.newVersion : null;
|
|
43
|
+
const parsed = version ? semver.parse(version) : null;
|
|
44
|
+
|
|
45
|
+
return {
|
|
46
|
+
name: release.name,
|
|
47
|
+
type: release.type,
|
|
48
|
+
version,
|
|
49
|
+
majorMinor: parsed ? `${parsed.major}.${parsed.minor}` : null,
|
|
50
|
+
};
|
|
51
|
+
});
|
|
52
|
+
return changes;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function getLabels(changes) {
|
|
56
|
+
const labels = [];
|
|
57
|
+
for (const change of changes) {
|
|
58
|
+
const componentName = componentConfig[change.name];
|
|
59
|
+
if (componentName) {
|
|
60
|
+
const labelName = componentName;
|
|
61
|
+
if (!labels.includes(labelName)) {
|
|
62
|
+
labels.push(labelName);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return labels;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function getJiraVersions(changes) {
|
|
70
|
+
const versions = [];
|
|
71
|
+
for (const change of changes) {
|
|
72
|
+
const componentName = componentConfig[change.name];
|
|
73
|
+
if (componentName) {
|
|
74
|
+
const labelName = `${componentName} - ${change.majorMinor}`;
|
|
75
|
+
if (!versions.includes(labelName)) {
|
|
76
|
+
versions.push(labelName);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return versions;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async function getLabelIDs(labels) {
|
|
84
|
+
let cannyConfig;
|
|
85
|
+
try {
|
|
86
|
+
const cannyConfigPath = path.join(
|
|
87
|
+
process.cwd(),
|
|
88
|
+
'.changeset',
|
|
89
|
+
'canny.json',
|
|
90
|
+
);
|
|
91
|
+
cannyConfig = JSON.parse(fs.readFileSync(cannyConfigPath, 'utf-8'));
|
|
92
|
+
} catch (e) {
|
|
93
|
+
console.error('Canny read canny.json file', e);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const mergedLabelMap = { ...labelIDMap, ...cannyConfig?.labels };
|
|
97
|
+
return labels.map((label) => mergedLabelMap[label]);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function extractSummaryDescription(text) {
|
|
101
|
+
const lines = text.split(/\r?\n/);
|
|
102
|
+
|
|
103
|
+
// Start from the 5th line (index 4)
|
|
104
|
+
const summaryLines = [];
|
|
105
|
+
|
|
106
|
+
for (let i = 0; i < lines.length; i++) {
|
|
107
|
+
if (lines[i].startsWith('[[')) {
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
summaryLines.push(lines[i]);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return summaryLines.join('\n').trim();
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
async function fetchNewLink(oldLink, params) {
|
|
117
|
+
if (oldLink.includes('.yaml')) {
|
|
118
|
+
const normalizedOldLink = oldLink.replaceAll('\\', '/');
|
|
119
|
+
const yamlPath = path.resolve(
|
|
120
|
+
process.cwd(),
|
|
121
|
+
'.changeset',
|
|
122
|
+
normalizedOldLink,
|
|
123
|
+
);
|
|
124
|
+
const releaseNote = yaml.load(fs.readFileSync(yamlPath, 'utf-8'));
|
|
125
|
+
const ticketId = findJiraTicketId(params.changeset.id);
|
|
126
|
+
const mainTicketId = releaseNote.ticketId;
|
|
127
|
+
const summary = extractSummaryDescription(params.changeset.summary);
|
|
128
|
+
if (!ticketId) {
|
|
129
|
+
console.log('No ticket found in: ', JSON.stringify(params.changeset));
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const uploadToCannyInternal = async () => {
|
|
134
|
+
const changes = getChanges(params);
|
|
135
|
+
const jiraVersions = getJiraVersions(changes);
|
|
136
|
+
const labels = getLabels(changes);
|
|
137
|
+
const labelIDs = await getLabelIDs([...labels, ...jiraVersions]);
|
|
138
|
+
const data = await uploadToCanny(releaseNote, labelIDs);
|
|
139
|
+
return data;
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
const uploadToJiraInternal = async (ticketId, url) => {
|
|
143
|
+
const changes = getChanges(params);
|
|
144
|
+
const jiraVersions = getJiraVersions(changes);
|
|
145
|
+
await updateJiraReleaseNotes(ticketId, summary, url, jiraVersions);
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
const jiraReleaseInfo = await getJiraReleaseNotes(mainTicketId);
|
|
149
|
+
if (mainTicketId != ticketId) {
|
|
150
|
+
const subtaskJiraReleaseInfo = await getJiraReleaseNotes(ticketId);
|
|
151
|
+
if (subtaskJiraReleaseInfo?.url) {
|
|
152
|
+
return subtaskJiraReleaseInfo?.url;
|
|
153
|
+
} else {
|
|
154
|
+
if (jiraReleaseInfo?.url) {
|
|
155
|
+
await uploadToJiraInternal(ticketId, jiraReleaseInfo?.url);
|
|
156
|
+
return jiraReleaseInfo?.url;
|
|
157
|
+
} else {
|
|
158
|
+
const data = await uploadToCannyInternal();
|
|
159
|
+
await uploadToJiraInternal(ticketId, data.url);
|
|
160
|
+
await uploadToJiraInternal(mainTicketId, data.url);
|
|
161
|
+
return data.url;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
} else {
|
|
165
|
+
if (jiraReleaseInfo?.url) {
|
|
166
|
+
return jiraReleaseInfo.url;
|
|
167
|
+
} else {
|
|
168
|
+
const data = await uploadToCannyInternal();
|
|
169
|
+
await uploadToJiraInternal(mainTicketId, data.url);
|
|
170
|
+
return data.url;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
} else {
|
|
174
|
+
return oldLink;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
async function uploadChangeset(changeset) {
|
|
179
|
+
const output = await loadChangesetOutput();
|
|
180
|
+
const summary = await updateDetailsLinkInText(
|
|
181
|
+
changeset.summary,
|
|
182
|
+
fetchNewLink,
|
|
183
|
+
{ changeset, output },
|
|
184
|
+
);
|
|
185
|
+
return { ...changeset, summary };
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
async function getReleaseLine(changeset, type, changelogOpts) {
|
|
189
|
+
const newChangeset = await uploadChangeset(changeset);
|
|
190
|
+
return await defaultChangeLog.getReleaseLine(
|
|
191
|
+
newChangeset,
|
|
192
|
+
type,
|
|
193
|
+
changelogOpts,
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
async function getDependenciesReleaseLine(
|
|
198
|
+
changesets,
|
|
199
|
+
dependenciesUpdated,
|
|
200
|
+
changelogOpts,
|
|
201
|
+
) {
|
|
202
|
+
return await defaultChangeLog.getDependencyReleaseLine(
|
|
203
|
+
changesets,
|
|
204
|
+
dependenciesUpdated,
|
|
205
|
+
changelogOpts,
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
export default { getReleaseLine, getDependenciesReleaseLine };
|
|
210
|
+
export { fetchNewLink };
|
package/src/changeset/cli.js
CHANGED
|
@@ -10,10 +10,8 @@ import {
|
|
|
10
10
|
versionCommand,
|
|
11
11
|
} from './version.js';
|
|
12
12
|
import { createChangeset } from './create.js';
|
|
13
|
-
import {
|
|
14
|
-
|
|
15
|
-
upsertReleaseNotesFromFile,
|
|
16
|
-
} from './changelog-wiki.js';
|
|
13
|
+
import { updateWikiWithVersion } from './changelog-wiki.js';
|
|
14
|
+
import { convertPrepare, convertComplete } from './convert.js';
|
|
17
15
|
|
|
18
16
|
dotenv.config({ path: ['.env.pipeline.local', 'config/.env.pipeline.local'] });
|
|
19
17
|
|
|
@@ -93,14 +91,12 @@ async function commitTagMono(releases) {
|
|
|
93
91
|
}
|
|
94
92
|
|
|
95
93
|
async function commitTag() {
|
|
96
|
-
const newVersion = (
|
|
97
|
-
await $`node -p "require('./package.json').version"`
|
|
98
|
-
).stdout.trim();
|
|
99
|
-
|
|
100
94
|
if (process.env.IS_DEV) {
|
|
101
|
-
console.log(`Simulate commit of version ${newVersion}`);
|
|
102
95
|
return;
|
|
103
96
|
}
|
|
97
|
+
const newVersion = (
|
|
98
|
+
await $`node -p "require('./package.json').version"`
|
|
99
|
+
).stdout.trim();
|
|
104
100
|
|
|
105
101
|
const defaultBranch = process.env.BITBUCKET_BRANCH;
|
|
106
102
|
|
|
@@ -119,7 +115,16 @@ program
|
|
|
119
115
|
if (!process.env.BITBUCKET_PR_ID) {
|
|
120
116
|
return;
|
|
121
117
|
}
|
|
122
|
-
|
|
118
|
+
console.log('🔍 Validating changesets...');
|
|
119
|
+
try {
|
|
120
|
+
await validateChangesets();
|
|
121
|
+
console.log('✅ Changeset validation passed.');
|
|
122
|
+
} catch {
|
|
123
|
+
console.error(
|
|
124
|
+
'❌ 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',
|
|
125
|
+
);
|
|
126
|
+
process.exit(1);
|
|
127
|
+
}
|
|
123
128
|
});
|
|
124
129
|
// Command: version
|
|
125
130
|
program
|
|
@@ -197,40 +202,20 @@ program
|
|
|
197
202
|
await createChangeset();
|
|
198
203
|
});
|
|
199
204
|
|
|
205
|
+
// Command: convert-prepare
|
|
200
206
|
program
|
|
201
|
-
.command('
|
|
202
|
-
.description('
|
|
203
|
-
.
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
)
|
|
207
|
-
.requiredOption(
|
|
208
|
-
'-c, --component <component>',
|
|
209
|
-
'Component title (e.g., "Component A")',
|
|
210
|
-
)
|
|
211
|
-
.requiredOption('-f, --file <file>', 'Path to markdown file')
|
|
212
|
-
.requiredOption('-g, --group <group>', 'Group of release notes')
|
|
207
|
+
.command('convert-prepare <version> [changelogPath]')
|
|
208
|
+
.description('Convert release notes to Canny format - Part 1 (Prepare)')
|
|
209
|
+
.action(async (version, changelogPath) => {
|
|
210
|
+
await convertPrepare(version, changelogPath);
|
|
211
|
+
});
|
|
213
212
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
markdownFile: options.file,
|
|
221
|
-
group: options.group,
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
console.log('✅ Successfully uploaded to Confluence');
|
|
225
|
-
console.log('Version page:', versionPage._links?.webui || versionPage.id);
|
|
226
|
-
console.log(
|
|
227
|
-
'Component page:',
|
|
228
|
-
componentPage._links?.webui || componentPage.id,
|
|
229
|
-
);
|
|
230
|
-
} catch (error) {
|
|
231
|
-
console.error('❌ Error uploading to Confluence:', error.message);
|
|
232
|
-
process.exit(1);
|
|
233
|
-
}
|
|
213
|
+
// Command: convert-complete
|
|
214
|
+
program
|
|
215
|
+
.command('convert-complete [changelogPath]')
|
|
216
|
+
.description('Convert release notes to Canny format - Part 2 (Complete)')
|
|
217
|
+
.action(async (changelogPath) => {
|
|
218
|
+
await convertComplete(changelogPath);
|
|
234
219
|
});
|
|
235
220
|
|
|
236
221
|
// Parse arguments
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export const componentConfig = {
|
|
2
|
+
'@docupace/enterprise-ui-app': 'Enterprise',
|
|
3
|
+
'@docupace/cc-ui-app': 'C & C Application',
|
|
4
|
+
'@docupace/core': 'Enterprise Core',
|
|
5
|
+
'@docupace/graphql-server': 'Enterprise',
|
|
6
|
+
'@docupace/enterprise-template': 'Enterprise',
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const labelIDMap = {
|
|
10
|
+
Enterprise: '6836d53ad8622b2abab1fbd9',
|
|
11
|
+
'Enterprise Core': '6836d532716bbe32f53661fb',
|
|
12
|
+
'Enterprise Core - 25.0': '68400cea3c20ce44785cca3e',
|
|
13
|
+
'Enterprise Core - 25.1': '68401502fa2d977cfcd6e102',
|
|
14
|
+
'Enterprise Core - 25.2': '6840151b0915e310b1766005',
|
|
15
|
+
'Enterprise Core - 25.3': '684018c7f11b9e5d5d24936f',
|
|
16
|
+
'Enterprise Core - 25.4': '6914853cd07d92c594ab8c61',
|
|
17
|
+
'Enterprise Core - 25.5': '691485400eb37f0c0fdf75c5',
|
|
18
|
+
'Enterprise Core - 25.6': '69148545c0a13575489d609f',
|
|
19
|
+
'Enterprise Core - 25.7': '691485fcdd3accda32e16288',
|
|
20
|
+
};
|