@astra-kit/rp 0.0.0-stage → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/CHANGELOG.md +196 -0
  2. package/LICENSE.md +21 -0
  3. package/README.md +352 -2
  4. package/bin/astra-rp.js +51 -0
  5. package/package.json +93 -4
  6. package/src/build-gate.js +157 -0
  7. package/src/changelog-blocks.js +53 -0
  8. package/src/changelog.js +108 -0
  9. package/src/constants/build-gate.js +30 -0
  10. package/src/constants/changelog-draft.js +180 -0
  11. package/src/constants/changelog.js +74 -0
  12. package/src/constants/ci-release.js +346 -0
  13. package/src/constants/cli.js +12 -0
  14. package/src/constants/create-version.js +523 -0
  15. package/src/constants/guard-publish.js +29 -0
  16. package/src/constants/index.js +18 -0
  17. package/src/constants/monorepo.js +57 -0
  18. package/src/constants/package-manager.js +56 -0
  19. package/src/constants/registry.js +72 -0
  20. package/src/constants/terminal-ui.js +93 -0
  21. package/src/constants/version-files.js +63 -0
  22. package/src/constants/versions.js +60 -0
  23. package/src/create-version/artifact.js +343 -0
  24. package/src/create-version/changelog-draft-workspace.js +124 -0
  25. package/src/create-version/changelog-draft.js +380 -0
  26. package/src/create-version/changelog.js +264 -0
  27. package/src/create-version/ci-config.js +54 -0
  28. package/src/create-version/ci-publication-history.js +113 -0
  29. package/src/create-version/ci-release-identity-step.js +58 -0
  30. package/src/create-version/ci-setup.js +794 -0
  31. package/src/create-version/ci.js +555 -0
  32. package/src/create-version/committed-tree.js +75 -0
  33. package/src/create-version/config.js +489 -0
  34. package/src/create-version/errors.js +46 -0
  35. package/src/create-version/github-workflow.js +199 -0
  36. package/src/create-version/index.js +54 -0
  37. package/src/create-version/json.js +32 -0
  38. package/src/create-version/jsonc.js +76 -0
  39. package/src/create-version/jsr.js +96 -0
  40. package/src/create-version/local-changes.js +178 -0
  41. package/src/create-version/npm-auth.js +142 -0
  42. package/src/create-version/npm.js +812 -0
  43. package/src/create-version/plan.js +1200 -0
  44. package/src/create-version/process.js +334 -0
  45. package/src/create-version/registry-config.js +121 -0
  46. package/src/create-version/registry-http.js +62 -0
  47. package/src/create-version/registry.js +220 -0
  48. package/src/create-version/release-execution.js +45 -0
  49. package/src/create-version/release-tag-config.js +76 -0
  50. package/src/create-version/run.js +2087 -0
  51. package/src/create-version/state.js +461 -0
  52. package/src/create-version/strict-utf8.js +11 -0
  53. package/src/create-version/templates/release.yml +52 -0
  54. package/src/create-version/templates/vercel-ignore-build.mjs +66 -0
  55. package/src/guard-publish.js +77 -0
  56. package/src/index.js +42 -0
  57. package/src/monorepo/plan.js +475 -0
  58. package/src/monorepo/release-commit.js +46 -0
  59. package/src/monorepo/run.js +927 -0
  60. package/src/monorepo/state.js +206 -0
  61. package/src/monorepo/workspaces.js +327 -0
  62. package/src/package-manager.js +107 -0
  63. package/src/terminal-ui.js +548 -0
  64. package/src/testing.js +70 -0
  65. package/src/version-files.js +142 -0
  66. package/src/versions.js +303 -0
  67. package/types/build-gate.d.ts +43 -0
  68. package/types/changelog-blocks.d.ts +33 -0
  69. package/types/changelog.d.ts +61 -0
  70. package/types/constants/build-gate.d.ts +23 -0
  71. package/types/constants/changelog-draft.d.ts +138 -0
  72. package/types/constants/changelog.d.ts +56 -0
  73. package/types/constants/ci-release.d.ts +284 -0
  74. package/types/constants/cli.d.ts +11 -0
  75. package/types/constants/create-version.d.ts +397 -0
  76. package/types/constants/guard-publish.d.ts +25 -0
  77. package/types/constants/index.d.ts +17 -0
  78. package/types/constants/monorepo.d.ts +45 -0
  79. package/types/constants/package-manager.d.ts +40 -0
  80. package/types/constants/registry.d.ts +79 -0
  81. package/types/constants/terminal-ui.d.ts +73 -0
  82. package/types/constants/version-files.d.ts +51 -0
  83. package/types/constants/versions.d.ts +47 -0
  84. package/types/create-version/artifact.d.ts +113 -0
  85. package/types/create-version/changelog-draft-workspace.d.ts +33 -0
  86. package/types/create-version/changelog-draft.d.ts +127 -0
  87. package/types/create-version/changelog.d.ts +141 -0
  88. package/types/create-version/ci-config.d.ts +33 -0
  89. package/types/create-version/ci-publication-history.d.ts +51 -0
  90. package/types/create-version/ci-release-identity-step.d.ts +12 -0
  91. package/types/create-version/ci-setup.d.ts +148 -0
  92. package/types/create-version/ci.d.ts +145 -0
  93. package/types/create-version/committed-tree.d.ts +55 -0
  94. package/types/create-version/config.d.ts +128 -0
  95. package/types/create-version/errors.d.ts +39 -0
  96. package/types/create-version/github-workflow.d.ts +41 -0
  97. package/types/create-version/index.d.ts +28 -0
  98. package/types/create-version/json.d.ts +21 -0
  99. package/types/create-version/jsonc.d.ts +21 -0
  100. package/types/create-version/jsr.d.ts +52 -0
  101. package/types/create-version/local-changes.d.ts +52 -0
  102. package/types/create-version/npm-auth.d.ts +60 -0
  103. package/types/create-version/npm.d.ts +331 -0
  104. package/types/create-version/plan.d.ts +369 -0
  105. package/types/create-version/process.d.ts +151 -0
  106. package/types/create-version/registry-config.d.ts +56 -0
  107. package/types/create-version/registry-http.d.ts +22 -0
  108. package/types/create-version/registry.d.ts +86 -0
  109. package/types/create-version/release-execution.d.ts +22 -0
  110. package/types/create-version/release-tag-config.d.ts +18 -0
  111. package/types/create-version/run.d.ts +407 -0
  112. package/types/create-version/state.d.ts +204 -0
  113. package/types/create-version/strict-utf8.d.ts +10 -0
  114. package/types/guard-publish.d.ts +49 -0
  115. package/types/index.d.ts +23 -0
  116. package/types/monorepo/plan.d.ts +68 -0
  117. package/types/monorepo/release-commit.d.ts +29 -0
  118. package/types/monorepo/run.d.ts +68 -0
  119. package/types/monorepo/state.d.ts +96 -0
  120. package/types/monorepo/workspaces.d.ts +86 -0
  121. package/types/package-manager.d.ts +58 -0
  122. package/types/terminal-ui.d.ts +196 -0
  123. package/types/testing.d.ts +31 -0
  124. package/types/version-files.d.ts +59 -0
  125. package/types/versions.d.ts +158 -0
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Reads the worker's own GitHub Actions history to prove that a custom publisher already finished,
3
+ * so neither a retry that only needs to deploy nor a duplicate dispatch queued behind the release's
4
+ * concurrency group runs a non-idempotent publication again.
5
+ * A registry publication is proven by the registry itself; a custom `publish` function leaves no
6
+ * such record, and the successful release step of an earlier run or attempt is the durable one.
7
+ * @module create-version/ci-publication-history
8
+ */
9
+ export type ActionsWorkflowRun = {
10
+ id: number;
11
+ display_title: string;
12
+ run_attempt: number;
13
+ html_url: string;
14
+ };
15
+ export type ActionsJob = {
16
+ steps?: {
17
+ name: string;
18
+ conclusion: string | null;
19
+ }[];
20
+ };
21
+ export type CompletedCiPublication = {
22
+ url: string;
23
+ attempt: number;
24
+ };
25
+ /**
26
+ * @typedef {{ id: number, display_title: string, run_attempt: number, html_url: string }} ActionsWorkflowRun
27
+ * @typedef {{ steps?: { name: string, conclusion: string | null }[] }} ActionsJob
28
+ * @typedef {{ url: string, attempt: number }} CompletedCiPublication
29
+ */
30
+ /**
31
+ * Tells whether the worker must prove from its Actions history that the publication already
32
+ * finished: a custom publisher leaves no registry record, and both a retry after a failed deployment
33
+ * and two concurrent `--retry-ci` dispatches (queued, not cancelled, by the workflow's concurrency
34
+ * group) reach the worker again for the same release, with or without a deployment.
35
+ * @param {import("./config.js").ResolvedCreateVersionConfig} config - Project configuration.
36
+ * @returns {boolean} True when `publish` is a function.
37
+ */
38
+ export declare function requiresCiPublicationHistory(config: import("./config.js").ResolvedCreateVersionConfig): boolean;
39
+ /**
40
+ * Finds another run or attempt of this exact release whose release step succeeded, which means its
41
+ * custom publisher already finished. Only successful release steps count: a duplicate dispatch queued
42
+ * behind the release's concurrency group starts after the first run ends, so it sees that success.
43
+ * The current run attempt (`GITHUB_RUN_ID`/`GITHUB_RUN_ATTEMPT`) never counts.
44
+ * Fails closed: when the history cannot be read, the worker stops before publishing.
45
+ * @param {string} workflow - Configured workflow filename that dispatches the release.
46
+ * @param {import("./github-workflow.js").CiReleaseIdentity} release - Verified release identity.
47
+ * @param {NodeJS.ProcessEnv} [environment] - Worker environment providing the Actions API, repository and token.
48
+ * @returns {Promise<CompletedCiPublication | null>} Another successful run attempt, or null when publication never finished.
49
+ * @throws {ReleaseStepError} When the Actions history is unavailable or unreadable.
50
+ */
51
+ export declare function findCompletedCiPublication(workflow: string, release: import("./github-workflow.js").CiReleaseIdentity, environment?: NodeJS.ProcessEnv): Promise<CompletedCiPublication | null>;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Renders the dependency-free workflow step that authenticates a dispatched release before any
3
+ * project-controlled code (package installation, lifecycle scripts, hooks) runs with the job's
4
+ * publication secrets and OIDC permission.
5
+ * @module create-version/ci-release-identity-step
6
+ */
7
+ /**
8
+ * Renders the identity step placed right after checkout and before any toolchain or dependency setup.
9
+ * Inputs reach the script only through step environment variables, never through `${{ }}` interpolation.
10
+ * @returns {string} Workflow YAML for one step, indented for the release job.
11
+ */
12
+ export declare function renderCiReleaseIdentityStep(): string;
@@ -0,0 +1,148 @@
1
+ /**
2
+ * Prepares automatic CI setup as rollback-capable files of the release commit.
3
+ * @module create-version/ci-setup
4
+ */
5
+ export type ResolvedCreateVersionConfig = import("./config.js").ResolvedCreateVersionConfig;
6
+ export type ReleaseFileUpdate = import("./run.js").ReleaseFileUpdate;
7
+ /**
8
+ * @typedef {import("./config.js").ResolvedCreateVersionConfig} ResolvedCreateVersionConfig
9
+ * @typedef {import("./run.js").ReleaseFileUpdate} ReleaseFileUpdate
10
+ */
11
+ /**
12
+ * Builds the worker's environment from explicit bindings and the selected registry credential.
13
+ * @param {ResolvedCreateVersionConfig} config - Project configuration.
14
+ * Every Vercel credential is listed once in `secrets` (so preflight requires it) and always in
15
+ * `deploymentSecrets`, even when also declared in `ci.secrets`, which keeps it out of the job-level environment.
16
+ * @returns {{ secrets: string[], variables: string[], githubToken: boolean, githubTokenWrite: boolean, deploymentSecrets: string[] }} Required worker bindings, step-scoped deployment credentials and package permission.
17
+ */
18
+ export declare function describeCiEnvironment(config: ResolvedCreateVersionConfig): {
19
+ secrets: string[];
20
+ variables: string[];
21
+ githubToken: boolean;
22
+ githubTokenWrite: boolean;
23
+ deploymentSecrets: string[];
24
+ };
25
+ /**
26
+ * Reads the package manager version pinned by `packageManager`, the exact one the generated workflow installs.
27
+ * @param {Record<string, unknown>} manifest - Parsed project `package.json`.
28
+ * @returns {string | null} Pinned version such as `11.5.1`, or `null` when the field is absent or not a safe pin.
29
+ */
30
+ export declare function extractPinnedPackageManagerVersion(manifest: Record<string, unknown>): string | null;
31
+ /**
32
+ * Reads the major of the Node.js running setup, the runtime the generated workflow falls back to
33
+ * when HEAD commits no `.nvmrc`.
34
+ * @returns {string} Major version such as `22`.
35
+ */
36
+ export declare function readRunningNodeMajor(): string;
37
+ /**
38
+ * Describes the Node.js version the generated workflow asks `actions/setup-node` for: the
39
+ * `.nvmrc` pin when HEAD commits it as a regular file, otherwise the major of the Node.js running
40
+ * setup. Only HEAD counts because the worker checks out the release commit built from it: an
41
+ * untracked, ignored or set-aside `.nvmrc` would make `node-version-file` fail there after the tag
42
+ * was pushed. Reading HEAD also keeps the rendered workflow deterministic for the drift check.
43
+ * @param {string} repositoryRoot - Project checkout.
44
+ * @returns {Promise<{ pinnedFile: string | null, version: string }>} Pin file the workflow reads (or `null`) and its version without a `v` prefix.
45
+ * @throws {ReleaseStepError} When Git cannot list or read HEAD.
46
+ */
47
+ export declare function describeCiNodeVersion(repositoryRoot: string): Promise<{
48
+ pinnedFile: string | null;
49
+ version: string;
50
+ }>;
51
+ export type ProjectGithubPackagesConfig = {
52
+ /**
53
+ * - A literal registry or any project credential selects GitHub Packages.
54
+ */
55
+ usesGithubPackages: boolean;
56
+ /**
57
+ * - Variable expanded by the accepted host token (`${NAME}`), or `null`.
58
+ */
59
+ tokenVariable: string | null;
60
+ /**
61
+ * - Effective top-level entries, validated by
62
+ * {@link assertProjectNpmConfigEntriesSupported}.
63
+ */
64
+ entries: Array<{
65
+ key: string;
66
+ value: string | true;
67
+ }>;
68
+ /**
69
+ * - Git tree mode of a committed `.npmrc` that is not a regular file
70
+ * (a symlink, `120000`, or another kind of entry), which npm still follows in the worker; `null` otherwise.
71
+ */
72
+ irregularFileMode: string | null;
73
+ };
74
+ export type CommittedPackageManagerFile = {
75
+ /**
76
+ * - Root-relative path of the file committed at HEAD.
77
+ */
78
+ filePath: string;
79
+ /**
80
+ * - Committed content, or `null` when the entry is not a regular file.
81
+ */
82
+ text: string | null;
83
+ /**
84
+ * - Git tree mode of an entry that is not a regular file (a symlink,
85
+ * `120000`, or another kind of entry), which the package manager still follows in the worker; `null` otherwise.
86
+ */
87
+ irregularFileMode: string | null;
88
+ };
89
+ /**
90
+ * Renders the release workflow and keeps the GitHub Packages description it was rendered from, so a caller
91
+ * can compare the workflow first and validate that setup afterwards without describing it twice.
92
+ * @param {string} repositoryRoot - Project checkout.
93
+ * @param {ResolvedCreateVersionConfig} config - Release hooks and package manager.
94
+ * @returns {Promise<{ content: string, assertGithubPackagesSetupSupported: () => Promise<void> }>} GitHub Actions YAML,
95
+ * and the check that the generated workflow can authenticate the project's GitHub Packages setup.
96
+ * @throws {ReleaseStepError} When Git cannot list or read HEAD or the worker bindings are invalid.
97
+ */
98
+ export declare function prepareCiReleaseWorkflow(repositoryRoot: string, config: ResolvedCreateVersionConfig): Promise<{
99
+ content: string;
100
+ assertGithubPackagesSetupSupported: () => Promise<void>;
101
+ }>;
102
+ /**
103
+ * Renders a workflow that installs the project's package manager and finishes a pinned release.
104
+ * @param {string} repositoryRoot - Project checkout.
105
+ * @param {ResolvedCreateVersionConfig} config - Release hooks and package manager.
106
+ * @param {{ validateGithubPackages?: boolean }} [options] - `validateGithubPackages: false` only renders,
107
+ * for comparisons against a committed workflow that may be customized and authenticate on its own.
108
+ * @returns {Promise<string>} GitHub Actions YAML.
109
+ * @throws {ReleaseStepError} When Git cannot list or read HEAD or, while validating, the GitHub Packages
110
+ * setup is unsupported (see {@link assertGeneratedGithubPackagesSetupSupported}).
111
+ */
112
+ export declare function renderCiReleaseWorkflow(repositoryRoot: string, config: ResolvedCreateVersionConfig, { validateGithubPackages }?: {
113
+ validateGithubPackages?: boolean;
114
+ }): Promise<string>;
115
+ /**
116
+ * Prepares a named CI export and a new workflow without replacing existing project code.
117
+ * Syntax is checked with Node before anything in the project is written.
118
+ * @param {string} repositoryRoot - Checkout whose configuration is already loaded.
119
+ * @param {ResolvedCreateVersionConfig} config - Configuration selecting the default workflow.
120
+ * @param {boolean} [writeConfiguration] - Add a named CI export only when settings were absent.
121
+ * @returns {Promise<ReleaseFileUpdate[]>} Files to include atomically with the bump.
122
+ * @throws {ReleaseStepError} When an existing workflow would be overwritten or configuration cannot be extended.
123
+ */
124
+ export declare function prepareCiSetupFiles(repositoryRoot: string, config: ResolvedCreateVersionConfig, writeConfiguration?: boolean): Promise<ReleaseFileUpdate[]>;
125
+ /**
126
+ * Records the execution mode for the early Vercel build gate without importing project dependencies.
127
+ * @param {string} repositoryRoot - Project root.
128
+ * @param {string} version - Version of the release being committed.
129
+ * @param {"local" | "ci"} execution - Execution location chosen for this release.
130
+ * @returns {ReleaseFileUpdate} Version-scoped metadata included in the bump.
131
+ */
132
+ export declare function prepareCiReleaseMetadata(repositoryRoot: string, version: string, execution: "local" | "ci"): ReleaseFileUpdate;
133
+ /**
134
+ * Prevents concurrent editor changes from being overwritten after an interactive version prompt.
135
+ * @param {string} repositoryRoot - Checkout about to receive the bump.
136
+ * @param {ReleaseFileUpdate[]} updates - CI files captured before prompting.
137
+ * @returns {void}
138
+ * @throws {ReleaseStepError} When a captured file changed or a new workflow appeared.
139
+ */
140
+ export declare function assertCiSetupFilesUnchanged(repositoryRoot: string, updates: ReleaseFileUpdate[]): void;
141
+ /**
142
+ * Rejects symlinks anywhere in an owned setup path before writes can leave the checkout.
143
+ * @param {string} repositoryRoot - Trusted checkout root.
144
+ * @param {string} relativePath - Constant or validated relative file path.
145
+ * @returns {void}
146
+ * @throws {ReleaseStepError} When an existing path component is a symlink.
147
+ */
148
+ export declare function assertSafeCiPath(repositoryRoot: string, relativePath: string): void;
@@ -0,0 +1,145 @@
1
+ /**
2
+ * Selects the release location and plans the worker for an already-created release tag.
3
+ * @module create-version/ci
4
+ */
5
+ /**
6
+ * Selects the execution location without ever dispatching again inside a CI runtime.
7
+ * @param {import("./config.js").ResolvedCreateVersionConfig} config - Project configuration.
8
+ * @param {import("./plan.js").ReleaseOptions} options - CLI overrides.
9
+ * @returns {Promise<{ execution: "local" | "ci", setup: boolean } | null>} Selection, or null when canceled.
10
+ */
11
+ export declare function chooseReleaseExecution(config: import("./config.js").ResolvedCreateVersionConfig, options: import("./plan.js").ReleaseOptions): Promise<{
12
+ execution: "local" | "ci";
13
+ setup: boolean;
14
+ } | null>;
15
+ /**
16
+ * Rejects registry authentication that a non-interactive GitHub Actions worker can never complete,
17
+ * before the immutable release commit and tag exist (or before a retry dispatches them again).
18
+ * OIDC stays allowed, since only the worker can prove it, except when the runtime the generated
19
+ * workflow sets up provably cannot perform npm trusted publishing: the worker would reject it only
20
+ * after the release was pushed. The Node.js runtime is checked for every package manager. With npm,
21
+ * the version pinned by `packageManager` is checked too and never raised silently, because that
22
+ * would change the client that runs `npm ci` against the committed lockfile; an unpinned npm
23
+ * project and other package managers get a capable npm installed by the workflow for publication
24
+ * (see `requiresCiNpmOidcClient`), after `npm ci` in the unpinned npm case. The effective npm
25
+ * destination is resolved as well, since trusted publishing only exists on the public npm registry.
26
+ * A token publication named `GITHUB_TOKEN` gets the built-in Actions token injected by the generated
27
+ * workflow, which only GitHub Packages accepts, so its effective destination is resolved too.
28
+ * @param {import("./config.js").ResolvedCreateVersionConfig} config - Project configuration.
29
+ * @param {string} repositoryRoot - Project root whose `package.json`, `.nvmrc` and npm config pin the worker's runtime and destination.
30
+ * @returns {Promise<void>}
31
+ * @throws {ReleaseStepError} When the registry publication authorizes from a browser, uses npm OIDC with a Node.js or npm pin below the trusted publishing minimum or a registry other than the public npm one, or names `GITHUB_TOKEN` as the token of a destination other than GitHub Packages.
32
+ */
33
+ export declare function assertCiCompatiblePublication(config: import("./config.js").ResolvedCreateVersionConfig, repositoryRoot: string): Promise<void>;
34
+ /**
35
+ * Rejects resuming a pending release in a location different from the one it was prepared in: the
36
+ * Vercel build gate decides from the committed release metadata, and a CI preparation skipped the
37
+ * checks and migrations that a local resume (which only pushes and publishes) would never run.
38
+ * The Vercel metadata wins when it names this version; otherwise the release commit trailer decides.
39
+ * Release commits without either mark (created before they existed) are accepted as before.
40
+ * @param {import("./process.js").GitReader} reader - Git reader of the checkout whose HEAD is the release commit.
41
+ * @param {string} version - Version of the pending release.
42
+ * @param {"local" | "ci"} execution - Location selected for this run.
43
+ * @returns {Promise<void>}
44
+ * @throws {ReleaseStepError} When the committed mark belongs to this version and names another location, or is unreadable.
45
+ */
46
+ export declare function assertResumeExecutionMatches(reader: import("./process.js").GitReader, version: string, execution: "local" | "ci"): Promise<void>;
47
+ /**
48
+ * Reads the configured workflow from HEAD after checking it is a regular file inside the project.
49
+ * `gh workflow run --ref <tag>` only finds workflows contained in the pushed release commit, so a
50
+ * local file that is untracked, ignored or set aside by `--ignore-local-changes` is not enough.
51
+ * @param {string} repositoryRoot - Project root.
52
+ * @param {string} workflow - Validated workflow filename.
53
+ * @param {string} [missingHint] - Recovery hint shown when HEAD does not contain the workflow.
54
+ * @returns {Promise<string>} Workflow content committed at HEAD.
55
+ * @throws {ReleaseStepError} When the workflow is missing, a symlink or not committed at HEAD.
56
+ */
57
+ export declare function readCommittedCiWorkflow(repositoryRoot: string, workflow: string, missingHint?: string): Promise<string>;
58
+ /**
59
+ * Rejects the generated workflow when HEAD has no lockfile of the project's package manager: it
60
+ * installs dependencies with a frozen lockfile (`npm ci`, `pnpm install --frozen-lockfile`,
61
+ * `yarn install --frozen-lockfile`/`--immutable`, `bun install --frozen-lockfile`), which fails
62
+ * without one, so the worker would stop only after the release commit and tag were pushed.
63
+ * A file present on disk is not enough: the worker checks out the pushed release commit.
64
+ * @param {string} repositoryRoot - Project root.
65
+ * @param {import("../package-manager.js").PackageManagerName} packageManager - Package manager the workflow installs with.
66
+ * @returns {Promise<void>}
67
+ * @throws {ReleaseStepError} When HEAD cannot be listed or contains none of the package manager's lockfiles.
68
+ */
69
+ export declare function assertCiInstallLockfileCommitted(repositoryRoot: string, packageManager: import("../package-manager.js").PackageManagerName): Promise<void>;
70
+ /**
71
+ * Rejects the generated workflow when the checkout has a `.nvmrc` that HEAD does not commit as a
72
+ * regular file (untracked, ignored, set aside by `--ignore-local-changes`, or committed as a
73
+ * symlink). The workflow only follows the committed pin, so it would silently run the local
74
+ * Node.js major instead of the pinned runtime, and the npm OIDC check would judge that other
75
+ * version; stopping before the bump lets the user commit the pin or drop it deliberately.
76
+ * @param {string} repositoryRoot - Project root.
77
+ * @returns {Promise<void>}
78
+ * @throws {ReleaseStepError} When `.nvmrc` exists locally but not as a regular file committed at HEAD, or HEAD cannot be read.
79
+ */
80
+ export declare function assertCiNodeVersionFileCommitted(repositoryRoot: string): Promise<void>;
81
+ /**
82
+ * Tells whether the configured workflow committed at HEAD is exactly the one setup renders for the
83
+ * current configuration, so an ordinary CI release knows it installs dependencies with a frozen
84
+ * lockfile and follows the committed `.nvmrc` like `--setup-ci` does. A missing, non-regular or
85
+ * customized workflow is not the generated one; its own checks stay with the release flow. The
86
+ * comparison renders without the generated workflow's GitHub Packages validations, so a customized
87
+ * workflow that authenticates on its own is never blocked by them; they run only once the committed
88
+ * workflow is known to be the generated one. A workflow that only lacks the GitHub Packages authentication
89
+ * lines (see {@link lacksOnlyGithubPackagesAuthentication}) was generated before that authentication existed:
90
+ * releasing with it would fail with 401 after the tag was pushed, so it is rejected instead of treated as customized.
91
+ * @param {string} repositoryRoot - Project root.
92
+ * @param {import("./config.js").ResolvedCreateVersionConfig} config - Project configuration.
93
+ * @returns {Promise<boolean>} True when HEAD commits the generated workflow unchanged.
94
+ * @throws {ReleaseStepError} When Git cannot list or read HEAD, HEAD commits the generated workflow
95
+ * with a GitHub Packages setup it cannot authenticate, or a generated workflow without that authentication.
96
+ */
97
+ export declare function isCommittedCiWorkflowGenerated(repositoryRoot: string, config: import("./config.js").ResolvedCreateVersionConfig): Promise<boolean>;
98
+ /**
99
+ * Rejects `--setup-ci` over an existing workflow whose committed content no longer matches what
100
+ * setup would generate for the current configuration (for example a new publication token binding).
101
+ * Regeneration is never automatic: the committed file may hold intentional manual edits, so the
102
+ * user decides between regenerating it and releasing with the customized workflow through `--ci`.
103
+ * @param {string} repositoryRoot - Project root.
104
+ * @param {import("./config.js").ResolvedCreateVersionConfig} config - Configuration with a validated `ci.workflow`.
105
+ * @returns {Promise<void>}
106
+ * @throws {ReleaseStepError} When the workflow is not committed at HEAD or differs from the rendered one.
107
+ */
108
+ export declare function assertGeneratedCiWorkflowCurrent(repositoryRoot: string, config: import("./config.js").ResolvedCreateVersionConfig): Promise<void>;
109
+ /**
110
+ * Reads an immutable release identity and proves it already exists on origin/main.
111
+ * @param {import("./process.js").GitReader} reader - Git reader.
112
+ * @param {string} tag - Stable release tag, vX.Y.Z.
113
+ * @param {boolean} [requireHead] - Require the checkout to be exactly this release.
114
+ * @returns {Promise<import("./github-workflow.js").CiReleaseIdentity>} Verified remote identity.
115
+ * @throws {ReleaseStepError} When the tag, commit, version or checkout differs.
116
+ */
117
+ export declare function readCiReleaseIdentity(reader: import("./process.js").GitReader, tag: string, requireHead?: boolean): Promise<import("./github-workflow.js").CiReleaseIdentity>;
118
+ /**
119
+ * Appends dispatch to the minimal local preparation plan.
120
+ * @param {import("./plan.js").ReleasePlan} plan - Existing bump/push plan.
121
+ * @returns {import("./plan.js").ReleasePlan} Plan whose last step only submits the worker.
122
+ */
123
+ export declare function appendCiDispatch(plan: import("./plan.js").ReleasePlan): import("./plan.js").ReleasePlan;
124
+ /**
125
+ * Plans checks and unfinished publication for a pinned worker; never bumps or pushes.
126
+ * @param {import("./state.js").ReleaseSnapshot} state - Diagnosed worker checkout.
127
+ * @param {import("./plan.js").ReleaseCapabilities} capabilities - Normal project hooks.
128
+ * A retry after the registry publication succeeded skips migrations and publication, but still
129
+ * re-runs the preparation when the workflow deploys afterwards: the retry starts from a fresh
130
+ * checkout, so files or setup produced by `prepare` would otherwise be missing from the deployment.
131
+ * @param {string} version - Existing release version.
132
+ * A custom publisher leaves no registry record, so its completion comes from the worker's Actions
133
+ * history (see `findCompletedCiPublication`) and is treated exactly like a confirmed registry publication.
134
+ * @param {boolean} [deploymentFollows] - Whether the workflow deploys (for example to Vercel) after this worker finishes.
135
+ * @param {boolean} [customPublicationCompleted] - Whether an earlier run or attempt already finished the custom publisher.
136
+ * @returns {import("./plan.js").ReleasePlan} Worker-only execution plan.
137
+ */
138
+ export declare function buildCiWorkerPlan(state: import("./state.js").ReleaseSnapshot, capabilities: import("./plan.js").ReleaseCapabilities, version: string, deploymentFollows?: boolean, customPublicationCompleted?: boolean): import("./plan.js").ReleasePlan;
139
+ /**
140
+ * Derives setup defaults from the application's deployment and migration configuration.
141
+ * @param {string} repositoryRoot - Checkout offered automatic setup.
142
+ * @param {import("./config.js").ResolvedCreateVersionConfig} config - Existing project hooks.
143
+ * @returns {import("./ci-config.js").ResolvedCiReleaseConfig} In-memory settings, committed only with a successful bump.
144
+ */
145
+ export declare function defaultCiReleaseConfig(repositoryRoot: string, config: import("./config.js").ResolvedCreateVersionConfig): import("./ci-config.js").ResolvedCiReleaseConfig;
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Reads files from the commit at HEAD: the content a CI worker checks out from the pushed release
3
+ * commit, unlike the working tree, which may hold untracked, ignored or set-aside files.
4
+ * @module create-version/committed-tree
5
+ */
6
+ export type CommittedTreeEntry = {
7
+ /**
8
+ * - Git tree mode, such as `100644` or `120000`.
9
+ */
10
+ mode: string;
11
+ /**
12
+ * - Git object type, such as `blob` or `tree`.
13
+ */
14
+ type: string;
15
+ /**
16
+ * - Object id of the entry.
17
+ */
18
+ objectId: string;
19
+ /**
20
+ * - Path relative to the repository root.
21
+ */
22
+ filePath: string;
23
+ };
24
+ /**
25
+ * Lists which of the given root-relative paths HEAD contains.
26
+ * @param {string} repositoryRoot - Project root.
27
+ * @param {string[]} filePaths - Root-relative paths to look up.
28
+ * @returns {Promise<CommittedTreeEntry[]>} Entries found at HEAD; absent paths are omitted.
29
+ * @throws {ReleaseStepError} When `git ls-tree` fails, for example without a commit at HEAD.
30
+ */
31
+ export declare function listCommittedTreeEntries(repositoryRoot: string, filePaths: string[]): Promise<CommittedTreeEntry[]>;
32
+ /**
33
+ * Tells whether a HEAD tree entry is a regular file, which the worker checks out as is; a symlink,
34
+ * submodule or directory is not.
35
+ * @param {CommittedTreeEntry} entry - Entry listed by {@link listCommittedTreeEntries}.
36
+ * @returns {boolean} True for a blob with one of {@link GIT_REGULAR_FILE_MODES}.
37
+ */
38
+ export declare function isCommittedRegularFile(entry: CommittedTreeEntry): boolean;
39
+ /**
40
+ * Reads the content of a regular file entry of HEAD.
41
+ * @param {string} repositoryRoot - Project root.
42
+ * @param {CommittedTreeEntry} entry - Regular file entry (see {@link isCommittedRegularFile}).
43
+ * @returns {Promise<string>} Committed content.
44
+ * @throws {ReleaseStepError} When Git cannot read the committed object.
45
+ */
46
+ export declare function readCommittedFileEntry(repositoryRoot: string, entry: CommittedTreeEntry): Promise<string>;
47
+ /**
48
+ * Reads a file committed at HEAD only when it is a regular file, which the worker checks out as is;
49
+ * a symlink, submodule or directory at that path counts as absent.
50
+ * @param {string} repositoryRoot - Project root.
51
+ * @param {string} filePath - Root-relative path.
52
+ * @returns {Promise<string | null>} Committed content, or `null` when HEAD has no regular file there.
53
+ * @throws {ReleaseStepError} When Git cannot list HEAD or read the committed object.
54
+ */
55
+ export declare function readCommittedRegularFile(repositoryRoot: string, filePath: string): Promise<string | null>;
@@ -0,0 +1,128 @@
1
+ /**
2
+ * Loads and validates `astra-rp.config.js`, the per-project part of
3
+ * `astra-rp create-version`: version
4
+ * descriptions, registry, checks, migrations, preparation and publication.
5
+ *
6
+ * The configuration never needs to import `@astra-kit/rp`: hooks receive every
7
+ * helper through their context, so a project can type it with
8
+ * `@type {import("@astra-kit/rp/create-version").CreateVersionConfig}` only.
9
+ *
10
+ * @module create-version/config
11
+ */
12
+ export type GitReader = import("./process.js").GitReader;
13
+ export type ProjectCommands = import("../package-manager.js").ProjectCommands;
14
+ export type ReleaseType = "patch" | "minor" | "major";
15
+ export type MigrationCheck = {
16
+ status: "up-to-date" | "pending" | "unknown";
17
+ pending: string[];
18
+ target: string | null;
19
+ reason: string | null;
20
+ };
21
+ export type HookContext = {
22
+ repositoryRoot: string;
23
+ version: string | null;
24
+ git: GitReader;
25
+ run: (commandLine: string) => Promise<number>;
26
+ print: (text?: string) => void;
27
+ fail: (message: string, hint: string) => never;
28
+ releases?: {
29
+ name: string;
30
+ version: string;
31
+ directory: string;
32
+ }[];
33
+ };
34
+ export type ReleaseHook = (context: HookContext) => Promise<void> | void;
35
+ export type MigrationsAdapter = {
36
+ check: (context: HookContext) => Promise<MigrationCheck> | MigrationCheck;
37
+ apply: (context: HookContext) => Promise<void> | void;
38
+ targetHint?: string;
39
+ };
40
+ export type CreateVersionConfig = {
41
+ projectName?: string;
42
+ releaseTypeDescriptions?: Partial<Record<ReleaseType, string>>;
43
+ preMajorShift?: boolean;
44
+ registry?: import("./registry-config.js").RegistryProvider | null;
45
+ publication?: import("./registry-config.js").PublicationOptions;
46
+ publishedLabel?: string;
47
+ checks?: string[] | false;
48
+ migrations?: MigrationsAdapter | null;
49
+ prepare?: string[] | ReleaseHook | null;
50
+ publish?: import("./registry-config.js").RegistryProvider | ReleaseHook | null;
51
+ artifact?: string | null;
52
+ summary?: string[];
53
+ versionFiles?: string[];
54
+ packages?: "workspaces" | string[];
55
+ tagFormat?: string;
56
+ ci?: import("./ci-config.js").CiReleaseConfig | null;
57
+ releaseTimeZone?: string;
58
+ changelogDraft?: boolean | import("./changelog-draft.js").ChangelogDraftProvider[];
59
+ };
60
+ export type ResolvedCreateVersionConfig = {
61
+ projectName: string | null;
62
+ releaseTypeDescriptions: Record<ReleaseType, string>;
63
+ preMajorShift: boolean;
64
+ registry: import("./registry-config.js").RegistryProvider | null;
65
+ publication: import("./registry-config.js").ResolvedPublicationOptions;
66
+ publishedLabel: string;
67
+ checks: string[] | null;
68
+ migrations: MigrationsAdapter | null;
69
+ prepare: string[] | ReleaseHook | null;
70
+ publish: import("./registry-config.js").RegistryProvider | ReleaseHook | null;
71
+ artifact: string | null;
72
+ summary: string[];
73
+ versionFiles: string[];
74
+ packages: "workspaces" | string[] | null;
75
+ tagFormat: string | null;
76
+ ci: import("./ci-config.js").ResolvedCiReleaseConfig | null;
77
+ releaseTimeZone: string | null;
78
+ changelogDraft: import("./changelog-draft.js").ChangelogDraftProvider[];
79
+ commands: ProjectCommands;
80
+ };
81
+ export type ConfigResolutionContext = {
82
+ packageScripts?: Record<string, unknown>;
83
+ commands?: ProjectCommands;
84
+ };
85
+ /**
86
+ * Describes the release types offered after `currentVersion`. While `preMajorShift` applies (the
87
+ * same `0.x` rule as the suggestion), the default descriptions move one level down with the
88
+ * suggestion: a patch carries features and a minor breaking changes. Descriptions the project
89
+ * defined are kept as they are.
90
+ *
91
+ * @param {Pick<ResolvedCreateVersionConfig, "releaseTypeDescriptions" | "preMajorShift">} config - Resolved configuration.
92
+ * @param {string} currentVersion - Current `X.Y.Z` version.
93
+ * @returns {Record<ReleaseType, string>} Description of each release type.
94
+ */
95
+ export declare function describeReleaseTypes({ releaseTypeDescriptions, preMajorShift }: Pick<ResolvedCreateVersionConfig, "releaseTypeDescriptions" | "preMajorShift">, currentVersion: string): Record<ReleaseType, string>;
96
+ /**
97
+ * Types a configuration in editors; returns it unchanged.
98
+ *
99
+ * @param {CreateVersionConfig} config - Project configuration.
100
+ * @returns {CreateVersionConfig} The same configuration.
101
+ */
102
+ export declare function defineCreateVersionConfig(config: CreateVersionConfig): CreateVersionConfig;
103
+ /**
104
+ * Validates a raw configuration and fills its defaults.
105
+ *
106
+ * @param {unknown} rawConfig - Default export of `astra-rp.config.js`.
107
+ * @param {ConfigResolutionContext} [resolutionContext] - Project data the defaults depend on.
108
+ * @returns {ResolvedCreateVersionConfig} Configuration ready for the command.
109
+ * @throws {Error} When a field has an unsupported type or value.
110
+ */
111
+ export declare function resolveCreateVersionConfig(rawConfig: unknown, { packageScripts, commands }?: ConfigResolutionContext): ResolvedCreateVersionConfig;
112
+ /**
113
+ * Tells whether a configured path stays inside the project root: relative, without `..` segments.
114
+ *
115
+ * @param {string} filePath - Configured path.
116
+ * @returns {boolean} Whether it is a relative path that cannot escape the root.
117
+ */
118
+ export declare function isPathInsideRoot(filePath: string): boolean;
119
+ /**
120
+ * Imports `astra-rp.config.mjs` or `astra-rp.config.js` from the repository root and validates it.
121
+ * It is imported once per process: after syncing `main` the command stops and asks to run it
122
+ * again, so a new process imports the updated file and everything it imports.
123
+ *
124
+ * @param {string} repositoryRoot - Repository root.
125
+ * @returns {Promise<ResolvedCreateVersionConfig>} Resolved configuration.
126
+ * @throws {Error} When the file is missing, fails to load or is invalid.
127
+ */
128
+ export declare function loadCreateVersionConfig(repositoryRoot: string): Promise<ResolvedCreateVersionConfig>;
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Errors of `astra-rp create-version`.
3
+ *
4
+ * @module create-version/errors
5
+ */
6
+ /**
7
+ * Describes any thrown value for a Spanish message: the message of an `Error`, otherwise its text.
8
+ *
9
+ * @param {unknown} error - Thrown value.
10
+ * @returns {string} Message to quote.
11
+ */
12
+ export declare function describeError(error: unknown): string;
13
+ /** Failure of a release step or hook, with a Spanish explanation and the next action to take. */
14
+ export declare class ReleaseStepError extends Error {
15
+ hint: string;
16
+ /**
17
+ * @param {string} message - What failed, in Spanish.
18
+ * @param {string} hint - What to do next, in Spanish.
19
+ * @param {{ cause?: unknown }} [options] - Original error, when wrapping one.
20
+ */
21
+ constructor(message: string, hint: string, options?: {
22
+ cause?: unknown;
23
+ });
24
+ }
25
+ /** Reports a CI boundary failure while retaining the release identity for a safe retry.
26
+ * @extends ReleaseStepError
27
+ */
28
+ export declare class CiReleaseError extends ReleaseStepError {
29
+ code: "ci-dispatch-unconfirmed" | "ci-preflight-failed" | "ci-run-lookup-failed";
30
+ /**
31
+ * @param {"ci-preflight-failed" | "ci-run-lookup-failed" | "ci-dispatch-unconfirmed"} code - Stable failure category.
32
+ * @param {string} message - Safe Spanish diagnostic.
33
+ * @param {string} hint - Recovery action preserving the existing release.
34
+ * @param {{ cause?: unknown }} [options] - Original dependency failure.
35
+ */
36
+ constructor(code: "ci-preflight-failed" | "ci-run-lookup-failed" | "ci-dispatch-unconfirmed", message: string, hint: string, options?: {
37
+ cause?: unknown;
38
+ });
39
+ }
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Adapts GitHub CLI for credential preflight and dispatch reconciliation.
3
+ * @module create-version/github-workflow
4
+ */
5
+ import { runCaptured } from "./process.js";
6
+ export type CiReleaseIdentity = {
7
+ version: string;
8
+ tag: string;
9
+ sha: string;
10
+ };
11
+ export type CiDispatchResult = {
12
+ status: "submitted" | "existing";
13
+ url: string | null;
14
+ };
15
+ export type ActionsBindingKind = "secret" | "variable";
16
+ export type GithubWorkflowClient = {
17
+ preflight: (workflow: string, secrets: string[], variables: string[]) => Promise<void>;
18
+ dispatch: (workflow: string, release: CiReleaseIdentity, retryCommand: string) => Promise<CiDispatchResult>;
19
+ };
20
+ /**
21
+ * @typedef {{ version: string, tag: string, sha: string }} CiReleaseIdentity
22
+ * @typedef {{ status: "submitted" | "existing", url: string | null }} CiDispatchResult
23
+ * @typedef {"secret" | "variable"} ActionsBindingKind
24
+ * @typedef {{
25
+ * preflight: (workflow: string, secrets: string[], variables: string[]) => Promise<void>,
26
+ * dispatch: (workflow: string, release: CiReleaseIdentity, retryCommand: string) => Promise<CiDispatchResult>,
27
+ * }} GithubWorkflowClient
28
+ */
29
+ /**
30
+ * Builds the `run-name` the generated workflow gives a dispatched release, which identifies its runs.
31
+ * @param {CiReleaseIdentity} release - Dispatched release.
32
+ * @returns {string} Run title, such as `astra-rp release v1.2.4 <sha>`.
33
+ */
34
+ export declare function formatCiReleaseRunTitle(release: CiReleaseIdentity): string;
35
+ /**
36
+ * Creates a GitHub workflow adapter with an explicit subprocess boundary.
37
+ * @param {string} repositoryRoot - Checkout whose origin selects the repository.
38
+ * @param {typeof runCaptured} [capture] - Process executor, injectable by other CLI hosts.
39
+ * @returns {GithubWorkflowClient} Preflight and dispatch operations.
40
+ */
41
+ export declare function createGithubWorkflowClient(repositoryRoot: string, capture?: typeof runCaptured): GithubWorkflowClient;
@@ -0,0 +1,28 @@
1
+ /**
2
+ * `@astra-kit/rp/create-version`: shared release command.
3
+ *
4
+ * Projects run it as `astra-rp create-version` and describe their differences
5
+ * in `astra-rp.config.js` (checks, migrations,
6
+ * preparation, publication). The pure planner and the state reader are
7
+ * exported for project tests and custom tooling.
8
+ *
9
+ * @module create-version
10
+ */
11
+ export type CreateVersionConfig = import("./config.js").CreateVersionConfig;
12
+ export type CiReleaseConfig = import("./ci-config.js").CiReleaseConfig;
13
+ /**
14
+ * @typedef {import("./config.js").CreateVersionConfig} CreateVersionConfig
15
+ * @typedef {import("./ci-config.js").CiReleaseConfig} CiReleaseConfig
16
+ */
17
+ export { computeNpmIntegrity, computeSha256, expandArtifactPattern, findPnpmPackRewrites, findPreparedArtifact, isSafeArtifactPath, verifyPreparedArtifact, withArtifactOutsidePackageRoot, } from "./artifact.js";
18
+ export { defineCreateVersionConfig, loadCreateVersionConfig, resolveCreateVersionConfig } from "./config.js";
19
+ export { CiReleaseError, ReleaseStepError } from "./errors.js";
20
+ export { resolveCiReleaseConfig } from "./ci-config.js";
21
+ export { buildNpmAuthConfigLine, buildNpmOwnerListArguments, buildNpmPublishArguments, buildNpmPublishEnvironment, buildNpmTokenEnvironment, buildNpmViewArguments, buildNpmWhoamiArguments, checkNpmPublishAccess, lookupPublishedVersions, parseNpmOwnerList, parseNpmPackDryRunOutput, publishToNpm, readNpmPackIntegrity, resolveNpmToken, resolvePublishRegistry, withNpmAuthConfig, } from "./npm.js";
22
+ export { describeNpmAuthProblem, describeNpmPublishFailure, describeNpmTokenSource } from "./npm-auth.js";
23
+ export { DEFAULT_CAPABILITIES, RELEASE_USAGE, buildReleasePlan, describeFeatureBranchGaps, parseReleaseArguments } from "./plan.js";
24
+ export { createGitReader, listCommits, parseCommitLog, readPackageManifestAt, readPackageVersionAt, runCaptured, runCommandLine, runInherited } from "./process.js";
25
+ export { createHookContext, runCreateVersion } from "./run.js";
26
+ export { collectReleaseState, findLastRelease, readChangelogState } from "./state.js";
27
+ export { isRegistryProvider, resolvePublicationOptions } from "./registry-config.js";
28
+ export { checkRegistryAccess, lookupRegistryVersions, resolveRegistry, selectProjectRegistry } from "./registry.js";