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

Monorepo support #469

Open
josemarluedke opened this issue Mar 31, 2020 · 16 comments
Open

Monorepo support #469

josemarluedke opened this issue Mar 31, 2020 · 16 comments

Comments

@josemarluedke
Copy link

First, thank you for this project. I really like it and I have been using it in every project that I work on.

This is a feature request that probably is a bit controversial, but I wanted to submit anyway.

When working in projects that are monorepo, the changelog usually makes sense to mention what packages the changes have affected. This is very common in JavaScript projects for example.

There is lerna-changelog that has support for this, for reference.

It would be awesome if we could have something like this with release-drafter. I understand that this project is not specific to a language and that's why I think it is a bit controversial. However, many other languages have the same concept of packages and monorepos.

Thank you.

@gavinlove
Copy link
Contributor

You can use actions/labeler to automatically add a label with the correct package then add those labels to the categories list in the release drafter config.

@RehanSaeed
Copy link

I use release-drafter in a few projects now with great effect.

In one of my projects I have multiple packages that are released automatically based on the tag name e.g. Foo.1.2.3 releases the Foo package with version 1.2.3 and Bar.4.5.6 releases the Bar package with version 4.5.6.

Is it possible to use release-drafter with this kind of setup?

@mxj4
Copy link

mxj4 commented Dec 22, 2021

monorepo almost works if I run this action multiple times, each time with a different configuration, the only issue is when detecting last release: the last release from a different package is also included in search. If we can have a git tag prefix option in the configuration, then we can do better filtering when detecting the last release and exclude other packages.

Created a draft PR for this idea: #997

@Blacksmoke16
Copy link

A kinda related question is how to handle the case where you use a monorepo, but then sync the changes to read-only mirrors of each package. E.g. https://github.com/crystal-manyrepos/root when then on merge syncs to https://github.com/crystal-manyrepos/one if the change affected that repo.

I'm struggling a bit trying to think about how to handle this, or even if its possible. Ideally I was thinking I could enable release drafter on each child repo and have it update a draft release of only things merged into that component, but it doesn't seem to pickup on the changes. I suppose this makes sense as its a totally different repo than the PR that was merged.

My second thought was to try and use labels to group changes per component, but I'm thinking the problem there would be for changes that affect multiple components would only show up once.

I'll keep thinking about this, but in the meantime, anyone have any ideas/workarounds for this context?

@jetersen
Copy link
Member

I believe @blast-hardcheese managed to get it working pretty well.

https://github.com/guardrail-dev/guardrail/blob/master/.github/workflows/release-drafter.yml it ant pretty but it works 👍

@blast-hardcheese
Copy link
Contributor

That reminds me, I still need to apply your advice for config merging, instead of generating via bash script, it would be a better example for those trying to do this

@Blacksmoke16
Copy link

@jetersen Thanks for that link! I played around a bit with that approach, but not sure it'll fit my use case unfortunately.

In my case I don't have an actual monorepo so I think there would be issues with the drafts including every PR all the time given there would be no release to filter by. Unless you can filter by commit hash? But even then would be kinda a meh flow needing to update that whenever a version is released in a child repo.

After thinking about it for a bit, I think the crux of my issue is wanting to create the release in a different repo than which the PR is merged while still filtering to specific paths for each child repo. I.e. this way the child repo's latest version/releases list is used and is only updated with PRs that affected it.

Totally understandable if this isn't something that is going to be supported. Just going through and trying to figure out my options to make it so I don't need to keep track of all this manually anymore 😅.

@blast-hardcheese
Copy link
Contributor

@Blacksmoke16 Possibly not the flow you currently use, but if you use the release-drafter with monorepo style, when you sync out to the individual read-only replicas, the tags and release metadata could be copied as well.

If they're truly read-only, that seems sensible, and may already be supported by the tool you're using to extract specific module paths

@Blacksmoke16
Copy link

@blast-hardcheese Challenge there is the git commit hashes aren't the same when they're synced over, so that would probably break the tags :/.

I think the normal monorepo workflow would work good enough for me, if there was a good way to filter what gets added (without creating an actual tag/release). E.g. when releasing a child repo, go and update the sha hash to use as the base commit so it doesn't add anything before that. Maybe this is already possible with filter-by-commitish and commitsh?

@blast-hardcheese
Copy link
Contributor

@Blacksmoke16 it's tricky to estimate what could work here without knowing the feature set of the software that's doing the mirroring. Is that tool internal, or something that could be examined?

I agree about the commit hashes, though I was thinking more along the line of just making one tag manually synced between the two, then when syncing just do "from this tag to the next", which gets you parity. Using this approach, if you filter tags by some release prefix, you don't have to worry about if a tag refers to something that doesn't exist in the smaller repo, since by the nature of the release having been done, there's at least one commit.

@Blacksmoke16
Copy link

Blacksmoke16 commented May 11, 2022

or something that could be examined

It's all just git subtree stuff. An example of it can be found here.

Oh, so like create a manual release/tag for a specific component in the monorepo when a new release is created in the child. Then when another release happens update the commit that tag represents. This way it filters correctly? That might work, I'll have to play around with that.

@blast-hardcheese
Copy link
Contributor

Updating the tag could work too, I was thinking of just applying the commits since the last tag to the HEAD, then once the commits are over just drop a new version tag. That way version tags are present in both repos, which seems like a nice to have.

@blast-hardcheese
Copy link
Contributor

@Blacksmoke16 Would you mind renaming this issue to something more fitting, or closing it if you found an acceptable workaround?

I think we've established here that release-drafter's monorepo support is sufficient (and getting better all the time!) for single-repo monorepos, but this issue's name gives a false impression that it's still in flux or not implemented at all.

(I'm still happy to collaborate or help come up with a workable solution for your particular issue, btw!)

@blast-hardcheese
Copy link
Contributor

Oops, mistargeted -- @josemarluedke, the above comment was intended for you

@ksolie
Copy link

ksolie commented Apr 18, 2023

@blast-hardcheese , It looks like in your repo you were able to not create a release if there isn't a change:

Run blast-hardcheese/release-drafter@v5.16.42
  with:
    config-name: release-drafter-java-support.yml
  env:
    GITHUB_TOKEN: ***
guardrail-dev/guardrail: Found [2](https://github.com/guardrail-dev/guardrail/actions/runs/4239242321/jobs/7367101171#step:2:2)41 releases
{ name: 'event', id: '42[3](https://github.com/guardrail-dev/guardrail/actions/runs/4239242321/jobs/7367101171#step:2:3)92[4](https://github.com/guardrail-dev/guardrail/actions/runs/4239242321/jobs/7367101171#step:2:4)2321' }
guardrail-dev/guardrail: No draft release found
{ name: 'event', id: '4239242321' }
guardrail-dev/guardrail: Last release: java-support-v0.[7](https://github.com/guardrail-dev/guardrail/actions/runs/4239242321/jobs/7367101171#step:2:8)3.1
{ name: 'event', id: '423[9](https://github.com/guardrail-dev/guardrail/actions/runs/4239242321/jobs/7367101171#step:2:10)242321' }

How were you able to achieve this? Every time I try to mimic what you did, it creates a release for every file

@blast-hardcheese
Copy link
Contributor

@ksolie do you have a link?

I just have different path prefixes for the different modules that get picked up in the different release-drafter configurations

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

8 participants