Skip to content

feat: add Express API changelog generation#319

Merged
shenbenson merged 1 commit intomasterfrom
dx-3144-add-express-api-to-changelog
Mar 6, 2026
Merged

feat: add Express API changelog generation#319
shenbenson merged 1 commit intomasterfrom
dx-3144-add-express-api-to-changelog

Conversation

@shenbenson
Copy link
Contributor

Parameterize api-diff.js to accept custom input/output paths via CLI args. Update generate-release workflow to diff both Platform and Express specs and combine release descriptions under section headers.

Ticket: DX-3144

Parameterize api-diff.js to accept custom input/output paths via CLI
args. Update generate-release workflow to diff both Platform and Express
specs and combine release descriptions under section headers.

Ticket: DX-3144

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@shenbenson shenbenson requested a review from a team as a code owner March 6, 2026 17:07

// Run the script with custom input/output paths
execSync(
`node scripts/api-diff.js ${path.join(scenarioDir, 'previous.json')} ${path.join(scenarioDir, 'current.json')} custom-output.md`

Check warning

Code scanning / CodeQL

Shell command built from environment values Medium test

This shell command depends on an uncontrolled
absolute path
.

Copilot Autofix

AI 5 days ago

In general, the best way to fix this kind of issue is to avoid building a single shell command string that is interpreted by a shell. Instead, call the program directly and pass arguments as an array to execFileSync/spawn or use the argument-array form of execSync, so the Node runtime handles argument escaping and no shell interpretation occurs.

For this specific test, we should change the vulnerable execSync call on line 53 to use the options form: execSync(command, options) with shell: false and args represented explicitly. Since we already import execSync from child_process, and execSync supports an array via its args in child_process.execFileSync but not in execSync, the more direct and clearer fix here is to switch this one call to execFileSync, which takes (file, args[, options]) and does not invoke a shell. That keeps behavior the same (running node scripts/api-diff.js with three CLI arguments) while safely handling any special characters in paths.

Concretely:

  • Add execFileSync to the destructured import from child_process at the top of tests/generate-release.test.js.
  • Replace the interpolated-string execSync call in the "supports custom file paths via CLI args" test with an execFileSync call: execFileSync('node', ['scripts/api-diff.js', path.join(...), path.join(...), 'custom-output.md']);.
  • Leave the earlier execSync('node scripts/api-diff.js'); alone, since it uses only hard-coded literals and is not part of the tainted flow.

No new helper methods are needed; just the additional import and the changed call.

Suggested changeset 1
tests/generate-release.test.js

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/tests/generate-release.test.js b/tests/generate-release.test.js
--- a/tests/generate-release.test.js
+++ b/tests/generate-release.test.js
@@ -1,6 +1,6 @@
 const fs = require('fs');
 const path = require('path');
-const { execSync } = require('child_process');
+const { execSync, execFileSync } = require('child_process');
 const { describe, it, beforeEach, afterEach } = require('node:test');
 const assert = require('node:assert');
 
@@ -49,9 +49,12 @@
     const scenarioDir = path.join(FIXTURES_DIR, 'new-route-and-method');
 
     // Run the script with custom input/output paths
-    execSync(
-      `node scripts/api-diff.js ${path.join(scenarioDir, 'previous.json')} ${path.join(scenarioDir, 'current.json')} custom-output.md`
-    );
+    execFileSync('node', [
+      'scripts/api-diff.js',
+      path.join(scenarioDir, 'previous.json'),
+      path.join(scenarioDir, 'current.json'),
+      'custom-output.md',
+    ]);
 
     const actual = fs.readFileSync('custom-output.md', 'utf8').trim();
     const expected = fs.readFileSync(
EOF
@@ -1,6 +1,6 @@
const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');
const { execSync, execFileSync } = require('child_process');
const { describe, it, beforeEach, afterEach } = require('node:test');
const assert = require('node:assert');

@@ -49,9 +49,12 @@
const scenarioDir = path.join(FIXTURES_DIR, 'new-route-and-method');

// Run the script with custom input/output paths
execSync(
`node scripts/api-diff.js ${path.join(scenarioDir, 'previous.json')} ${path.join(scenarioDir, 'current.json')} custom-output.md`
);
execFileSync('node', [
'scripts/api-diff.js',
path.join(scenarioDir, 'previous.json'),
path.join(scenarioDir, 'current.json'),
'custom-output.md',
]);

const actual = fs.readFileSync('custom-output.md', 'utf8').trim();
const expected = fs.readFileSync(
Copilot is powered by AI and may make mistakes. Always verify output.
Copy link
Contributor

@starfy84 starfy84 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems fine to me

@shenbenson shenbenson merged commit 05c1575 into master Mar 6, 2026
4 checks passed
@shenbenson shenbenson deleted the dx-3144-add-express-api-to-changelog branch March 6, 2026 18:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants