mirror of
https://github.com/changesets/action
synced 2026-10-26 16:39:56 +08:00
Add select-mode, version, pack and publish sub-actions (#656)
* Add select-mode, version, and publish sub-actions * Rename * No github-token needed for select-mode for now * extend select-mode with publish-plan check and upload * Rename base-branch to pr-base-branch * add `pack` subaction * `--from-pack` support in the publish subaction * rename CLI arg * update rolldown config * rename pack dir input/output * tweak retendion days --------- Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com>
This commit is contained in:
co-authored by
Mateusz Burzyński
parent
5649ff41b8
commit
a12d90de83
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"@changesets/action": minor
|
||||||
|
---
|
||||||
|
|
||||||
|
Add new `/select-mode`, `/version`, and `/publish` sub-actions to better control version and publish steps
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
# changesets/action/pack
|
||||||
|
|
||||||
|
TODO
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
name: Changesets - Pack
|
||||||
|
description: Pack publishable packages into tarballs
|
||||||
|
runs:
|
||||||
|
using: node24
|
||||||
|
main: ../dist/pack.js
|
||||||
|
inputs:
|
||||||
|
publish-plan-artifact-id:
|
||||||
|
description: "Artifact id for a publish plan generated by the select-mode subaction"
|
||||||
|
required: false
|
||||||
|
outputs:
|
||||||
|
pack-dir-artifact-id:
|
||||||
|
description: "Artifact id for the packed output directory"
|
||||||
|
branding:
|
||||||
|
icon: package
|
||||||
|
color: blue
|
||||||
@@ -17,6 +17,7 @@
|
|||||||
"release:pr": "node --experimental-strip-types ./scripts/release-pr.ts"
|
"release:pr": "node --experimental-strip-types ./scripts/release-pr.ts"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@actions/artifact": "^6.2.1",
|
||||||
"@actions/core": "^3.0.1",
|
"@actions/core": "^3.0.1",
|
||||||
"@actions/exec": "^3.0.0",
|
"@actions/exec": "^3.0.0",
|
||||||
"@actions/github": "^9.1.1",
|
"@actions/github": "^9.1.1",
|
||||||
|
|||||||
Generated
+943
-2
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,3 @@
|
|||||||
|
# changesets/action/publish
|
||||||
|
|
||||||
|
TODO
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
name: Changesets - Publish
|
||||||
|
description: Publish packages to npm
|
||||||
|
runs:
|
||||||
|
using: node24
|
||||||
|
main: ../dist/publish.js
|
||||||
|
inputs:
|
||||||
|
github-token:
|
||||||
|
description: "The GitHub token to use for authentication. Defaults to the GitHub-provided token."
|
||||||
|
required: false
|
||||||
|
default: ${{ github.token }}
|
||||||
|
script:
|
||||||
|
description: "The command to use to publish packages"
|
||||||
|
required: false
|
||||||
|
pack-dir-artifact-id:
|
||||||
|
description: "Artifact id for packed publish output generated by the pack subaction"
|
||||||
|
required: false
|
||||||
|
create-github-releases:
|
||||||
|
description: "Whether to create Github releases after publish"
|
||||||
|
required: false
|
||||||
|
default: true
|
||||||
|
outputs:
|
||||||
|
published:
|
||||||
|
description: "A boolean value to indicate whether a publishing has happened or not"
|
||||||
|
published-packages:
|
||||||
|
description: >
|
||||||
|
A JSON array to present the published packages. The format is `[{"name": "@xx/xx", "version": "1.2.0"}, {"name": "@xx/xy", "version": "0.8.9"}]`
|
||||||
|
branding:
|
||||||
|
icon: package
|
||||||
|
color: blue
|
||||||
+6
-2
@@ -3,8 +3,12 @@ import { defineConfig } from "rolldown";
|
|||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
input: {
|
input: {
|
||||||
index: "src/index.ts",
|
index: "src/index.ts",
|
||||||
["pr-status"]: "src/pr-status/index.ts",
|
pack: "src/pack/index.ts",
|
||||||
["pr-comment"]: "src/pr-comment/index.ts",
|
"pr-status": "src/pr-status/index.ts",
|
||||||
|
"pr-comment": "src/pr-comment/index.ts",
|
||||||
|
"select-mode": "src/select-mode/index.ts",
|
||||||
|
version: "src/version/index.ts",
|
||||||
|
publish: "src/publish/index.ts",
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
dir: "dist",
|
dir: "dist",
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
# changesets/action/select-mode
|
||||||
|
|
||||||
|
TODO
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
name: Changesets - Select Mode
|
||||||
|
description: Whether to version or publish in the current repo state
|
||||||
|
runs:
|
||||||
|
using: node24
|
||||||
|
main: ../dist/select-mode.js
|
||||||
|
inputs: {}
|
||||||
|
outputs:
|
||||||
|
mode:
|
||||||
|
description: "The mode to use for the current repo state: 'version', 'publish', or 'none'."
|
||||||
|
publish-plan-artifact-id:
|
||||||
|
description: "Artifact id for the generated publish plan when mode is `publish`"
|
||||||
|
branding:
|
||||||
|
icon: package
|
||||||
|
color: blue
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
import fs from "node:fs/promises";
|
||||||
|
import os from "node:os";
|
||||||
|
import path from "node:path";
|
||||||
|
import artifact from "@actions/artifact";
|
||||||
|
import * as core from "@actions/core";
|
||||||
|
import { downloadArtifact, execChangesetsCli } from "../utils.ts";
|
||||||
|
|
||||||
|
try {
|
||||||
|
await main();
|
||||||
|
} catch (err) {
|
||||||
|
core.setFailed((err as Error).message);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const publishPlanArtifactId = core.getInput("publish-plan-artifact-id");
|
||||||
|
|
||||||
|
// If the user needs to change the cwd, set `working-directory` in the step instead
|
||||||
|
const cwd = process.cwd();
|
||||||
|
const tmpDir = process.env.RUNNER_TEMP ?? (await fs.realpath(os.tmpdir()));
|
||||||
|
const outDir = path.join(tmpDir, `changeset-pack-${Date.now()}`);
|
||||||
|
|
||||||
|
await pack(cwd, {
|
||||||
|
outDir,
|
||||||
|
publishPlanPath: publishPlanArtifactId
|
||||||
|
? await downloadPublishPlanArtifact(tmpDir, Number(publishPlanArtifactId))
|
||||||
|
: undefined,
|
||||||
|
});
|
||||||
|
|
||||||
|
const packDirArtifact = await artifact.uploadArtifact(
|
||||||
|
`changeset-pack-${Date.now()}`,
|
||||||
|
await getFiles(outDir),
|
||||||
|
outDir,
|
||||||
|
{
|
||||||
|
retentionDays: 30,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if (packDirArtifact.id === undefined) {
|
||||||
|
throw new Error("Packed artifact upload did not return an artifact id");
|
||||||
|
}
|
||||||
|
core.setOutput("pack-dir-artifact-id", String(packDirArtifact.id));
|
||||||
|
}
|
||||||
|
|
||||||
|
async function pack(
|
||||||
|
cwd: string,
|
||||||
|
args: {
|
||||||
|
outDir: string;
|
||||||
|
publishPlanPath?: string;
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
const cliArgs = ["pack", "--out-dir", args.outDir];
|
||||||
|
if (args.publishPlanPath) {
|
||||||
|
cliArgs.push("--from-plan", args.publishPlanPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
await execChangesetsCli(cliArgs, {
|
||||||
|
cwd,
|
||||||
|
env: process.env,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function downloadPublishPlanArtifact(tmpDir: string, artifactId: number) {
|
||||||
|
const downloadPath = await downloadArtifact(
|
||||||
|
tmpDir,
|
||||||
|
artifactId,
|
||||||
|
"changeset-publish-plan",
|
||||||
|
);
|
||||||
|
return path.join(downloadPath, "publish-plan.json");
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getFiles(dir: string): Promise<string[]> {
|
||||||
|
const entries = await fs.readdir(dir, { withFileTypes: true });
|
||||||
|
const files = await Promise.all(
|
||||||
|
entries.map(async (entry) => {
|
||||||
|
const entryPath = path.join(dir, entry.name);
|
||||||
|
if (entry.isDirectory()) {
|
||||||
|
return getFiles(entryPath);
|
||||||
|
}
|
||||||
|
return [entryPath];
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
return files.flat();
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
import fs from "node:fs/promises";
|
||||||
|
import os from "node:os";
|
||||||
|
import * as core from "@actions/core";
|
||||||
|
import { Git } from "../git.ts";
|
||||||
|
import { setupOctokit } from "../octokit.ts";
|
||||||
|
import { runPublish } from "../run.ts";
|
||||||
|
import { downloadArtifact } from "../utils.ts";
|
||||||
|
|
||||||
|
try {
|
||||||
|
await main();
|
||||||
|
} catch (err) {
|
||||||
|
core.setFailed((err as Error).message);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const githubToken = core.getInput("github-token", { required: true });
|
||||||
|
const script = core.getInput("script");
|
||||||
|
const packDirArtifactId = core.getInput("pack-dir-artifact-id");
|
||||||
|
const createGithubReleases = core.getBooleanInput("create-github-releases");
|
||||||
|
|
||||||
|
// If the user needs to change the cwd, set `working-directory` in the step instead
|
||||||
|
const cwd = process.cwd();
|
||||||
|
|
||||||
|
const octokit = setupOctokit(githubToken);
|
||||||
|
// NOTE: Always pass octokit here as publish does not need a commit-mode
|
||||||
|
const git = new Git({ octokit, cwd });
|
||||||
|
|
||||||
|
const fromPackDir = packDirArtifactId
|
||||||
|
? await downloadArtifact(
|
||||||
|
process.env.RUNNER_TEMP ?? (await fs.realpath(os.tmpdir())),
|
||||||
|
Number(packDirArtifactId),
|
||||||
|
"changeset-pack",
|
||||||
|
)
|
||||||
|
: undefined;
|
||||||
|
|
||||||
|
const result = await runPublish({
|
||||||
|
script,
|
||||||
|
githubToken,
|
||||||
|
git,
|
||||||
|
octokit,
|
||||||
|
createGithubReleases,
|
||||||
|
cwd,
|
||||||
|
fromPackDir,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (result.published) {
|
||||||
|
core.setOutput("published", "true");
|
||||||
|
core.setOutput(
|
||||||
|
"published-packages",
|
||||||
|
JSON.stringify(result.publishedPackages),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
core.setOutput("published", "false");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.exitCode !== 0) {
|
||||||
|
throw new Error(
|
||||||
|
`Publish command exited with code ${result.exitCode}${
|
||||||
|
result.published
|
||||||
|
? `, but some packages were published: ${result.publishedPackages
|
||||||
|
.map((p) => `${p.name}@${p.version}`)
|
||||||
|
.join(", ")}`
|
||||||
|
: ""
|
||||||
|
}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
+32
-20
@@ -1,8 +1,12 @@
|
|||||||
import fs from "node:fs/promises";
|
import fs from "node:fs/promises";
|
||||||
import { createRequire } from "node:module";
|
|
||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
import * as core from "@actions/core";
|
import * as core from "@actions/core";
|
||||||
import { exec, getExecOutput } from "@actions/exec";
|
import {
|
||||||
|
exec,
|
||||||
|
getExecOutput,
|
||||||
|
type ExecOptions,
|
||||||
|
type ExecOutput,
|
||||||
|
} from "@actions/exec";
|
||||||
import * as github from "@actions/github";
|
import * as github from "@actions/github";
|
||||||
import type { PreState } from "@changesets/types";
|
import type { PreState } from "@changesets/types";
|
||||||
import { type Package, getPackages } from "@manypkg/get-packages";
|
import { type Package, getPackages } from "@manypkg/get-packages";
|
||||||
@@ -10,15 +14,15 @@ import { Git } from "./git.ts";
|
|||||||
import type { Octokit } from "./octokit.ts";
|
import type { Octokit } from "./octokit.ts";
|
||||||
import readChangesetState from "./readChangesetState.ts";
|
import readChangesetState from "./readChangesetState.ts";
|
||||||
import {
|
import {
|
||||||
|
execChangesetsCli,
|
||||||
getChangedPackages,
|
getChangedPackages,
|
||||||
getChangelogEntry,
|
getChangelogEntry,
|
||||||
|
getExecOutputChangesetsCli,
|
||||||
getVersionsByDirectory,
|
getVersionsByDirectory,
|
||||||
isErrorWithCode,
|
isErrorWithCode,
|
||||||
sortTheThings,
|
sortTheThings,
|
||||||
} from "./utils.ts";
|
} from "./utils.ts";
|
||||||
|
|
||||||
const require = createRequire(import.meta.url);
|
|
||||||
|
|
||||||
// GitHub Issues/PRs messages have a max size limit on the
|
// GitHub Issues/PRs messages have a max size limit on the
|
||||||
// message body payload.
|
// message body payload.
|
||||||
// `body is too long (maximum is 65536 characters)`.
|
// `body is too long (maximum is 65536 characters)`.
|
||||||
@@ -58,7 +62,8 @@ const createRelease = async (
|
|||||||
};
|
};
|
||||||
|
|
||||||
type PublishOptions = {
|
type PublishOptions = {
|
||||||
script: string;
|
script?: string;
|
||||||
|
fromPackDir?: string;
|
||||||
githubToken: string;
|
githubToken: string;
|
||||||
octokit: Octokit;
|
octokit: Octokit;
|
||||||
createGithubReleases: boolean;
|
createGithubReleases: boolean;
|
||||||
@@ -81,17 +86,36 @@ type PublishResult =
|
|||||||
|
|
||||||
export async function runPublish({
|
export async function runPublish({
|
||||||
script,
|
script,
|
||||||
|
fromPackDir,
|
||||||
githubToken,
|
githubToken,
|
||||||
git,
|
git,
|
||||||
octokit,
|
octokit,
|
||||||
createGithubReleases,
|
createGithubReleases,
|
||||||
cwd,
|
cwd,
|
||||||
}: PublishOptions): Promise<PublishResult> {
|
}: PublishOptions): Promise<PublishResult> {
|
||||||
let changesetPublishOutput = await getExecOutput(script, undefined, {
|
let changesetPublishOutput: ExecOutput;
|
||||||
|
const execOptions: ExecOptions = {
|
||||||
cwd,
|
cwd,
|
||||||
ignoreReturnCode: true,
|
ignoreReturnCode: true,
|
||||||
env: { ...process.env, GITHUB_TOKEN: githubToken },
|
env: { ...process.env, GITHUB_TOKEN: githubToken },
|
||||||
});
|
};
|
||||||
|
|
||||||
|
if (script) {
|
||||||
|
changesetPublishOutput = await getExecOutput(
|
||||||
|
script,
|
||||||
|
undefined,
|
||||||
|
execOptions,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const args = ["publish"];
|
||||||
|
if (fromPackDir) {
|
||||||
|
args.push("--from-pack-dir", fromPackDir);
|
||||||
|
}
|
||||||
|
changesetPublishOutput = await getExecOutputChangesetsCli(
|
||||||
|
args,
|
||||||
|
execOptions,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let { packages, tool } = await getPackages(cwd);
|
let { packages, tool } = await getPackages(cwd);
|
||||||
let releasedPackages: Package[] = [];
|
let releasedPackages: Package[] = [];
|
||||||
@@ -277,19 +301,7 @@ export async function runVersion({
|
|||||||
if (script) {
|
if (script) {
|
||||||
await exec(script, undefined, { cwd, env });
|
await exec(script, undefined, { cwd, env });
|
||||||
} else {
|
} else {
|
||||||
await exec(
|
await execChangesetsCli(["version"], { cwd, env });
|
||||||
"node",
|
|
||||||
[
|
|
||||||
require.resolve("@changesets/cli/bin.js", {
|
|
||||||
paths: [cwd],
|
|
||||||
}),
|
|
||||||
"version",
|
|
||||||
],
|
|
||||||
{
|
|
||||||
cwd,
|
|
||||||
env,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let changedPackages = await getChangedPackages(cwd, versionsByDirectory);
|
let changedPackages = await getChangedPackages(cwd, versionsByDirectory);
|
||||||
|
|||||||
@@ -0,0 +1,117 @@
|
|||||||
|
import fs from "node:fs/promises";
|
||||||
|
import os from "node:os";
|
||||||
|
import path from "node:path";
|
||||||
|
import artifact from "@actions/artifact";
|
||||||
|
import * as core from "@actions/core";
|
||||||
|
import readChangesetState from "../readChangesetState.ts";
|
||||||
|
import { execChangesetsCli } from "../utils.ts";
|
||||||
|
|
||||||
|
type ModeResult =
|
||||||
|
| {
|
||||||
|
mode: "none";
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
mode: "version";
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
mode: "publish";
|
||||||
|
publishPlanPath: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type PublishPlan = unknown[];
|
||||||
|
|
||||||
|
try {
|
||||||
|
await main();
|
||||||
|
} catch (err) {
|
||||||
|
core.setFailed((err as Error).message);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const result = await getMode();
|
||||||
|
core.setOutput("mode", result.mode);
|
||||||
|
if (result.mode === "publish") {
|
||||||
|
const publishPlanArtifact = await artifact.uploadArtifact(
|
||||||
|
path.basename(result.publishPlanPath, ".json"),
|
||||||
|
[result.publishPlanPath],
|
||||||
|
path.dirname(result.publishPlanPath),
|
||||||
|
{
|
||||||
|
skipArchive: true,
|
||||||
|
retentionDays: 30,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if (publishPlanArtifact.id === undefined) {
|
||||||
|
throw new Error(
|
||||||
|
"Publish plan artifact upload did not return an artifact id",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
core.setOutput("publish-plan-artifact-id", String(publishPlanArtifact.id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getMode(): Promise<ModeResult> {
|
||||||
|
const { changesets } = await readChangesetState();
|
||||||
|
|
||||||
|
if (changesets.length > 0) {
|
||||||
|
const hasNonEmptyChangesets = changesets.some(
|
||||||
|
(changeset) => changeset.releases.length > 0,
|
||||||
|
);
|
||||||
|
if (hasNonEmptyChangesets) {
|
||||||
|
return { mode: "version" };
|
||||||
|
}
|
||||||
|
return { mode: "none" };
|
||||||
|
}
|
||||||
|
|
||||||
|
const cwd = process.cwd();
|
||||||
|
const publishPlanPath = path.join(
|
||||||
|
process.env.RUNNER_TEMP ?? (await fs.realpath(os.tmpdir())),
|
||||||
|
`changeset-publish-plan-${Date.now()}.json`,
|
||||||
|
);
|
||||||
|
await execChangesetsCli(["publish-plan", "--output", publishPlanPath], {
|
||||||
|
cwd,
|
||||||
|
env: process.env,
|
||||||
|
});
|
||||||
|
|
||||||
|
const publishPlan = await readPublishPlan(publishPlanPath);
|
||||||
|
if (publishPlan.length === 0) {
|
||||||
|
return { mode: "none" };
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
mode: "publish",
|
||||||
|
publishPlanPath,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function readPublishPlan(publishPlanPath: string): Promise<PublishPlan> {
|
||||||
|
let rawPlan: string;
|
||||||
|
try {
|
||||||
|
rawPlan = await fs.readFile(publishPlanPath, "utf8");
|
||||||
|
} catch (err) {
|
||||||
|
throw new Error(`Failed to read publish plan at ${publishPlanPath}`, {
|
||||||
|
cause: err,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let plan: unknown;
|
||||||
|
try {
|
||||||
|
plan = JSON.parse(rawPlan);
|
||||||
|
} catch (err) {
|
||||||
|
throw new Error(`Failed to parse publish plan at ${publishPlanPath}`, {
|
||||||
|
cause: err,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
typeof plan !== "object" ||
|
||||||
|
plan === null ||
|
||||||
|
!("version" in plan) ||
|
||||||
|
typeof plan.version !== "number" ||
|
||||||
|
!("plan" in plan) ||
|
||||||
|
!Array.isArray(plan.plan)
|
||||||
|
) {
|
||||||
|
throw new Error(
|
||||||
|
`Invalid publish plan at ${publishPlanPath}: expected { version: number; plan: unknown[] }`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return plan.plan;
|
||||||
|
}
|
||||||
@@ -1,6 +1,17 @@
|
|||||||
import fs from "node:fs/promises";
|
import fs from "node:fs/promises";
|
||||||
|
import { createRequire } from "node:module";
|
||||||
|
import path from "node:path";
|
||||||
|
import artifact from "@actions/artifact";
|
||||||
|
import {
|
||||||
|
exec,
|
||||||
|
getExecOutput,
|
||||||
|
type ExecOptions as ActionsExecOptions,
|
||||||
|
type ExecOutput,
|
||||||
|
} from "@actions/exec";
|
||||||
import { getPackages, type Package } from "@manypkg/get-packages";
|
import { getPackages, type Package } from "@manypkg/get-packages";
|
||||||
|
|
||||||
|
const require = createRequire(import.meta.url);
|
||||||
|
|
||||||
export const BumpLevels = {
|
export const BumpLevels = {
|
||||||
dep: 0,
|
dep: 0,
|
||||||
patch: 1,
|
patch: 1,
|
||||||
@@ -111,3 +122,57 @@ export function fileExists(filePath: string) {
|
|||||||
() => false,
|
() => false,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function resolveChangesetsCli(cwd: string) {
|
||||||
|
return require.resolve("@changesets/cli/bin.js", {
|
||||||
|
paths: [cwd],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ExecOptions extends Omit<ActionsExecOptions, "env"> {
|
||||||
|
env?: Record<string, string | undefined>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function execChangesetsCli(args: string[], options?: ExecOptions) {
|
||||||
|
return exec(
|
||||||
|
"node",
|
||||||
|
[resolveChangesetsCli(options?.cwd ?? process.cwd()), ...args],
|
||||||
|
options as ActionsExecOptions,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getExecOutputChangesetsCli(
|
||||||
|
args: string[],
|
||||||
|
options?: ExecOptions,
|
||||||
|
): Promise<ExecOutput> {
|
||||||
|
return getExecOutput(
|
||||||
|
"node",
|
||||||
|
[resolveChangesetsCli(options?.cwd ?? process.cwd()), ...args],
|
||||||
|
options as ActionsExecOptions,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function downloadArtifact(
|
||||||
|
tmpDir: string,
|
||||||
|
artifactId: number,
|
||||||
|
name: string,
|
||||||
|
) {
|
||||||
|
if (!Number.isInteger(artifactId) || artifactId <= 0) {
|
||||||
|
throw new Error(
|
||||||
|
`Invalid ${JSON.stringify(name)} artifact id: ${artifactId}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const downloadPath = path.join(tmpDir, `${name}-${artifactId}-${Date.now()}`);
|
||||||
|
const result = await artifact.downloadArtifact(artifactId, {
|
||||||
|
path: downloadPath,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!result.downloadPath) {
|
||||||
|
throw new Error(
|
||||||
|
`${JSON.stringify(name)} artifact download did not return a path for artifact ${artifactId}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.downloadPath;
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
import * as core from "@actions/core";
|
||||||
|
import { Git } from "../git.ts";
|
||||||
|
import { setupOctokit } from "../octokit.ts";
|
||||||
|
import { runVersion } from "../run.ts";
|
||||||
|
|
||||||
|
try {
|
||||||
|
await main();
|
||||||
|
} catch (err) {
|
||||||
|
core.setFailed((err as Error).message);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const githubToken = core.getInput("github-token", { required: true });
|
||||||
|
const script = core.getInput("script");
|
||||||
|
const commitMessage = core.getInput("commit-message", { required: true });
|
||||||
|
const prTitle = core.getInput("pr-title", { required: true });
|
||||||
|
const prDraft = core.getInput("pr-draft") || undefined;
|
||||||
|
const prBaseBranch = core.getInput("pr-base-branch");
|
||||||
|
const commitMode = core.getInput("commit-mode") || "git-cli";
|
||||||
|
const setupGitUser = core.getBooleanInput("setup-git-user");
|
||||||
|
|
||||||
|
// Validations
|
||||||
|
if (prDraft !== undefined && prDraft !== "always" && prDraft !== "create") {
|
||||||
|
throw new Error(`Invalid pr-draft input: ${prDraft}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the user needs to change the cwd, set `working-directory` in the step instead
|
||||||
|
const cwd = process.cwd();
|
||||||
|
|
||||||
|
const octokit = setupOctokit(githubToken);
|
||||||
|
const git = new Git({
|
||||||
|
octokit: commitMode === "github-api" ? octokit : undefined,
|
||||||
|
cwd,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (setupGitUser) {
|
||||||
|
core.info("setting git user");
|
||||||
|
await git.setupUser();
|
||||||
|
}
|
||||||
|
|
||||||
|
const { pullRequestNumber } = await runVersion({
|
||||||
|
script,
|
||||||
|
githubToken,
|
||||||
|
git,
|
||||||
|
octokit,
|
||||||
|
cwd,
|
||||||
|
prTitle,
|
||||||
|
commitMessage,
|
||||||
|
// TODO: Use neutral message for PR description
|
||||||
|
hasPublishScript: true,
|
||||||
|
prDraft,
|
||||||
|
branch: prBaseBranch,
|
||||||
|
});
|
||||||
|
|
||||||
|
core.setOutput("pr-number", String(pullRequestNumber));
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
# changesets/action/version
|
||||||
|
|
||||||
|
TODO
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
name: Changesets - Version
|
||||||
|
description: Version packages
|
||||||
|
runs:
|
||||||
|
using: node24
|
||||||
|
main: ../dist/version.js
|
||||||
|
inputs:
|
||||||
|
github-token:
|
||||||
|
description: "The GitHub token to use for authentication. Defaults to the GitHub-provided token."
|
||||||
|
required: false
|
||||||
|
default: ${{ github.token }}
|
||||||
|
script:
|
||||||
|
description: "The command to use to publish packages"
|
||||||
|
required: false
|
||||||
|
commit-message:
|
||||||
|
description: "The commit message. Default to `Version Packages`"
|
||||||
|
required: false
|
||||||
|
default: "Version Packages"
|
||||||
|
pr-title:
|
||||||
|
description: "The pull request title. Default to `Version Packages`"
|
||||||
|
required: false
|
||||||
|
default: "Version Packages"
|
||||||
|
pr-draft:
|
||||||
|
description: "Controls draft PR behavior. Use 'create' to create new version PRs as draft, or 'always' to also convert existing version PRs back to draft when updating them."
|
||||||
|
required: false
|
||||||
|
pr-base-branch:
|
||||||
|
description: "Sets the base branch of the PR. Defaults to `github.ref_name`."
|
||||||
|
required: false
|
||||||
|
commit-mode:
|
||||||
|
description: >
|
||||||
|
An enum to specify the commit mode. Use "git-cli" to push changes using the Git CLI,
|
||||||
|
or "github-api" to push changes via the GitHub API. When using "github-api",
|
||||||
|
all commits and tags are signed using GitHub's GPG key and attributed to the user
|
||||||
|
or app who owns the GITHUB_TOKEN.
|
||||||
|
required: false
|
||||||
|
default: "git-cli"
|
||||||
|
setup-git-user:
|
||||||
|
description: Sets up the git user for commits as `"github-actions[bot]"`. Default to `true`
|
||||||
|
required: false
|
||||||
|
default: true
|
||||||
|
outputs: {}
|
||||||
|
branding:
|
||||||
|
icon: package
|
||||||
|
color: blue
|
||||||
Reference in New Issue
Block a user