Skip to content

Conversation

@jeremywiebe
Copy link
Collaborator

@jeremywiebe jeremywiebe commented Oct 29, 2025

Summary:

This PR co-locates the two jobs that publish to npm (release and snapshot). This is a necessity for enabling Trusted Publishing (https://docs.npmjs.com/trusted-publishers#how-trusted-publishing-works).

Once this PR has landed, we'll be able to go into each npm package's settings on npmjs.com and enable Trusted Publishing. Once that's enabled, we no longer need a npm token (stored in NPM_TOKEN) in this repo at all and will no longer have to manage an auth token for publishing to npm.

Issue: LEMS-3681

Test plan:

😅 This will be tricky.

  • I plan to land this PR and then enable trusted publishing for all perseus packages.
  • Once that's enabled, I'll try a snapshot publish by invoking it manually using workflow_dispatch
  • If that succeeds, I'll create a tiny release that touches all packages (I'll update/add a comment in each package's code) and then cut a release to test the release flow works also.
  • Finally, I'll work through the workflow files and remove references to NPM_TOKEN and remove that secret from this repo.

@github-actions
Copy link
Contributor

github-actions bot commented Oct 29, 2025

🗄️ Schema Change: No Changes ✅

@github-actions
Copy link
Contributor

github-actions bot commented Oct 29, 2025

🛠️ Item Splitting: No Changes ✅

@github-actions
Copy link
Contributor

github-actions bot commented Oct 29, 2025

Size Change: 0 B

Total Size: 497 kB

ℹ️ View Unchanged
Filename Size
packages/kas/dist/es/index.js 20.8 kB
packages/keypad-context/dist/es/index.js 1 kB
packages/kmath/dist/es/index.js 5.98 kB
packages/math-input/dist/es/index.js 99.2 kB
packages/math-input/dist/es/strings.js 1.61 kB
packages/perseus-core/dist/es/index.item-splitting.js 13.1 kB
packages/perseus-core/dist/es/index.js 22.4 kB
packages/perseus-editor/dist/es/index.js 96.8 kB
packages/perseus-linter/dist/es/index.js 7.21 kB
packages/perseus-score/dist/es/index.js 9.2 kB
packages/perseus-utils/dist/es/index.js 403 B
packages/perseus/dist/es/index.js 204 kB
packages/perseus/dist/es/strings.js 7.73 kB
packages/pure-markdown/dist/es/index.js 1.39 kB
packages/simple-markdown/dist/es/index.js 6.71 kB

compressed-size-action

@github-actions
Copy link
Contributor

github-actions bot commented Oct 29, 2025

npm Snapshot: Published

Good news!! We've packaged up the latest commit from this PR (41c45a1) and published it to npm. You
can install it using the tag PR2999.

Example:

pnpm add @khanacademy/perseus@PR2999

If you are working in Khan Academy's frontend, you can run the below command.

./dev/tools/bump_perseus_version.ts -t PR2999

If you are working in Khan Academy's webapp, you can run the below command.

./dev/tools/bump_perseus_version.js -t PR2999

@jeremywiebe
Copy link
Collaborator Author

jeremywiebe commented Oct 29, 2025

Verified that the snapshot publish works (it happened right on this PR!)

image

https://www.npmjs.com/package/@khanacademy/math-input/v/0.0.0-PR2999-20251029180740

And the Provenance reports the correct (new) workflow filename!

image

@jeremywiebe jeremywiebe marked this pull request as ready for review October 29, 2025 18:15
@jeremywiebe jeremywiebe requested review from a team, jandrade and somewhatabstract October 29, 2025 18:15
label-name: item-splitting-change
comment-title: 🛠️ Item Splitting

publish_snapshot:
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is basically copy-pasted over to publish.yml.

@@ -1,96 +0,0 @@
name: Release
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was all moved into publish.yml also.

Copy link
Collaborator Author

@jeremywiebe jeremywiebe Oct 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This workflow only deals with publishing to Chromatic, so I've renamed the workflow file to be clearer (as we do Storybook stuff elsewhere too: gh-pages.yml, which publishes Storybook to our GitHub Pages environment).

Comment on lines +7 to +16
inputs:
run_type:
description: "The type of publish to test"
required: true
default: "snapshot"
type: choice
options:
- snapshot
- release

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding an input so that we can manually start either job in this file.

Comment on lines 28 to 32
concurrency:
group: ${{ github.workflow }}
# IMPORTANT! We do not want to cancel in-progress runs, because we don't
# want a production publish to be interrupted by a snapshot publish ever.
cancel-in-progress: false
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This requires attention during review. I'm setting it so this workflow can only run one job at a time. This could mean snapshots take longer, but I think it's worth protecting.

Open to thoughts on other ways or things I'm missing.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm pretty sure that this stuff is idempotent, so I don't think it matters if they are concurrent. Only one will win and the others will error out somehow.

I agree that we shouldn't cancel in progress though.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's mostly idempotent. However, if there were two pushes to a PR in close succession, the earlier one could complete after the latter resulting in the wrong code being marked as the "latest" version of that snapshot on npm.

Oh! If I add the branch, then we'd have safety for snapshot runs, but would be able to run a full release with any mount of snapshots safely and simultaneously.

I'll update that.

 ${{ github.workflow }}-${{ github.ref }}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like this race was addressed in Wonder Blocks a while back by me. I don't remember what I did though.

Comment on lines 34 to 38
permissions:
id-token: write # Required for OIDC/Trusted Publishing and provenance
contents: write # For GitHub pages and creating release PRs
pull-requests: write # For snapshot PR comments
issues: write # For PR comments
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the union of permissions that the release and snapshot jobs had in the other files.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check the GitHub docs to verify what you need. At the job level, permissions are a complete overwrite, so if you want to add permissions, you also need to list the default permissions.

I don't know how workflow-level permissions integrate with job level. I would assume they are additive to avoid needing to explicitly list defaults, but worth checking to be sure.

Comment on lines +64 to +66
if: |
(github.event_name == 'workflow_dispatch' && inputs.run_type == 'release') ||
(github.event_name == 'push' && github.ref == 'refs/heads/main')
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the same as the original if but adds workflow_dispatch and checking the input param to see if we're asked to run this job.

Comment on lines 69 to 70
id-token: write # required for publishing to npm with provenance
contents: write # required for creating pull requests
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I don't think this is needed given we define permissions at the file-level above.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it is. I would remove it. You'll find out the first time you use this and it'll be easy to fix.

Comment on lines +135 to +136
(github.event_name == 'workflow_dispatch' && inputs.run_type == 'snapshot') ||
(github.event_name == 'pull_request' && !startsWith(github.head_ref, 'changeset-release/'))
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the same as the original if but adds workflow_dispatch and checking the input param to see if we're asked to run this job.

Comment on lines 138 to 140
permissions:
id-token: write # required for publishing to npm with provenance
pull-requests: write # required because we write a comment on the PR
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, I think I can remove this now that we have permissions defined at the file level.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this will run on your PR, why not remove it and try it. Easy to fix if it's needed.

Copy link
Member

@somewhatabstract somewhatabstract left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me. Some inline comments but nothing huge.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

praise: Thanks for making this clarifying change!

Comment on lines 28 to 32
concurrency:
group: ${{ github.workflow }}
# IMPORTANT! We do not want to cancel in-progress runs, because we don't
# want a production publish to be interrupted by a snapshot publish ever.
cancel-in-progress: false
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm pretty sure that this stuff is idempotent, so I don't think it matters if they are concurrent. Only one will win and the others will error out somehow.

I agree that we shouldn't cancel in progress though.

Comment on lines 34 to 38
permissions:
id-token: write # Required for OIDC/Trusted Publishing and provenance
contents: write # For GitHub pages and creating release PRs
pull-requests: write # For snapshot PR comments
issues: write # For PR comments
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check the GitHub docs to verify what you need. At the job level, permissions are a complete overwrite, so if you want to add permissions, you also need to list the default permissions.

I don't know how workflow-level permissions integrate with job level. I would assume they are additive to avoid needing to explicitly list defaults, but worth checking to be sure.

Comment on lines 69 to 70
id-token: write # required for publishing to npm with provenance
contents: write # required for creating pull requests
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it is. I would remove it. You'll find out the first time you use this and it'll be easy to fix.

Comment on lines 138 to 140
permissions:
id-token: write # required for publishing to npm with provenance
pull-requests: write # required because we write a comment on the PR
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this will run on your PR, why not remove it and try it. Easy to fix if it's needed.

@github-actions github-actions bot added schema-change Attached to PRs when we detect Perseus Schema changes in it item-splitting-change and removed schema-change Attached to PRs when we detect Perseus Schema changes in it labels Nov 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants