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

Branch specific configuration? #656

Closed
joakime opened this issue Sep 30, 2020 · 5 comments
Closed

Branch specific configuration? #656

joakime opened this issue Sep 30, 2020 · 5 comments

Comments

@joakime
Copy link

joakime commented Sep 30, 2020

It would be nice if release-drafter has the ability to specify multiple configurations with different target-branch to manage multiple branches in parallel.

This is a concept seen on other actions, like dependabot.

An example of this for dependabot is can be seen at https://github.com/eclipse/jetty.project/blob/jetty-10.0.x/.github/dependabot.yml

Looks like ...

version: 2
updates:
  - package-ecosystem: "maven"
    directory: "/"
    schedule:
      interval: "weekly"
    target-branch: "jetty-9.4.x"

  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "weekly"
    target-branch: "jetty-9.4.x"

  - package-ecosystem: "maven"
    directory: "/"
    schedule:
      interval: "weekly"
    target-branch: "jetty-10.0.x"

  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "weekly"
    target-branch: "jetty-10.0.x"

  - package-ecosystem: "maven"
    directory: "/"
    schedule:
      interval: "weekly"
    target-branch: "jetty-11.0.x"

  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "weekly"
    target-branch: "jetty-11.0.x"

If release-drafter supported this target-branch concept, then it could be configured to manage multiple active releases in larger projects that have multiple active branches all with interleaved releases.

@mkurz
Copy link
Contributor

mkurz commented Mar 24, 2021

This is possible thanks to the filter-by-commitish config introduced in #657 / #683.

It took me a while to figure out how things work, that's why I am going to share my learnings. Actually, I set up an example repo which I used as a playground to get things working: https://github.com/mkurz/release-drafter-test/ You can fork that repo and just try yourself.

So let's assume you currently have two branches: a master branch (which is your GitHub default branch) and a 2.8.x branch.
The master branch is your dirty development branch in which you work towards a 2.9.0 release - so later you will create a 2.9.x branch off it, like you did with the 2.8.x branch long time ago. From the 2.8.x branch you released versions 2.8.1, 2.8.2,... Actually 2.8.0 was tagged on the master branch back then, and only afterwards the 2.8.x branch was created, like you would tag the 2.9.0 release from the master branch and afterwards create the 2.9.x branch from it.

So now let's configure the release drafter:
In your GitHub default branch (which is the master branch in the above example) you need to create two separate release drafter configs, one for each branch:

We did setup the release-drafter configs, now we need to configure the GitHub workflows to run release drafter on the right branches with the right configs. In both your branches you need to create a .github/workflows/release-drafter.yml config:

As you can see the config-name config within this file refers to the release drafter configs that are both located in the default (=master) branch. Also the workflow is setup to run on push events for the branch the file is located in (line 7).

