Skip to content
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

Release "workflow" for @cubing projects #3

Open
jfly opened this issue Jan 9, 2025 · 6 comments
Open

Release "workflow" for @cubing projects #3

jfly opened this issue Jan 9, 2025 · 6 comments

Comments

@jfly
Copy link
Member

jfly commented Jan 9, 2025

Today, releasing @cubing projects requires running scripts on a developer's laptop. This is error-prone, and we don't always do it correctly. See cubing/icons#143 (comment).

We do have some tooling to generate github releases for commits that appear to have version tags: https://github.com/cubing/actions-workflows/blob/02f6b937ac2a350970b0aa47b30e1acb4ec038ad/.github/workflows/publish-github-release.yaml

For my personal open source projects, releasing every time main changes is sufficient. My understanding is that this would be sufficient for all @cubing projects at their current level of activity/maturity. @lgarron, feel free to disagree.

I am familiar with a few tools in the Conventional Commits* ecosystem:

*Note: I don't actually love Conventional Commits, but I am sold on the fact that they automate releasing (no human needs to be involved to pick a "next version" number). Another way to get humans out of the loop is CalVer (which I personally prefer to semver).

@jfly jfly mentioned this issue Jan 9, 2025
@lgarron
Copy link
Member

lgarron commented Jan 9, 2025

Thanks for filing this, I've been hoping to implement a process for this for a long time!

For my personal open source projects, releasing every time main changes is sufficient. My understanding is that this would be sufficient for all @cubing projects at their current level of activity/maturity. @lgarron, feel free to disagree.

That's definitely not the case, we have a few projects that sometimes have a dozen or more commits to main per day. It's also sometimes useful to allow merging code to main separately from vetting all of main for a full release every time.

