DioxusLabs / dioxus

Fullstack GUI library for web, desktop, mobile, and more.
https://dioxuslabs.com
Apache License 2.0
18.69k stars 712 forks source link

Configure automated release versioning and publishing #1539

Open esimkowitz opened 7 months ago

esimkowitz commented 7 months ago

Specific Demand

As Dioxus grows in size and scope, it's time for the project to evolve its release management process. Ideally, a GitHub workflow can be configured to remove the complex manual steps required to tag, version, and publish new releases. This can also help with security as fewer Crates.io tokens need to be floating around between maintainers. Instead, a single copy can be uploaded to the organization and used by the pipeline for automated publishing.

Implement Suggestion

There are many tools available for automating versioning and publishing, the following seem the most promising. I'm still investigating this and will update this list with benefits and tradeoffs as I learn more.

release-plz

This is a rust-specific CI tool that automates the creation of release-PRs, which manage versioning and changelog generation for all changes between the last successful release and the current one. It is capable of automating versioning using either conventional commits schema or cargo-semver-checks, making it flexible to projects that don't have a well-established PR hygiene.

release-please

This is a Google-maintained project that was the original inspiration for release-plz, though it is compatible with many languages (Rust among them). This project enforces stronger PR hygiene by requiring all PRs to use the conventional commits schema. This project also seems to support additional workspace-specific tooling, though I am still looking into this.

cargo-workspaces

This is a workspaces-optimized CLI for managing crate versioning and publishing. It doesn't appear to have the best support for CI automation, though I'm still looking into this.

cargo-smart-release

This is a very opinionated toolset for managing and publishing releases, though the opinions appear to be pretty well-aligned to the current Dioxus workflow. Still looking into this and how it can be CI-automated.

esimkowitz commented 7 months ago

Another thing that could be useful, though is more of a procedural improvement, is to establish milestone integration branches. We can build automation around git-semver-checks to confirm that there are no breaking changes in a new PR against master. This should allow bug fixes, security patches, and dependabot updates to still be developed against and directly committed to master. The automation would reject any breaking changes, requiring a maintainer to override the check if there's an issue that can only be addressed through a breaking change but doesn't qualify for a new minor bump. Otherwise, any breaking changes that require a minor version bump (0.1.5 -> 0.2.0) would need to be committed first to a milestone branch (e.g. milestone-0.5).

These milestone branches can be automatically created after each minor release (i.e. if 0.4.0 tag gets created by the release pipeline, a milestone-0.5 branch would be automatically created). These branches would be subject to the same validation checks and protection policies as master, ensuring they are kept in a stable state. When the maintainers are ready to release the next milestone, they can create a new PR to merge it into master. This will automatically bump the minor version according to the policy of whichever release automation tool we choose and then the cycle will start over, with the next milestone branch created.

As a bonus, if we choose to exempt milestone branches from automatic deletion, we could retroactively patch and release older milestones if serious security fixes need to be applied. We don't currently have a long-term-support plan, but this could set us up for one in the future.

ealmloff commented 7 months ago

An automated tool for tracking breaking changes would be great!

Another thing that could be useful, though is more of a procedural improvement, is to establish milestone integration branches. We can build automation around git-semver-checks to confirm that there are no breaking changes in a new PR against master. This should allow bug fixes, security patches, and dependabot updates to still be developed against and directly committed to master. The automation would reject any breaking changes, requiring a maintainer to override the check if there's an issue that can only be addressed through a breaking change but doesn't qualify for a new minor bump. Otherwise, any breaking changes that require a minor version bump (0.1.5 -> 0.2.0) would need to be committed first to a milestone branch (e.g. milestone-0.5).

These milestone branches can be automatically created after each minor release (i.e. if 0.4.0 tag gets created by the release pipeline, a milestone-0.5 branch would be automatically created). These branches would be subject to the same validation checks and protection policies as master, ensuring they are kept in a stable state. When the maintainers are ready to release the next milestone, they can create a new PR to merge it into master. This will automatically bump the minor version according to the policy of whichever release automation tool we choose and then the cycle will start over, with the next milestone branch created.

For comparison the process we are following for this release is:

Both of these process require additional work merging changes. With the new approach you proposed every time a bug fix is added it needs to be merged into the main branch and then the conflicts with the release branch need to be fixed. With the current approach all of the accumulated fixes must be merged into each breaking branch before the breaking branch is merged.

Switching feature development to a new branch could make releasing easier but it does raise some additional conserns:

As a bonus, if we choose to exempt milestone branches from automatic deletion, we could retroactively patch and release older milestones if serious security fixes need to be applied. We don't currently have a long-term-support plan, but this could set us up for one in the future.

Right now I don't think a long term support plan makes sense for Dioxus. It would slow down development significantly because we need to fix merge conflicts several times for each release. It makes sense for some projects that are more stable but I don't think Dioxus is there yet. Most of the core API of Dioxus is stable externally which should make upgrading easy but the internals are changing more often

esimkowitz commented 7 months ago

Who handles fixing conflicts in bug PRs: the person who filed the PR or the maintainers?