So that is basically it, the workflows run and draft releases get created...
But wait...
You configured everything correctly but the drafted releases are incorrect? That's probably because the GitHub releases have the wrong target_commitish set. What do I mean? First of all: I am talking about the releases you can see in a GitHub repo, like e.g. https://github.com/mkurz/release-drafter-test/releases - but don't confuse such releases with tags (https://github.com/mkurz/release-drafter-test/tags)! Not every tag is (or has to be) a GitHub release!
So what is the target_commitish? Usually when you create a release with the GitHub UI (by visiting https://github.com/.../releases/new of your repo) you have two choices.

  • (Choice ONE) Either you enter an existing tag:
    image
  • (Choice TWO) or you create a new tag off an branch:
    image

So, here you can see the "target" branch... That is exactly what the target_commitish is. So if you choose master here, the target_commitish for that 2.8.99 release would be master, if you choose the 2.8.x branch the target_commitish for that 2.8.99 release would be 2.8.x.
Alright, that means as long as you did and do cut your releases from the GitHub UI by choosing the target branch, the target_commitish would always be correct. However usually that is not the case, usually people create tags on the command line or have some kind of release/publishing/whatever pipeline setup in their (CI/CD or whatever) environment. That means usually you already have existing tags (which later can and often will be mapped to a GitHub release, see "Choice ONE" above).
So how can you actually see the target_commitish of an existing release or even change it?
You can get details about all your releases (again I am talking about GitHub releases not about tags) via the GitHub API:

curl https://api.github.com/repos/mkurz/release-drafter-test/releases

This gives you some nice JSON which should containt a line like

"target_commitish": "master",

for every release.
Now, if a config contains the lines

filter-by-commitish: true
commitish: 2.8.x

the release drafter will fetch all the releases, filter only the ones with target_commitish set to 2.8.x and get the last release of this filtered releases.
In my case I had a repo where all releases (2.0.0 - 2.8.7) had the target_commitish set to master. That was a problem, because filtering by commitish 2.8.x would not work as there does no commitish 2.8.x exist for a release...
To change a target_commitish for an existing release you can

  • either use the GitHub API again: https://docs.github.com/en/rest/reference/releases#update-a-release

    target_commitish ... Specifies the commitish value that determines where the Git tag is created from. Can be any branch or commit SHA. Unused if the Git tag already exists. Default: the repository's default branch (usually master).

  • or use the GitHub UI again: Go to the page where you can edit a release (like https://github.com/.../releases/edit/2.8.7). You will see that the tag (of course) already exists:
    image
    Now clear that textbox, instead write something random like "abc" and, with the cursor, leave the textbox (focus out). The target branch dropdown will now appear:
    image
    Now choose the wished target branch (=target_commitish), and then again enter the original tag, so you can see "Existing tag" again and the dropdown disappears, so actually the screen it looks like before. Now you changed the target_commitish and you can save the release ("Update release" button).
    You should do that for all 2.8.1, 2.8.2 releases: Set them the target_commitish to 2.8.x. Now the release that gets draft for the 2.8.x branch will use 2.8.2 as the latest release.
    For major releases like 2.8.0 you should set (or keep) the target_commitish to master. This way the release that gets drafted for the master branch will use the 2.8.0 release as the latest release.

That's it, I hope I can help other people with this howto.

@shreyanshp
Copy link

@mkurz Amazing explanation buddy!

However I am facing a small problem, when I set the commitish branch from input of action and not template, for some reason it is not reflected on release

Workflow for patch - https://github.com/shreyanshp/gitops/blob/trunk/.github/workflows/cherry_pick_prs.yml#L50
Template for patch -

action run - https://github.com/shreyanshp/gitops/runs/3346241319?check_suite_focus=true (you can see it picked up trunk and not Release/7.7.1

https://github.com/shreyanshp/gitops/blob/trunk/.github/release-drafter-patch.yml

(cc @jetersen )

@jetersen
Copy link
Member

Should be possible to craft an action with filter-by-commitish and version input based on output from another action. Potentially you want to have multiple config files as well.

Though I would suggest git flow is not the best approach to releases and CI/CD:

Gitflow is a legacy Git workflow that was originally a disruptive and novel strategy for managing Git branches.
Gitflow has fallen in popularity in favor of trunk-based workflows, which are now considered best practices for modern continuous software development and DevOps practices.
Gitflow also can be challenging to use with CI/CD. This post details Gitflow for historical purposes.
https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow

@robbinjanssen
Copy link
Contributor

robbinjanssen commented Jan 31, 2022

@mkurz great explanation, thanks!

I have a followup question:

After a bunch of hotfixes to the v21.3.x branch, we always merge those hotfixes into the master branch. This currently results into duplicate release notes for the master branch (all hotfix notes are also in the master draft)

Is there anything we can do to skip notes already released in the v21.3.x branch?


Solution below, thanks @mkurz!

@mkurz
Copy link
Contributor

mkurz commented Jan 31, 2022

@robbinjanssen I am not an expert, but maybe the exclude-labels config helps? See https://github.com/release-drafter/release-drafter#exclude-pull-requests
You could label all pull requests that get merged into v21.3.x with a special label like hotfix and for the release workflow for the master branch only you can set the exclude-labels config to exclude those hotfix pull requests from the changelog.
(If you generate release notes for the 21.x branch you will have a different workflow config were you just don't add the exclude-labels config, so nothing changes for it and it will still correctly generate the release notes for that branch)

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

5 participants