I'll have to take a closer look at those links, but I'm definitely agreed that:

  • We should definitely have a process that does not require running on a developer's laptop. (I think it would be good if this still possible, in order to handle exceptional cases and debug/unbork some situations. But I would be okay if this required jumping through some hoops).
  • I also like the ideas behind Conventional Commits, while being unenthused with their implementation details1. Something else in that space could be great.
  • A button you can use to perform the full publication process without human input would be great. In practice, I think it would need to:
    • Be runnable from a GitHub Actions workflow as a manual trigger.
    • Commit the version number to the relevant ecosystem package files. (I've started using code to do this instead of constructing the command myself — see repo version bump.)
    • Synthesize release notes from somewhere (e.g. commit messages or in-tree release notes), and include them in the release.
    • Publish the release to the relevant package managers and to GitHub.

I think the most "common" approach using the GitHub UI is to create a release by clicking in the GitHub releases page for the repo, but I think this is a worse approach than something integrated with package versioning and publication.

Regarding versioning semantics: In practice, I think semantic versioning would cause the fewest complications (and it's effectively what we've been using for a very long time).

Footnotes

  1. I find their commit prefixes to be visual noise, and find it more useful to identify a part of the project in a commit prefix. See the cubing.js history for a lot of examples of this: https://github.com/cubing/cubing.js/commits/main/

@lgarron
Copy link
Member

lgarron commented Jan 9, 2025

Additional things:

Scoped tokens

Something that came up in conversation with @jfly: if we use GitHub Actions to publish, I would like to insist that each project has its own token that is scoped to just that project when possible.

In particular, npm has package-scoped tokens, but this cannot be done programmatically yet: npm/npm-profile#158

I would be okay creating these tokens by hand in the short-term, but I don't want it to be easy to use a token with overly broad permissions by accident (failing to add restrictions) or on purpose (e.g. when rushing to fix an issue). Best would be to have a tool for developers to generate and upload these tokens without any room for human mistakes.

Related packages

We have some related packages that are commonly published together. In particular, when we release cubing.js we also:

  • Bump the version of cubing in create-cubing-app and immediately publish a release with the same version.
  • Bump the version of cubing in cdn.cubing.net. Since cdn.cubing.net is not a package, this does not get published to a package manager, but it does get deployed instantly.

I think the simplest approach would be for the cubing.js publication to trigger a workflow in each of its downstream repos.

There are also other situations like:

Deployments

Moved to: #4

DNS

Moved to: #5

@jfly
Copy link
Member Author

jfly commented Jan 9, 2025

we have a few projects that sometimes have a dozen or more commits to main per day

IMO, this does not seem like a good reason not to release on every change to main.

It's also sometimes useful to allow merging code to main separately from vetting all of main for a full release every time.

This is a good reason.

I also like the ideas behind Conventional Commits, while being unenthused with their implementation details [...] I find their commit prefixes to be visual noise

I agree on the visual noise issue. I believe that changesets (implemented by knope, but the concept comes from https://github.com/changesets/changesets) might be a nice alternative to conventional commits. Instead of putting weird keywords in your commit messages, you document your changes in changeset files, which tooling converts into a "next release number" and a changelog.

and find it more useful to identify a part of the project in a commit prefix.

For the record, it is common for convention commits to include a parenthesized "scope".

A button you can use to perform the full publication process without human input would be great

Are you familiar with Knope/release-please's solutions to this? See:

I prefer the preview workflow more than the release button approach:

  • Previews: you can actually see what the CHANGELOG will look like, and any changes to version numbers in package.json/Cargo.toml files.
  • CI: you can see that the release actually builds/passes tests.
  • Engagement/subscriptions: people who are eagerly awaiting that next release can comment on the PR, and subscribe for updates.

Multiple simultaneously published packages in the same repo

I believe this is a pretty common pattern these days, especially in the JS/Rust ecosystem. For example, see Knope's docs on Releasing multiple packages.

Multiple ecosystems in the same repo

I don't think this would be an issue with any of the tools mentioned above. Definitely should try it out.

In particular, when we release cubing.js we also [...] Bump the version of cubing in create-cubing-app and immediately publish a release with the same version

At first glance, this smells like an antipattern to me. Perhaps these things should live in a monorepo? That said, I'm sure we can figure something out here.

Deployments

There are some interesting thoughts here, which I'm super down to discuss, but I think we're getting out of scope. Let's keep this issue about picking a release workflow we're happy with (and ideally a tool that implements that workflow). IMO, the actual "getting stuff deployed to npm.js/crates.io/GH pages/Dreamhost" is an important, but separate problem.

@jfly jfly changed the title Continuous deployment (CD) patterns/infra Release "workflow" for @cubing projects Jan 9, 2025
@lgarron
Copy link
Member

lgarron commented Jan 9, 2025

Sounds good, agreed with the updated scope/title. I don't want to lose track of the deployment topic, though, so I'll remove that from above and put it in a new issue!

@lgarron
Copy link
Member

lgarron commented Jan 9, 2025

For the record, it is common for convention commits to include a parenthesized "scope".

Also: neat, didn't realize that! TIL, thanks!

(I guess I've been so fussed by the visual noise that I developed warning fatigue and never really picked up on that.)

@lgarron
Copy link
Member

lgarron commented Jan 9, 2025

we have a few projects that sometimes have a dozen or more commits to main per day

IMO, this does not seem like a good reason not to release on every change to main.

I guess my implicit reason here was "this interacts badly with other ecosystems if we published on every commit to main".

  • We could run into publication rate limits or anti-spam measures.
  • Unless we implement something clever, we would publish on maintenance commits that do not even affect a single byte of the published code. I don't think there's anything at the right level of cleverness here.
  • People using Dependabot for version bumps would get a lot of update notifications for releases that contain no effective changes for them.

Are you familiar with Knope/release-please's solutions to this? See:

Oooh, this is the first I'm hearing of this idea, I love it!

(Assuming that it can be done without notification churn for maintainers.)

I believe this is a pretty common pattern these days, especially in the JS/Rust ecosystem. For example, see Knope's docs on Releasing multiple packages.

Ooh, very encouragning!

In particular, when we release cubing.js we also [...] Bump the version of cubing in create-cubing-app and immediately publish a release with the same version

At first glance, this smells like an antipattern to me. Perhaps these things should live in a monorepo? That said, I'm sure we can figure something out here.

In principle, I kind of agree. That's how cubing.js became the monorepo that it is. However, I think it's likely we're always going to have some interactions like this between projects in different repos unless we put all our JS packages into the same repo. I don't mind that in principle, but JS monorepos still come with some very unfortunate tradeoff decisions right now.

(In particular, I would still like to split "Twizzle the branded app that is designed be a few parts of cubing.js together in a snazzy trenchcoat" out from "cubing.js the foundational ecosystem project" at some point.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants