Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 410
Add select-mode, version, pack and publish sub-actions#656
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
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
0595e1b26f6f8c40c95bc9fc198110ef577d5aac8f7c582483723a6aae062ce93abc0e2600e0b1c57c8cFile filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| "@changesets/action": minor | ||
| --- | ||
| Add new `/select-mode`, `/version`, and `/publish` sub-actions to better control version and publish steps |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| # changesets/action/pack | ||
| TODO |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
Large diffs are not rendered by default.
Uh oh!
There was an error while loading. Please reload this page.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| # changesets/action/publish | ||
| TODO |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| # changesets/action/select-mode | ||
| TODO |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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(); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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(", ")}` | ||
| : "" | ||
| }`, | ||
| ); | ||
| } | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note how with a custom publish
scriptwe don't handlefromPackDirat all. My best idea to handle this would be to also add support for passing this argument~ through CLI args. That way the scripts could forwardenvto the underlyingchangesets publishkinda naturally - without messing with flags forwarding. Thoughts?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer not relying on envs as it can be sometimes hard to follow who set what at when. Maybe we can support some sort of interpolation? Like
script: pnpm format && pnpm changeset publish $action_argsor... publish --from-pack-dir $action_from_pack_dir. Just need to make sure to prevent potential script injections.OR do we even need to allow specifying a script now? Since the sub-actions are explicit invocations now, if they need a pre-command or post-command, just do it in a pre-post-step. If they need a different version/publishing scheme, then don't call our action.
But I think what you have now is also fine and then we extend it later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I also wondered about that. Removing it would allow us to gather actual use cases for custom scripts before we re-commit to supporting them.
That said, it would break
changesets/action's own publishing pipeline - or at least, it would make it more cumbersome~. But perhaps it wouldn't be too bad if only we'd exposechangesets/action/github-releaseUh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For
changesets/action, I think our publish script could be called directly like before without using the sub-action. For version though, I guess we need like a pre/post hook to make changes before we commit 🤔There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For now, we can stick to using the old root action - and figure this one later.