-
Notifications
You must be signed in to change notification settings - Fork 0
release: start v0.1.1230 rc builds #3622
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,87 @@ | ||
| import { assertEquals, assertRejects } from "#veryfront/testing/assert.ts"; | ||
| import { describe, it } from "#veryfront/testing/bdd.ts"; | ||
| import { prepareRcBuildVersion } from "./prepare-rc-build.ts"; | ||
|
|
||
| async function createVersionFixture( | ||
| manifestVersion = "0.1.1230-rc", | ||
| sourceVersion = manifestVersion, | ||
| ): Promise<string> { | ||
| const rootDir = await Deno.makeTempDir(); | ||
| await Deno.mkdir(`${rootDir}/src/utils`, { recursive: true }); | ||
| await Deno.writeTextFile( | ||
| `${rootDir}/deno.json`, | ||
| JSON.stringify({ | ||
| name: "veryfront", | ||
| version: manifestVersion, | ||
| tasks: { "build:npm": "fixture" }, | ||
| }, null, 2) + "\n", | ||
| ); | ||
| await Deno.writeTextFile( | ||
| `${rootDir}/src/utils/version-constant.ts`, | ||
| `// Keep in sync with deno.json version.\nexport const VERSION = "${sourceVersion}";\n`, | ||
| ); | ||
| return rootDir; | ||
| } | ||
|
|
||
| describe("RC build version preparation", () => { | ||
| it("injects the published RC version into the manifest and source constant", async () => { | ||
| const rootDir = await createVersionFixture(); | ||
|
|
||
| try { | ||
| await prepareRcBuildVersion({ | ||
| rootDir, | ||
| version: "0.1.1230-rc.456", | ||
| }); | ||
|
|
||
| const manifest = JSON.parse(await Deno.readTextFile(`${rootDir}/deno.json`)); | ||
| assertEquals(manifest.version, "0.1.1230-rc.456"); | ||
| assertEquals(manifest.tasks["build:npm"], "fixture"); | ||
| assertEquals( | ||
| await Deno.readTextFile(`${rootDir}/src/utils/version-constant.ts`), | ||
| '// Keep in sync with deno.json version.\nexport const VERSION = "0.1.1230-rc.456";\n', | ||
| ); | ||
| } finally { | ||
| await Deno.remove(rootDir, { recursive: true }); | ||
| } | ||
| }); | ||
|
|
||
| it("rejects a publish version that is not the manifest prerelease plus a run number", async () => { | ||
| const rootDir = await createVersionFixture(); | ||
|
|
||
| try { | ||
| await assertRejects( | ||
| () => | ||
| prepareRcBuildVersion({ | ||
| rootDir, | ||
| version: "0.1.1231-rc.456", | ||
| }), | ||
| Error, | ||
| "must extend 0.1.1230-rc with a numeric run number", | ||
| ); | ||
| assertEquals( | ||
| JSON.parse(await Deno.readTextFile(`${rootDir}/deno.json`)).version, | ||
| "0.1.1230-rc", | ||
| ); | ||
| } finally { | ||
| await Deno.remove(rootDir, { recursive: true }); | ||
| } | ||
| }); | ||
|
|
||
| it("rejects source and manifest versions that are already out of sync", async () => { | ||
| const rootDir = await createVersionFixture("0.1.1230-rc", "0.1.1229-rc"); | ||
|
|
||
| try { | ||
| await assertRejects( | ||
| () => | ||
| prepareRcBuildVersion({ | ||
| rootDir, | ||
| version: "0.1.1230-rc.456", | ||
| }), | ||
| Error, | ||
| "does not match deno.json version", | ||
| ); | ||
| } finally { | ||
| await Deno.remove(rootDir, { recursive: true }); | ||
| } | ||
| }); | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,89 @@ | ||
| import { join } from "#std/path"; | ||
|
|
||
| type PrepareRcBuildVersionOptions = { | ||
| rootDir?: string; | ||
| version: string; | ||
| }; | ||
|
|
||
| const VERSION_CONSTANT_PATTERN = | ||
| /^export const VERSION = "([^"]+)";$/gm; | ||
|
|
||
| /** Inject the CI-generated RC version before npm build artifacts are created. */ | ||
| export async function prepareRcBuildVersion( | ||
| options: PrepareRcBuildVersionOptions, | ||
| ): Promise<void> { | ||
| const rootDir = options.rootDir ?? Deno.cwd(); | ||
| const manifestPath = join(rootDir, "deno.json"); | ||
| const versionConstantPath = join( | ||
| rootDir, | ||
| "src/utils/version-constant.ts", | ||
| ); | ||
| const manifestSource = await Deno.readTextFile(manifestPath); | ||
| const manifest = JSON.parse(manifestSource) as { version?: unknown }; | ||
| const baseVersion = manifest.version; | ||
|
|
||
| if (typeof baseVersion !== "string" || baseVersion.length === 0) { | ||
| throw new Error("deno.json must define a non-empty string version"); | ||
| } | ||
| if (!/^\d+\.\d+\.\d+-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*$/.test(baseVersion)) { | ||
| throw new Error(`deno.json version ${baseVersion} is not a prerelease version`); | ||
| } | ||
|
|
||
| const versionPrefix = `${baseVersion}.`; | ||
| const runNumber = options.version.startsWith(versionPrefix) | ||
| ? options.version.slice(versionPrefix.length) | ||
| : ""; | ||
| if (!/^[1-9]\d*$/.test(runNumber)) { | ||
| throw new Error( | ||
| `RC build version ${options.version} must extend ${baseVersion} with a numeric run number`, | ||
| ); | ||
| } | ||
|
|
||
| const versionConstantSource = await Deno.readTextFile(versionConstantPath); | ||
| const versionConstantMatches = [...versionConstantSource.matchAll( | ||
| VERSION_CONSTANT_PATTERN, | ||
| )]; | ||
| if (versionConstantMatches.length !== 1) { | ||
| throw new Error( | ||
| "src/utils/version-constant.ts must contain exactly one exported VERSION constant", | ||
| ); | ||
| } | ||
| if (versionConstantMatches[0][1] !== baseVersion) { | ||
| throw new Error( | ||
| `src/utils/version-constant.ts version ${versionConstantMatches[0][1]} does not match deno.json version ${baseVersion}`, | ||
| ); | ||
| } | ||
|
|
||
| const manifestVersionPattern = | ||
| /^(\s*"version"\s*:\s*)"([^"]+)"(,?\s*)$/gm; | ||
| const manifestVersionMatches = [...manifestSource.matchAll( | ||
| manifestVersionPattern, | ||
| )]; | ||
| if ( | ||
| manifestVersionMatches.length !== 1 || | ||
| manifestVersionMatches[0][2] !== baseVersion | ||
| ) { | ||
| throw new Error("deno.json must contain exactly one matching version field"); | ||
| } | ||
|
|
||
| const nextManifestSource = manifestSource.replace( | ||
| manifestVersionPattern, | ||
| `$1"${options.version}"$3`, | ||
| ); | ||
| const nextVersionConstantSource = versionConstantSource.replace( | ||
| VERSION_CONSTANT_PATTERN, | ||
| `export const VERSION = "${options.version}";`, | ||
| ); | ||
|
|
||
| await Deno.writeTextFile(manifestPath, nextManifestSource); | ||
| await Deno.writeTextFile(versionConstantPath, nextVersionConstantSource); | ||
| } | ||
|
|
||
| if (import.meta.main) { | ||
| const version = Deno.env.get("VERSION"); | ||
| if (!version) { | ||
| throw new Error("VERSION must be set for RC build preparation"); | ||
| } | ||
| await prepareRcBuildVersion({ version }); | ||
| console.log(`Prepared npm source artifacts for ${version}`); | ||
| } |
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -92,6 +92,13 @@ describe("repository hardening", () => { | |||||||||||||||||||||||||||||||||
| assert(workflow.includes("scripts/ci/publish-npm-packages.sh rc-publish")); | ||||||||||||||||||||||||||||||||||
| assert(workflow.includes("scripts/ci/publish-npm-packages.sh preflight")); | ||||||||||||||||||||||||||||||||||
| assert(workflow.includes("scripts/ci/publish-npm-packages.sh release-publish")); | ||||||||||||||||||||||||||||||||||
| assert(workflow.includes("deno run -A scripts/ci/prepare-rc-build.ts")); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| const prerelease = jobBlock(workflow, "prerelease"); | ||||||||||||||||||||||||||||||||||
| assert( | ||||||||||||||||||||||||||||||||||
| prerelease.indexOf("deno run -A scripts/ci/prepare-rc-build.ts") < | ||||||||||||||||||||||||||||||||||
| prerelease.indexOf("deno task build:npm"), | ||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||
|
Comment on lines
+95
to
+101
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win Require preparation in the prerelease job. The global assertion at Line 95 permits the command in a different job. If Proposed fix- assert(workflow.includes("deno run -A scripts/ci/prepare-rc-build.ts"));
-
const prerelease = jobBlock(workflow, "prerelease");
+ const prepareIndex = prerelease.indexOf(
+ "deno run -A scripts/ci/prepare-rc-build.ts",
+ );
+ assert(prepareIndex >= 0, "expected prerelease to prepare the RC version");
assert(
- prerelease.indexOf("deno run -A scripts/ci/prepare-rc-build.ts") <
+ prepareIndex <
prerelease.indexOf("deno task build:npm"),
);📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| assertEquals(publishScript.includes("NPM_TOKEN"), false); | ||||||||||||||||||||||||||||||||||
| assertEquals(publishScript.includes("NODE_AUTH_TOKEN"), false); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,4 @@ | ||
| // Keep in sync with deno.json version. | ||
| // scripts/release.ts updates this constant during releases. | ||
| /** Shared version value. */ | ||
| export const VERSION = "0.1.1229"; | ||
| export const VERSION = "0.1.1230-rc"; |
Uh oh!
There was an error while loading. Please reload this page.