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

Multiple drafts created due to GH workflow concurency #1146

Open
dduportal opened this issue May 17, 2022 · 13 comments · May be fixed by #1204
Open

Multiple drafts created due to GH workflow concurency #1146

dduportal opened this issue May 17, 2022 · 13 comments · May be fixed by #1204

Comments

@dduportal
Copy link

On the Jenkins infrastructure project, we've hit a reproductible case where we have multiple times the same draft created by release-drafter, while we have fixed the tag and release name to the static value next.

There are multiple causes that make it an "edge" case:

  • we define a static name for the "draft next release" so we expect only 1 at a given time
  • Jenkins is publishing the draft release to a given tag version, which is a parallel process to the Github workflow builds
  • we have the release: trigger event for release-drafter's workflow (we have a new "next release draft" published right after Jenkins publishing a given release)

In our case, since we "patch" the release, there are 3 events triggering 3 concurent builds of the GH workflow: it results in 3 different "next release draft":

Capture d’écran 2022-05-17 à 11 21 50

Capture d’écran 2022-05-17 à 11 21 56

We are thinking, in the short term, to enable the "concurency" feature of GH action (https://docs.github.com/en/actions/using-jobs/using-concurrency) so only 1 release-drafter job would be executed at once, streamlining the executions. The 2nd and 3rd builds in our case should pick the previous next release because executed AFTER.

Our use case is edgy, however you can reproduce it with any release-drafter process executed both manually (workflow_dispatch: event) and automatically: WDYT if we send a PR to the documentation suggesting to use the concurency keyword as a sane default?

@jetersen
Copy link
Member

jetersen commented Jun 15, 2022

@dduportal I am not following your explanation or pictures. Would be nice with link to workflow makes everything a lot easier.

Why do you need 3 actions to trigger when you could use parallel jobs and have release drafter as a job run before all of these 3 jobs?

cc @lemeurherve

@dduportal
Copy link
Author

Hello @jetersen ! No problem, please find some materials below:

  • One of our faulty "release-drafter" GHA workflows: https://github.com/jenkins-infra/docker-openvpn/blob/main/.github/workflows/release-drafter.yaml
  • The release of the artefact of this repository, a Docker image, is done through Jenkins with a pipeline that uses the following library: https://github.com/jenkins-infra/pipeline-library/blob/master/vars/buildDockerAndPublishImage.groovy
  • The idea is to provide an "automatic release": we do not want a human having to manually publish the release-drafter "next version" draft. This automation means that we hit cases where the actual "next" version is published, and the immediate next release fails because no new "release-drafter" workflow run happened in GHA (not enough time elapsed to trigger one).
  • Given this behavior ("quite often, no next release draft ready when deploying a release"), we added more events that could trigger a new draft:
    • push, as usual, to generate a new release draft on each commit (could be resrticted to principal branch, but we do not use any other branch so not an issue)
    • release to make sure that a new draft is generated immediatly after publishing a release, to ensure there is always one.
    • workflow_dispatch to allow us regenerate the release note of the draft, when we failed to correctly label a PR for instance. We can change the labels and regenerate.
  • Which drives us to the case where multiple runs of release-drafter ran at the same time, leading to creation of multiples "next".

=> You can reproduce this behavior with a simple case: enable "release-drafter" on a repo, only on the main branch + workflow dispatch.While the release drafter run is executed, trigger 1 or 2 others manually: you'll have multiple drafts (wether they are named or no not).

@jetersen
Copy link
Member

Hmm, hopefully once #1173 lands it should solve your issue.
Since you could use it on the Jenkins CI side via the CLI?

I have work locally, I will push tonight which mostly finishes the module and typescript transition.
Than it is a matter of finishing the three runtime CLI, Probot and GitHub Action.

@jetersen
Copy link
Member

@dduportal I am getting closer with v6 to actually write the action and cli implementation.

Would you be interested in testing out the release-drafter cli in your Jenkins infra once I have something that should function similar to running it as a GitHub action?

@dduportal
Copy link
Author

@dduportal I am getting closer with v6 to actually write the action and cli implementation.

Would you be interested in testing out the release-drafter cli in your Jenkins infra once I have something that should function similar to running it as a GitHub action?

Absolutely! Many thanks

@jetersen
Copy link
Member

jetersen commented Aug 10, 2022

I am thinking of four modes draft CLI part of it.

Mode one:
release-drafter draft
That detects locally whether it is running in a repository via current directory by finding the .github/release-drafter.yml file (override with -c --config)
Note: might need to check the .github repo potentially it will fallback and just use the GitHub API if it able to detect Repository.

Simply provide --config path/to/config to merge it with remote repo.
--no-fetch-config will not fetch the repository config

Than tries to find the github remote, it may need to actually understand Jenkins environment variables or other CI/CD environment variables.
As a fallback lookup remote in .git but could be faulty due to multiple remotes.
To detect repo.

No simply use --repository

Mode two:
release-drafter draft --repo jenkinsci/jenkins uses github api to find the config and draft a release based on releases.

Kiss this is the same as mode one just use --repository

Mode three: - not yet implemented
which would be for redrafting old releases.

release-drafter draft --repo jenkinsci/jenkins --update-tag tag --previous-tag oldtag
release-drafter --repository jenkinsci/jenkins --update-tag tag --previous-tag oldtag
By providing previous you can control release drafter so it does not try to guess the last tag.

Mode four:
Than you can also do
release-drafter publish same parameters but it publishes.
release-drafter --publish instead

We could potentially allow for the increment types that semver supports 'major' | 'premajor' | 'minor' | 'preminor' | 'patch' | 'prepatch' | 'prerelease'
Potentially we can use release-drafter --publish --semver prerelease --previous-tag 10.11.0-beta1 should generate 10.11.0-beta2

All of it can have dry-run so you can see the modifications it might do.

@dduportal
Copy link
Author

@jetersen impressive. It looks like that it would solve most of our issues (but we'll only be sure once we'll try to use it of course).

@jetersen jetersen linked a pull request Aug 20, 2022 that will close this issue
22 tasks
@jetersen
Copy link
Member

jetersen commented Aug 22, 2022

Thinking about mode one for local, I may want to detect repo. Attempt to download config and .github config and than merge with local config.

To provide the best experience.

Of course you could disable the repo lookup via CLI flag I think that would be valuable but disabling the repo lookup means you have to duplicate the entire config locally but I guess it depends on use cases.

Thinking about mode one for ci.

I looked at npmjs to see if anybody had done ci detection but it seems they have only done the detection not detecting the actual repository. Which is usually present in most CIs.

So I may have to write my own module, that fits my needs.

The module should detect CI, detect the ref and detect repository.

If none of this is possible complain and ask for git checkout or --repo myorg/myrepo --ref main

@jetersen
Copy link
Member

jetersen commented Aug 22, 2022

Okay most CI are crap at giving ref and repository via envs.

Maybe the best way forward is asking the user to provide via CLI flags. They can of course you environment variables if the CI provides it!

@jetersen
Copy link
Member

https://www.npmjs.com/package/commander Seems like a good fit for CLI it relatively small with zero dependencies, I don't need something fancy like chalk.js (coloring cli output) imho.

@jetersen
Copy link
Member

Managed to create an initial CLI that function similar to GitHub Action.

I simply need to package up the CLI and publish to @release-drafter/cli@next so you potentially could do npx --yes @release-drafter/cli@next --repository jenkinsci/jenkins and than have an GITHUB_TOKEN environment variable.

@jetersen
Copy link
Member

Decided against trying to being fancy 😅

@jetersen
Copy link
Member

jetersen commented Aug 27, 2022

@dduportal I have published a beta version

Available here: https://www.npmjs.com/package/@release-drafter/cli

You can run it like this npx -y @release-drafter/cli@next --repository org/repo and than have an GITHUB_TOKEN environment variable.
It does not allow passing of token via cli parameters.

npx -y @release-drafter/cli@next --help does work

--reference will default to --default-branch and --default-branch if not supplied will be looked up via rest API.

So if you release from default branch it will continue to work as always.

We allow to override commitish but it will also default to reference.

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