Skip to content

add: automated release of goodsdks packages - #58

Draft
L03TJ3 wants to merge 1 commit into
mainfrom
automate-release-packages
Draft

add: automated release of goodsdks packages#58
L03TJ3 wants to merge 1 commit into
mainfrom
automate-release-packages

Conversation

@L03TJ3

@L03TJ3 L03TJ3 commented Jul 29, 2026

Copy link
Copy Markdown
Collaborator

Description

This PR adds automated npm release flow for the publishable @goodsdks/* packages.

What changed

  • Added .github/workflows/release-packages.yml:
    • Runs on main pushes (with release-loop guard).
    • Supports manual workflow_dispatch modes for recover and bootstrap.
    • Prepares package versions, updates lockfile, commits release versions, tags, publishes, and verifies npm registry state.
  • Added release tooling under scripts/release/:
    • config.mjs: release allowlist + consumer cascade map.
    • release-lib.mjs: changed-file detection, release relevance filters, dependency cascade, semver helpers.
    • release.mjs: prepare/verify/pack/tag/publish/bootstrap/check-bootstrap commands.
    • validate-packages.mjs: enforces publishable package manifest invariants.
    • release.test.mjs: tests package selection, cascade behavior, and release marker handling.
  • Added root scripts:
    • yarn release:plan
    • yarn release:test
    • yarn release:validate

Motivation

Automate safe, repeatable package publishing while keeping release decisions deterministic in git and recoverable after partial registry failures.

How has this been tested?

  • yarn release:test
  • yarn release:validate

Checklist

  • I have performed a self-review of my own code
  • My changes generate no new warnings in targeted validation
  • New and existing release tests pass locally
  • I have added a detailed description of the changes proposed in the pull request

@sirpy

sirpy commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

@copilot update PR description and review code

Copilot AI commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

@copilot update PR description and review code

Updated the PR description with full scope, motivation, and test details. I also reviewed the release automation changes in commit 8344681 and validated them with:

  • yarn release:test
  • yarn release:validate

Both checks passed.

Copilot AI left a comment

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.

Pull request overview

This PR introduces an automated, deterministic npm release pipeline for the publishable @goodsdks/* workspaces, backed by repo-local release tooling and manifest validation, and tightens deployment/security posture for Vercel workflows and browser bundling.

Changes:

  • Added a GitHub Actions workflow to plan/version/tag/publish affected packages on main pushes, plus manual bootstrap/recover modes.
  • Introduced release tooling under scripts/release/ (package allowlist + cascade rules, changed-file based selection, version planning, publish/verify helpers, and tests).
  • Standardized publishable package manifests for npm (MIT licensing, repository metadata, files: ["dist"], and consistent workspace ranges), plus safer env handling in Vite/Vercel deploy flows.

Reviewed changes

Copilot reviewed 27 out of 29 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
yarn.lock Align internal workspace dependency selectors to workspace:^ to support publishing/versioning invariants.
scripts/scan-build-secrets.mjs New script to scan built assets for leaked CI/Vercel/npm secret values before deployment.
scripts/release/config.mjs Defines the publishable package allowlist, topological order, and consumer cascade map.
scripts/release/release-lib.mjs Implements release relevance detection, package selection/cascade logic, and semver helpers.
scripts/release/release.mjs Release CLI implementing plan/prepare/verify/pack/tag/publish/bootstrap flows.
scripts/release/validate-packages.mjs Central validation of publishable package.json invariants prior to release.
scripts/release/release.test.mjs Node test runner coverage for selection/cascade, release marker, and semver helpers.
packages/ui-components/tsup.config.claim.ts Enables DTS generation for the claim button bundle.
packages/ui-components/package.json Adds exports/types, restricts shipped files to dist, and standardizes publish metadata.
packages/streaming-sdk/package.json Adds MIT license + repository metadata + public publishConfig.
packages/savings-widget/tsup.config.savings.ts Enables DTS generation for the savings widget bundle.
packages/savings-widget/package.json Adds exports/types, restricts shipped files to dist, and standardizes publish metadata.
packages/savings-sdk/package.json Restricts shipped files to dist and standardizes publish metadata.
packages/react-hooks/package.json Restricts shipped files to dist, standardizes publish metadata, and uses workspace:^ for internal deps.
packages/invite-sdk/package.json Switches lint script to tsc --noEmit, restricts shipped files to dist, and standardizes publish metadata.
packages/good-reserve/package.json Restricts shipped files to dist and standardizes publish metadata.
packages/engagement-sdk/package.json Restricts shipped files to dist and standardizes publish metadata.
packages/citizen-sdk/package.json Adjusts test command for CI suitability, updates CJS types export path, restricts shipped files, and standardizes publish metadata.
packages/bridging-sdk/package.json Restricts shipped files to dist and standardizes publish metadata.
package.json Adds MIT license and root release scripts (release:plan, release:test, release:validate).
LICENSE Adds MIT license text at repo root.
apps/demo-identity-app/vite.config.mts Stops injecting full process.env into the browser bundle; only provides NODE_ENV.
.gitignore Ignores .release/ artifacts and normalizes .npmrc entry formatting.
.github/workflows/vercel-preview-identity.yml Pins checkout/setup-node SHAs, adds read-only permissions, and prevents fork PRs from running with secrets.
.github/workflows/vercel-preview-engagement.yml Pins checkout/setup-node SHAs, adds read-only permissions, and prevents fork PRs from running with secrets.
.github/workflows/vercel-deploy-identity.yml New production deploy workflow on prod, with pinned Vercel CLI and secret-leak scan gate.
.github/workflows/vercel-deploy-engagement.yml Hardens production deploy on main (permissions, concurrency, pinned CLI, env var adjustments).
.github/workflows/release-packages.yml New automated release workflow (plan/prepare/lockfile commit/tags/publish + manual recover/bootstrap).
.github/CODEOWNERS Adds code ownership for workflows and release scripts.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +6 to +9
const buildDirectory = path.resolve(process.argv[2] ?? "")
if (!process.argv[2] || !statSync(buildDirectory).isDirectory()) {
throw new Error("Usage: scan-build-secrets.mjs <build-directory>")
}
Comment on lines +2 to +7
import assert from "node:assert/strict"
import { readFileSync } from "node:fs"
import path from "node:path"
import { packageByName, packages } from "./config.mjs"

const root = path.resolve(import.meta.dirname, "../..")
Comment on lines +29 to +37
const leaks = []
for (const filename of files(buildDirectory)) {
const content = readFileSync(filename)
for (const [name, value] of candidates) {
if (content.includes(Buffer.from(value))) leaks.push(`${name} in ${path.relative(buildDirectory, filename)}`)
}
}
if (leaks.length) throw new Error(`Secret values found in production assets:\n${leaks.join("\n")}`)
console.log(`Scanned ${files(buildDirectory).length} production files for ${candidates.length} CI secrets`)
for (const group of ["dependencies", "devDependencies", "peerDependencies"]) {
for (const [name, range] of Object.entries(manifest[group] ?? {})) {
if (packageByName.has(name) && group !== "peerDependencies") {
assert.match(range, /^workspace:\^$/, `${manifest.name} has an unpinned workspace range`)
Comment on lines +2 to +18
import { execFileSync } from "node:child_process"
import { mkdirSync, readFileSync, writeFileSync } from "node:fs"
import path from "node:path"
import process from "node:process"
import { packageByName, packages, RELEASE_MARKER } from "./config.mjs"
import {
cascadePackages,
changedFiles,
compareVersions,
directPackagesForFiles,
gitOutput,
isReleaseCommit,
packageVersion,
patchVersion,
} from "./release-lib.mjs"

const root = path.resolve(import.meta.dirname, "../..")
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.

4 participants