GitHub Releases is the
canonical changelog. Under the current process, each new release combines a
short, reviewed summary with a categorized list of merged pull requests.
Historical releases may contain generated notes only. The release tag and npm
package use the same stable version: npm-vX.Y.Z and
@openai/codex-security@X.Y.Z.
Pull request titles must follow this form:
<type>[optional scope][!]: <description>
Use a lowercase type beginning with a letter and containing only letters, digits, and hyphens. Use a lowercase scope when present. Start the description with a non-whitespace character and do not leave trailing whitespace. Examples:
feat(cli): add component scan planning
fix(windows): preserve Unicode paths
docs: explain scan cost limits
feat(sdk)!: remove the legacy result field
The title controls the generated release category:
| Title | Release category |
|---|---|
Any type with ! |
Breaking changes |
feat |
Features |
fix |
Fixes |
docs |
Documentation |
chore(release), release, test |
Excluded |
| Any other type | Other changes |
Use chore(release) for release preparation and test for test-only changes.
The legacy release type remains supported. Use these only for changes that
do not affect package users. A maintainer can apply skip-release-notes to
exclude another internal change. That manual label takes precedence over the
title category.
Dependabot checks npm packages, Python test dependencies, and GitHub Actions daily, including weekends. OpenAI dependencies have no release cooldown; other releases must be at least seven days old. Security updates do not wait for the version-update cooldown. Updates still require review and passing CI; nothing is merged automatically.
Keep @openai/codex and @openai/codex-sdk on the same exact version across the
TypeScript SDK, MCP app, and triage evals in evals/triage-finding. Dependabot
groups their updates across all three projects, and the SDK tests reject
mismatched pins or multiple locked SDK versions. The evals override Promptfoo's
transitive Codex SDK to the direct SDK dependency so it follows the same update.
Each pnpm project applies the same seven-day age policy to newly resolved
dependencies, including transitive packages, with openai and @openai/* exempt.
Committed lockfiles remain installable. The existing Socket release checks remain
in place.
While the package is on 0.x, ordinary changes, including features, use a
patch release. Breaking changes use a minor release and reset the patch to
zero. For example, changes after 0.1.23 propose 0.1.24, or 0.2.0 if any
included change is breaking. The category of a feature remains Features;
the category does not imply a minor version bump.
The release PR updater recognizes breaking changes from a ! in a
Conventional Commit title, a BREAKING CHANGE: or BREAKING-CHANGE: footer,
or the breaking-change label. skip-release-notes affects visibility, not
version impact. All merges and direct commits after the release boundary
count toward the next version, including documentation and internal changes.
Review this policy before enabling automation for 1.x.
node-release-pr runs after pushes to main and can be dispatched manually.
It defaults to a read-only preview. It does not merge, tag, publish, or change
the existing publication gates.
The updater opens one ready-for-review proposal on release/next-<base-version>
once a change reaches main after the current package version. It recomputes
the proposal's version from all changes since that package version first
reached main. Squash-merge release PRs, as required by this
repository's enabled merge method, so the whole proposal lands as one
release boundary commit. Generated PR titles and commit subjects use
chore(release): X.Y.Z, matching the proposed package version. Confirm the
squash commit subject uses the current PR title when merging. A later breaking
change updates the version and title on the same PR. Each update incorporates
the latest main and appends a commit; the updater never force-pushes.
A concurrent commit causes it to reread and
retry. It requests Codex review when the proposal files change. Updates that
only incorporate main keep CI current without repeating the same proposal
review. New suggestions for human-owned notes still appear in a comment.
Before merging the proposal, check CI and request a final Codex review
if the last review targets an older head.
If a run reports that GitHub has not exposed the updated PR head, manually rerun the updater with dry_run disabled after the PR catches up. This allows any deferred review request or note suggestions to be posted. Verify review on the current head before merging the proposal.
When the release version merges, the updater waits for another change to
reach main before opening the next proposal. An empty release cycle returns
action: "unchanged" without creating a branch or PR. Publication of the
previous version still has to complete and pass the verification steps below.
The updater leaves another open chore(release): or legacy release: PR
targeting main, including a manually prepared release, untouched and does not
open a duplicate. Finish or close that PR before enabling the new flow.
Closing an automated proposal
pauses its cycle; reopen it to resume. Retargeting it away from main also
pauses updates; restore its main base before resuming. Both ready proposals
and existing drafts receive updates. Existing drafts can be marked ready
without pausing the updater. Review the current head before merging if
main has advanced. The updater rechecks pause conditions before advancing
the branch. Changes to other files on the release branch, or to package
fields other than the version, also pause the
updater so those edits cannot be lost. These intentional pauses return
action: "held" and leave the workflow successful. Preserve or merge the
additional changes, then rerun the updater to resume.
The committed .github/release-notes.md is authoritative. The updater
drafts highlights from merged titles and lists marked breaking changes for
migration review; it does not infer migration instructions from source code.
Review and refine these suggestions before releasing.
- Edit the highlights or upgrade notes on the release PR branch. Keep the
surrounding
release-sectioncomments if you want to retain section boundaries. The bot refreshes a section only while it matches the last generated draft. An edit or deletion makes that section human-owned, and later updates preserve it. Custom prose outside the sections is preserved. - Later suggestions appear in a new bot comment on the same PR. They do not replace human-owned notes. The bot updates the version header and PR title but never rewrites the PR description. Review version-specific links in human-owned prose when the proposed version changes.
.github/release-pr-state.jsonrecords the cycle and section ownership. To explicitly regenerate a section, add"reset": trueto that section's state entry. The next run consumes the reset and resumes automatic updates. Restore any damaged section markers before resetting. Do not delete the state file to reset ownership. A section with missing ownership metadata is preserved until explicitly reset; missing state does not authorize replacing manual notes.- Deleting the notes file is preserved too. Restore reviewed notes, or explicitly reset the sections, before merging; publication requires the versioned notes file.
With an authenticated gh CLI, a local checkout can preview the plan with:
RELEASE_PR_DRY_RUN=true node sdk/typescript/scripts/release-pr.mjsThe preview may fetch missing Git objects locally, but performs no GitHub
writes. Its JSON output includes the proposed files and any reason the
updater would pause. After the workflow is on main, use its Run workflow
form with dry_run enabled to test the hosted read-only path.
To test writes, enable Allow GitHub Actions to create and approve pull requests
under the repository's Settings → Actions → General → Workflow permissions,
then manually dispatch the workflow with dry_run disabled. This permits a
single write run while automatic updates remain disabled. The workflow uses
the repository's GITHUB_TOKEN with Contents: write and Pull requests: write
by default; no separate App credentials are required. Preview runs use a separate
job with read-only permissions for both scopes.
Review the resulting PR and select Approve workflows to run in its merge
box to start hosted CI. GitHub requires this approval for PRs created or updated
with GITHUB_TOKEN. Check the Codex review on the current head as well, and
request it manually if the automated request has not started a review.
For CI to start without this approval, optionally configure a GitHub App
installed on this repository with Contents: write and Pull requests: write.
Set the RELEASE_APP_CLIENT_ID repository variable and RELEASE_APP_PRIVATE_KEY
secret. When the Client ID is configured, write runs request an App token scoped
to this repository; a missing or invalid private key fails the run. Previews
always use GITHUB_TOKEN. See GitHub's token documentation.
After the manual write run is verified, set the RELEASE_PR_ENABLED
repository variable to true to allow updates after pushes to main.
Remove it or set it to false to return push-triggered runs to previews.
Manual runs always honor their dry_run input, which defaults to a preview;
disabling automatic updates does not prevent an explicit manual write run.
Generated PRs leave the disclosure attestations unchecked for maintainer review.
- Choose the next stable version and update
sdk/typescript/package.json. Keep the lockfile version in sync when it records the package version. - Update
.github/release-notes.md. Its first line must be<!-- release-version: X.Y.Z -->with the exact package version. - Summarize the changes a user will notice. Call out required migration or compatibility work, link relevant public documentation, and leave the pull-request inventory to the generated section.
- Open a pull request with a strict Conventional Commit title such as
chore(release): 0.2.0. - Run the checks required by the changed files and record the results in the pull request. Do not merge until required CI, review, and public disclosure checks pass on the current commit.
Review the summary with the same standard as product documentation. Keep it specific, describe behavior before implementation, and do not include private repositories, systems, people, findings, links, or issue identifiers.
The release starts after the version bump reaches main and node-ci succeeds
for that exact commit:
node-release-cutverifies that the version increased, checks the reviewed summary, and creates the exactnpm-vX.Y.Ztag.node-releaseinstalls the committed dependency graph, tests and packs the package, publishes it to npm, and records npm provenance.node-github-releaseverifies the public package, provenance, tag, and archive before publishing the GitHub release. It prepends the reviewed summary to GitHub's categorized notes.
node-release generates the npm plugin payload from the canonical source under
plugins/codex-security/ during prepack. The generated
sdk/typescript/_bundled_plugin/ directory is not a committed release input;
do not prepare a release by editing or committing files there.
Monitor all three workflows. A version bump is not a completed release until the npm package and GitHub release both exist and match the tag.
Check the published state before announcing the release:
- The tag points to the merged release commit.
npm view @openai/codex-security@X.Y.Zreports the expected version and commit, and the provenance check passed innode-release.- The GitHub release is stable, has the correct title, and contains exactly one verified package archive.
- The newest version is marked Latest. A historical backfill is not.
- For releases created under this process, the reviewed highlights, category headings, documentation links, and full comparison link are correct. Historical releases may have generated notes only.
- Every merged pull request is included or has an intentional
skip-release-noteslabel.
Do not retarget a release tag or publish a second package under the same version. The workflows are designed to recover from partial publication while keeping the original tag and package identity.
To retry GitHub publication, run node-github-release from main with the
existing npm-vX.Y.Z tag. Supply the successful node-release run ID when
automatic lookup is not enough. The workflow verifies the npm artifact and
provenance again before it creates or updates the release.
To repair categories on an existing release, correct the merged pull request's
title or release label first, then rerun node-github-release for the tag. For
a release that predates .github/release-notes.md, start the existing release
body with this marker block. Keep a blank line between the end marker and the
generated notes:
<!-- codex-security-release-summary:start -->
Reviewed summary
<!-- codex-security-release-summary:end -->
Generated notes
The workflow preserves that marked summary and replaces the generated section. After any recovery or repair, repeat every verification step above and review the final public release body.