Do you mean conflicts that bug PRs introduce into new milestone branches? I was envisioning that we would set up an automation that would automatically open a chore PR to the milestone branch for every bug PR. I think at the least a maintainer would have to approve the PR, not sure about who would be responsible for resolving the conflicts. It's hard to enforce those things. One option would be to create issues for each of them and tag them as good first contributions in some project table.

It could make contributing to Dioxus more confusing

This is certainly a trade-off. I think we could make this a little easier by setting up a Contributing guide and PR templates. We can also set up an automation that runs on PR creation to triage breaking changes and automatically change the PR target branch to the latest milestone if it is breaking and doesn't contain a category of bug. As projects grow in size, balancing ease of contribution against organization is a constant challenge ๐Ÿ˜•.

It makes it more difficult to test the new (non-breaking) features in the git version of Dioxus (you need to find a specific branch instead of just relying on the git version)

True, but it's not that smooth right now. Main is not stable so I've found I usually need to try a few different revs to find one that has the change I want but isn't broken. I suppose that could be classified as testing gaps, but I think it's also a case for just releasing patch versions more frequently.

Right now I don't think a long term support plan makes sense for Dioxus. It would slow down development significantly because we need to fix merge conflicts several times for each release. It makes sense for some projects that are more stable but I don't think Dioxus is there yet. Most of the core API of Dioxus is stable externally which should make upgrading easy but the internals are changing more often

Yeah I figured, just trying to say that this sets us up for a more mature support story in the future, not that we explicitly need to design for it yet.

ealmloff commented 7 months ago

Who handles fixing conflicts in bug PRs: the person who filed the PR or the maintainers?

Do you mean conflicts that bug PRs introduce into new milestone branches? I was envisioning that we would set up an automation that would automatically open a chore PR to the milestone branch for every bug PR. I think at the least a maintainer would have to approve the PR, not sure about who would be responsible for resolving the conflicts. It's hard to enforce those things. One option would be to create issues for each of them and tag them as good first contributions in some project table.

Yes, both approaches have this issue. It just makes it more difficult compared to merging breaking changes into main. I think it is worth it overall, but it will add more maintenance work. I agree there isn't a good way to enforce the author of the PR fixing the merge conflicts. (and I'm not sure that is something we would want to do)

It could make contributing to Dioxus more confusing

This is certainly a trade-off. I think we could make this a little easier by setting up a Contributing guide and PR templates. We can also set up an automation that runs on PR creation to triage breaking changes and automatically change the PR target branch to the latest milestone if it is breaking and doesn't contain a category of bug. As projects grow in size, balancing ease of contribution against organization is a constant challenge ๐Ÿ˜•.

We could definitely add something to the contributing guide. If we do get a but running that handles changing the target branch I think this would be much less of an issue

It makes it more difficult to test the new (non-breaking) features in the git version of Dioxus (you need to find a specific branch instead of just relying on the git version)

True, but it's not that smooth right now. Main is not stable so I've found I usually need to try a few different revs to find one that has the change I want but isn't broken. I suppose that could be classified as testing gaps, but I think it's also a case for just releasing patch versions more frequently.

It should be stable since the 0.4 release, a CI to check for that would definitely help make sure nothing gets through

ealmloff commented 7 months ago

Overall I think if the automation is good enough, the release branch approach is worth trying.

@jkelleyrtp I know you have looked into automatically tracking breaking changes before a release. What are your thoughts here?

esimkowitz commented 7 months ago

We could incubate it in the dioxus-std repo to minimize impact to the primary project

ealmloff commented 7 months ago

We can try this on the main repo. A major flaw with not merging everything until before a release is there are a lot less people testing the new features.

We can use https://github.com/DioxusLabs/dioxus/tree/0.5 as our feature branch for the next release

alexanderjophus commented 6 months ago

Reviving this/adding my own 2ยข.

I used cargo-workspaces for a the solution on dioxus-slides. Find the gha

The highights include;

Things to note;

Should also add, I'm happy to make a PR if that's the route you want to go.

ealmloff commented 6 months ago

That could be part of the solution. The other half of the solution would be automatically detecting PRs that will require a major version bump. We also release a lot of packages with the same version at once, so something like that workflow would definitely be helpful

esimkowitz commented 6 months ago

Yeah this sounds ideal, I am happy to hand this off, my life has been a bit too busy recently to do this issue justice. I'd been looking at cargo-semver-checks for detecting major version bumps, @alexanderjophus have you used this before?

alexanderjophus commented 6 months ago

@esimkowitz I haven't looked at it yet. Personally I'm not a huge fan of automating semver changes. Highlighting the differences so a maintainer can quickly parse "oh this needs to be a major/minor/patch release", sure. I'll check out cargo-semver-checks now :)

obi1kenobi commented 3 months ago

Personally I'm not a huge fan of automating semver changes. Highlighting the differences so a maintainer can quickly parse "oh this needs to be a major/minor/patch release", sure.

๐Ÿ‘‹ cargo-semver-checks maintainer here, just stumbled across this issue. cargo-semver-checks doesn't automate semver changes, but instead scans for breaking changes that would require a major version bump. So it's closer to what you described you wanted, than what you said you weren't a fan of โ€” I'm not generally a fan of it either ๐Ÿ˜„