Skip to content

refactor(ci): unify npm publish logic and improve workflows#58

Merged
vrdons merged 4 commits intomainfrom
refactor/ci
Mar 8, 2026
Merged

refactor(ci): unify npm publish logic and improve workflows#58
vrdons merged 4 commits intomainfrom
refactor/ci

Conversation

@vrdons
Copy link
Member

@vrdons vrdons commented Mar 8, 2026

No description provided.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly refactors the continuous integration (CI) scripts responsible for publishing packages to both GitHub Packages and the public npm registry. By extracting the core npm publishing logic into a dedicated utility function, the change aims to reduce code duplication, enhance maintainability, and ensure consistent publishing behavior across different release workflows.

Highlights

  • Centralized npm Publish Logic: Introduced a new publishTarball utility function in scripts/utils/npm.js to encapsulate the npm publish command and its associated logic (like determining dist-tag and provenance).
  • Refactored Release Workflows: The scripts/actions/github.js and scripts/actions/npm.js files were updated to utilize the new publishTarball function, removing duplicated npm publish command construction.
  • Improved Readability and Naming: Renamed the main asynchronous functions in scripts/actions/github.js and scripts/actions/npm.js from buildProject to runGitHubRelease and runNpmRelease respectively, and updated variable names like tempjson to releasePackageJson and github_token to githubToken.
Changelog
  • scripts/actions/github.js
    • Renamed buildProject function to runGitHubRelease.
    • Replaced manual npm publish command construction with a call to the new publishTarball utility.
    • Updated variable names from github_token to githubToken and tempjson to releasePackageJson for clarity.
    • Removed the exec import as its functionality is now encapsulated.
  • scripts/actions/npm.js
    • Renamed buildProject function to runNpmRelease.
    • Replaced manual npm publish command construction with a call to the new publishTarball utility, including provenance support.
    • Updated variable name from tempjson to releasePackageJson for clarity.
    • Removed the exec import as its functionality is now encapsulated.
  • scripts/utils/npm.js
    • Introduced a new publishTarball function that handles the construction and execution of the npm publish command, including logic for dist-tag and provenance.
    • The getNpmDistTag utility is now used internally by publishTarball.
Ignored Files
  • Ignored by pattern: .github/workflows/** (1)
    • .github/workflows/release.yml
Activity
  • No specific activity has been recorded for this pull request yet.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request refactors and unifies the npm publish logic into a new publishTarball utility function, reducing code duplication across github.js and npm.js action scripts and improving clarity through variable renaming. While the new publishTarball function is used safely, this refactoring has brought to light existing command injection vulnerabilities in the checkVersionExists utility function. This function interpolates package names and versions directly into shell commands, which could be exploited by a malicious contributor. I recommend updating utility functions to use safer alternatives like execFileSync that do not involve shell interpolation. Additionally, consider improving the robustness of the command construction within the new publishTarball function.

Comment on lines +41 to +45
const npmVerExists = checkVersionExists(
releasePackageJson.name,
version,
GITHUB_URL
);
Copy link
Contributor

Choose a reason for hiding this comment

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

security-high high

The checkVersionExists function (defined in scripts/utils/npm.js) is vulnerable to command injection because it interpolates its arguments directly into a shell command string. In this call, releasePackageJson.name and version are passed as arguments. These values are derived from package.json, which is an untrusted source in the context of CI/CD. An attacker could modify package.json to include shell metacharacters (e.g., ; touch /tmp/pwned), leading to arbitrary command execution in the CI environment. To remediate this, the checkVersionExists function should be updated to use execFileSync or spawnSync to pass arguments safely without shell interpolation.

Comment on lines +26 to +30
const npmVerExists = checkVersionExists(
releasePackageJson.name,
version,
NPM_URL
);
Copy link
Contributor

Choose a reason for hiding this comment

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

security-high high

The checkVersionExists function (defined in scripts/utils/npm.js) is vulnerable to command injection because it interpolates its arguments directly into a shell command string. In this call, releasePackageJson.name and version are passed as arguments. These values are derived from package.json, which is an untrusted source in the context of CI/CD. An attacker could modify package.json to include shell metacharacters, leading to arbitrary command execution in the CI environment. To remediate this, the checkVersionExists function should be updated to use execFileSync or spawnSync to pass arguments safely without shell interpolation.

Comment on lines +23 to +33
const { provenance = false } = options;
const distTag = getNpmDistTag(version);
const tagArg = distTag === "latest" ? "" : ` --tag ${distTag}`;
const provenanceArg = provenance ? " --provenance" : "";

exec(
`npm publish "${tarballPath}"${provenanceArg} --registry=${registry}${tagArg}`,
{
stdio: "inherit",
}
);
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

While the current command construction works, it relies on conditional variables (provenanceArg, tagArg) containing a leading space. This can be a bit fragile and harder to maintain. A more robust approach is to build an array of arguments and then join them. This makes the separation of arguments explicit and improves readability and maintainability.

    const { provenance = false } = options;
    const distTag = getNpmDistTag(version);

    const args = [];
    if (provenance) {
        args.push("--provenance");
    }
    args.push(`--registry=${registry}`);
    if (distTag !== "latest") {
        args.push("--tag", distTag);
    }

    exec(`npm publish "${tarballPath}" ${args.join(" ")}`, {
        stdio: "inherit",
    });

@github-advanced-security
Copy link

You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool.

What Enabling Code Scanning Means:

  • The 'Security' tab will display more code scanning analysis results (e.g., for the default branch).
  • Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results.
  • You will be able to see the analysis results for the pull request's branch on this overview once the scans have completed and the checks have passed.

For more information about GitHub Code Scanning, check out
the documentation.

@vrdons vrdons merged commit 62bf283 into main Mar 8, 2026
5 checks passed
@vrdons vrdons deleted the refactor/ci branch March 8, 2026 09:46
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.

1 participant