Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/release-patch-1-create-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ jobs:
REPOSITORY: '${{ github.repository }}'
GITHUB_RUN_ID: '${{ github.run_id }}'
LOG_CONTENT: '${{ env.LOG_CONTENT }}'
BASE_VERSION: '${{ steps.create_patch.outputs.base_version }}'
NEW_VERSION: '${{ steps.create_patch.outputs.new_version }}'
continue-on-error: true
run: |
git checkout '${{ github.event.inputs.ref }}'
Expand Down
19 changes: 15 additions & 4 deletions scripts/releasing/create-patch-pr.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/

import { execSync } from 'node:child_process';
import { appendFileSync } from 'node:fs';
import yargs from 'yargs';
import { hideBin } from 'yargs/helpers';

Expand Down Expand Up @@ -44,9 +45,16 @@ async function main() {

const releaseInfo = getLatestReleaseInfo(channel);
const latestTag = releaseInfo.currentTag;
const nextVersion = releaseInfo.nextVersion;
Comment thread
skeshive marked this conversation as resolved.

// Expose versions for subsequent steps
if (process.env.GITHUB_OUTPUT) {
appendFileSync(process.env.GITHUB_OUTPUT, `base_version=${latestTag}\n`);
appendFileSync(process.env.GITHUB_OUTPUT, `new_version=${nextVersion}\n`);
Comment on lines +52 to +53

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

critical

There is a potential command injection vulnerability here. The latestTag and nextVersion variables are written to the file specified by process.env.GITHUB_OUTPUT without sanitization. If either of these variables contains a newline character, it could allow an attacker to inject additional outputs into the GitHub Actions workflow.

For example, if latestTag is v1.2.3\nmalicious_output=foo, the following would be written to the output file:

base_version=v1.2.3
malicious_output=foo

This would set an unexpected output malicious_output with value foo, which could be exploited in subsequent steps.

According to GitHub Actions documentation, multiline strings are not supported for outputs written to GITHUB_OUTPUT. You should sanitize the values to remove any newline characters before writing them.

Suggested change
appendFileSync(process.env.GITHUB_OUTPUT, `base_version=${latestTag}\n`);
appendFileSync(process.env.GITHUB_OUTPUT, `new_version=${nextVersion}\n`);
appendFileSync(process.env.GITHUB_OUTPUT, `base_version=${latestTag.replace(/\r|\n/g, '')}\n`);
appendFileSync(process.env.GITHUB_OUTPUT, `new_version=${nextVersion.replace(/\r|\n/g, '')}\n`);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@mattKorwel Could you advise if this is actually a threat? IIUC these scripts run within Github's action runner?

}

const releaseBranch = `release/${latestTag}`;
const hotfixBranch = `hotfix/${latestTag}/${channel}/cherry-pick-${commit.substring(0, 7)}`;
const hotfixBranch = `hotfix/${latestTag}/${nextVersion}/${channel}/cherry-pick-${commit.substring(0, 7)}`;

// Create the release branch from the tag if it doesn't exist.
if (!branchExists(releaseBranch)) {
Expand Down Expand Up @@ -184,11 +192,14 @@ async function main() {
console.log(
`Creating pull request from ${hotfixBranch} to ${releaseBranch}...`,
);
let prTitle = `fix(patch): cherry-pick ${commit.substring(0, 7)} to ${releaseBranch}`;
let prBody = `This PR automatically cherry-picks commit ${commit} to patch the ${channel} release.`;
let prTitle = `fix(patch): cherry-pick ${commit.substring(0, 7)} to ${nextVersion} (from ${latestTag})`;
let prBody = `This PR automatically cherry-picks commit \`${commit.substring(
0,
7,
)}\` to create patch release **${nextVersion}** for the \`${channel}\` release channel, based on version \`${latestTag}\`.`;

if (hasConflicts) {
prTitle = `fix(patch): cherry-pick ${commit.substring(0, 7)} to ${releaseBranch} [CONFLICTS]`;
prTitle = `fix(patch): cherry-pick ${commit.substring(0, 7)} to ${nextVersion} (from ${latestTag}) [CONFLICTS]`;
prBody += `

## ⚠️ Merge Conflicts Detected
Expand Down
8 changes: 8 additions & 0 deletions scripts/releasing/patch-create-comment.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ async function main() {
const repository =
argv.repository || process.env.REPOSITORY || 'google-gemini/gemini-cli';
const runId = argv.runId || process.env.GITHUB_RUN_ID || '0';
const baseVersion = argv.baseVersion || process.env.BASE_VERSION;
const newVersion = argv.newVersion || process.env.NEW_VERSION;

// Validate required parameters
if (!runId || runId === '0') {
Expand Down Expand Up @@ -107,6 +109,8 @@ async function main() {
console.log(` - Channel: ${channel} → npm tag: ${npmTag}`);
console.log(` - Repository: ${repository}`);
console.log(` - Run ID: ${runId}`);
console.log(` - Base Version: ${baseVersion}`);
console.log(` - New Version: ${newVersion}`);
}

let commentBody;
Expand Down Expand Up @@ -211,6 +215,8 @@ A patch branch [\`${branch}\`](https://github.com/${repository}/tree/${branch})

**📋 Patch Details:**
- **Channel**: \`${channel}\` → will publish to npm tag \`${npmTag}\`
- **Base Version**: \`${baseVersion}\`
- **New Version**: \`${newVersion}\`
- **Commit**: \`${commit}\`
- **Hotfix Branch**: [\`${branch}\`](https://github.com/${repository}/tree/${branch})
- **Hotfix PR**: [#${mockPrNumber}](${mockPrUrl})${hasConflicts ? '\n- **⚠️ Status**: Cherry-pick conflicts detected - manual resolution required' : ''}
Expand Down Expand Up @@ -266,6 +272,8 @@ ${hasConflicts ? '4' : '3'}. You'll receive updates here when the release comple

**📋 Patch Details:**
- **Channel**: \`${channel}\` → will publish to npm tag \`${npmTag}\`
- **Base Version**: \`${baseVersion}\`
- **New Version**: \`${newVersion}\`
- **Commit**: \`${commit}\`
- **Hotfix Branch**: [\`${branch}\`](https://github.com/${repository}/tree/${branch})
- **Hotfix PR**: [#${pr.number}](${pr.url})${hasConflicts ? '\n- **⚠️ Status**: Cherry-pick conflicts detected - manual resolution required' : ''}
Expand Down
Loading