mirror of
https://github.com/apricote/releaser-pleaser.git
synced 2026-02-10 03:37:03 +00:00
Compare commits
7 commits
50b2762dca
...
fc1ee70c28
| Author | SHA1 | Date | |
|---|---|---|---|
| fc1ee70c28 | |||
| 0de242a4e6 | |||
| d540e2221d | |||
| 2d3a960939 | |||
| d24ae7de98 | |||
| 08d35f2f57 | |||
| eae0045359 |
11 changed files with 233 additions and 12 deletions
9
.github/workflows/releaser-pleaser.yaml
vendored
9
.github/workflows/releaser-pleaser.yaml
vendored
|
|
@ -10,6 +10,13 @@ on:
|
||||||
- labeled
|
- labeled
|
||||||
- unlabeled
|
- unlabeled
|
||||||
|
|
||||||
|
# Only one job needs to run at a time, if a new job is started there is probably new data to include in the response, so
|
||||||
|
# it does not make sense to finish the previous job. This also helps with "data-race conflicts", where a human changes
|
||||||
|
# the PR description but releaser-pleaser was already running and overwrites the humans changes.
|
||||||
|
concurrency:
|
||||||
|
group: releaser-pleaser
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
permissions: {}
|
permissions: {}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
@ -31,7 +38,7 @@ jobs:
|
||||||
# Without this, any new flags in `action.yml` would break the job in this repository until the new
|
# Without this, any new flags in `action.yml` would break the job in this repository until the new
|
||||||
# version is released. But a new version can only be released if this job works.
|
# version is released. But a new version can only be released if this job works.
|
||||||
- uses: ko-build/setup-ko@d006021bd0c28d1ce33a07e7943d48b079944c8d # v0.9
|
- uses: ko-build/setup-ko@d006021bd0c28d1ce33a07e7943d48b079944c8d # v0.9
|
||||||
- run: ko build --bare --local --tags ci github.com/apricote/releaser-pleaser/cmd/rp
|
- run: ko build --bare --local --platform linux/amd64 --tags ci github.com/apricote/releaser-pleaser/cmd/rp
|
||||||
|
|
||||||
- run: mkdir -p .github/actions/releaser-pleaser
|
- run: mkdir -p .github/actions/releaser-pleaser
|
||||||
- run: "sed -i 's|image: .*$|image: docker://ghcr.io/apricote/releaser-pleaser:ci|g' action.yml"
|
- run: "sed -i 's|image: .*$|image: docker://ghcr.io/apricote/releaser-pleaser:ci|g' action.yml"
|
||||||
|
|
|
||||||
39
CHANGELOG.md
39
CHANGELOG.md
|
|
@ -1,5 +1,44 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## [v0.6.0](https://github.com/apricote/releaser-pleaser/releases/tag/v0.6.0)
|
||||||
|
|
||||||
|
### ✨ Highlights
|
||||||
|
|
||||||
|
#### Reduced resource usage
|
||||||
|
|
||||||
|
`releaser-pleaser` now uses less resources:
|
||||||
|
|
||||||
|
- It now skips pushing changes to the release pull request if they are only a rebase.
|
||||||
|
- The configurations for GitHub Actions and GitLab CI/CD now makes sure that only a single job is running at the same time. On GitHub unnecessary/duplicate jobs are also automatically aborted.
|
||||||
|
- It handles the stop signals from the CI environment and tries to exit quickly.
|
||||||
|
|
||||||
|
\```yaml
|
||||||
|
concurrency:
|
||||||
|
group: releaser-pleaser
|
||||||
|
cancel-in-progress: true
|
||||||
|
\```
|
||||||
|
|
||||||
|
#### Avoid losing manual edits to release pull request
|
||||||
|
|
||||||
|
Before, releaser-pleaser was prone to overwriting user changes to the release pull request if they were made after releaser-pleaser already started running. There is now an additional check right before submitting the changes to see if the description changed, and retry if it did.
|
||||||
|
|
||||||
|
#### Proper commit authorship
|
||||||
|
|
||||||
|
Before, the release commits were created by `releaser-pleaser <>`. This was ugly to look at. We now check for details on the API user used to talk to the forge, and use that users details instead as the commit author. The committer is still `releaser-pleaser`.
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
- real user as commit author (#187)
|
||||||
|
- avoid pushing release branch only for rebasing (#114)
|
||||||
|
- colorize log output (#195)
|
||||||
|
- graceful shutdown when CI job is cancelled (#196)
|
||||||
|
- detect changed pull request description and retry process (#197)
|
||||||
|
- run one job concurrently to reduce chance of conflicts (#198)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
- crash when running in repo without any tags (#190)
|
||||||
|
|
||||||
## [v0.5.1](https://github.com/apricote/releaser-pleaser/releases/tag/v0.5.1)
|
## [v0.5.1](https://github.com/apricote/releaser-pleaser/releases/tag/v0.5.1)
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ inputs:
|
||||||
outputs: {}
|
outputs: {}
|
||||||
runs:
|
runs:
|
||||||
using: 'docker'
|
using: 'docker'
|
||||||
image: docker://ghcr.io/apricote/releaser-pleaser:v0.5.1 # x-releaser-pleaser-version
|
image: docker://ghcr.io/apricote/releaser-pleaser:v0.6.0 # x-releaser-pleaser-version
|
||||||
args:
|
args:
|
||||||
- run
|
- run
|
||||||
- --forge=github
|
- --forge=github
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,27 @@
|
||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"os"
|
"os"
|
||||||
|
"os/signal"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
|
"syscall"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/lmittmann/tint"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
var logger *slog.Logger
|
var logger *slog.Logger
|
||||||
|
|
||||||
var rootCmd = &cobra.Command{
|
var rootCmd = &cobra.Command{
|
||||||
Use: "rp",
|
Use: "rp",
|
||||||
Short: "",
|
Short: "",
|
||||||
Long: ``,
|
Long: ``,
|
||||||
Version: version(),
|
Version: version(),
|
||||||
|
SilenceUsage: true, // Makes it harder to find the actual error
|
||||||
|
SilenceErrors: true, // We log manually with slog
|
||||||
}
|
}
|
||||||
|
|
||||||
func version() string {
|
func version() string {
|
||||||
|
|
@ -39,15 +46,44 @@ func version() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func Execute() {
|
func Execute() {
|
||||||
err := rootCmd.Execute()
|
// Behaviour when cancelling jobs:
|
||||||
|
//
|
||||||
|
// GitHub Actions: https://docs.github.com/en/actions/managing-workflow-runs-and-deployments/managing-workflow-runs/canceling-a-workflow#steps-github-takes-to-cancel-a-workflow-run
|
||||||
|
// 1. SIGINT
|
||||||
|
// 2. Wait 7500ms
|
||||||
|
// 3. SIGTERM
|
||||||
|
// 4. Wait 2500ms
|
||||||
|
// 5. SIGKILL
|
||||||
|
//
|
||||||
|
// GitLab CI/CD: https://gitlab.com/gitlab-org/gitlab-runner/-/merge_requests/4446
|
||||||
|
// 1. SIGTERM
|
||||||
|
// 2. Wait ???
|
||||||
|
// 3. SIGKILL
|
||||||
|
//
|
||||||
|
// We therefore need to listen on SIGINT and SIGTERM
|
||||||
|
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
|
||||||
|
go func() {
|
||||||
|
// Make sure to stop listening on signals after receiving the first signal to hand control of the signal back
|
||||||
|
// to the runtime. The Go runtime implements a "force shutdown" if the signal is received again.
|
||||||
|
<-ctx.Done()
|
||||||
|
logger.InfoContext(ctx, "Received shutdown signal, stopping...")
|
||||||
|
stop()
|
||||||
|
}()
|
||||||
|
|
||||||
|
err := rootCmd.ExecuteContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
logger.ErrorContext(ctx, err.Error())
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
logger = slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{
|
logger = slog.New(
|
||||||
Level: slog.LevelDebug,
|
tint.NewHandler(os.Stderr, &tint.Options{
|
||||||
}))
|
Level: slog.LevelDebug,
|
||||||
|
TimeFormat: time.RFC3339,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
slog.SetDefault(logger)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@
|
||||||
# Explanation
|
# Explanation
|
||||||
|
|
||||||
- [Release Pull Request](explanation/release-pr.md)
|
- [Release Pull Request](explanation/release-pr.md)
|
||||||
|
- [Concurrency and Conflicts](explanation/concurrency-conflicts.md)
|
||||||
|
|
||||||
# Guides
|
# Guides
|
||||||
|
|
||||||
|
|
|
||||||
65
docs/explanation/concurrency-conflicts.md
Normal file
65
docs/explanation/concurrency-conflicts.md
Normal file
|
|
@ -0,0 +1,65 @@
|
||||||
|
# Concurrency and Conflicts
|
||||||
|
|
||||||
|
## Why
|
||||||
|
|
||||||
|
`releaser-pleaser` works on the "shared global state" that is your project on GitHub/GitLab. Each execution reads from that state and makes changes to it. While `releaser-pleaser` is generally [idempotent](https://en.wikipedia.org/wiki/Idempotence), we still need to consider concurrent executions for two reasons: avoiding conflicts and saving resources.
|
||||||
|
|
||||||
|
### Avoiding conflicts
|
||||||
|
|
||||||
|
The [Release Pull Request](release-pr.md) is used by `releaser-pleaser` to show the current release. Users may update the PR description to add additional notes into the Changelog.
|
||||||
|
|
||||||
|
When `releaser-pleaser` is running while the user modifies the Release Pull Request description, `releaser-pleaser` may overwrite the description afterward based on its outdated local copy of the pull request.
|
||||||
|
|
||||||
|
### Saving resources
|
||||||
|
|
||||||
|
While `releaser-pleaser` is idempotent, there is no benefit to running it multiple times in parallel. In the best case, `releaser-pleaser` could be stopped as soon as a new "change" that is relevant to it comes in and restarts based on that new state.
|
||||||
|
|
||||||
|
## Measures taken
|
||||||
|
|
||||||
|
### Concurrency limits in CI environments
|
||||||
|
|
||||||
|
Our default configurations for [GitHub Actions](../tutorials/github.md) and [GitLab CI/CD](../tutorials/gitlab.md) try to limit concurrent `releaser-pleaser` jobs to a single one.
|
||||||
|
|
||||||
|
#### GitHub Actions
|
||||||
|
|
||||||
|
On GitHub Actions, we use a `concurrency.group` to restrict it to a single running job per repository.
|
||||||
|
|
||||||
|
GitHub cancels the currently running job and any other pending ones when a new one is started. This makes sure that `releaser-pleaser` always works with the latest state.
|
||||||
|
|
||||||
|
Users need to enable this in their workflow (included in our GitHub tutorial):
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
concurrency:
|
||||||
|
group: releaser-pleaser
|
||||||
|
cancel-in-progress: true
|
||||||
|
```
|
||||||
|
|
||||||
|
#### GitLab
|
||||||
|
|
||||||
|
On GitLab CI/CD, we use a `resource_group: releaser-pleaser` in our GitLab CI/CD component to restrict it to a single running job per repository. This is part of the component YAML, so users do not need to set this manually.
|
||||||
|
|
||||||
|
There is no easy way to cancel the running job, so we let it proceed and rely on the other measures to safely handle the data. Users can enable "auto-cancel redundant pipelines" if they want, but should consider the ramifications for the rest of their CI carefully before doing so.
|
||||||
|
|
||||||
|
### Graceful shutdown
|
||||||
|
|
||||||
|
When GitHub Actions and GitLab CI/CD cancel jobs, they first sent a signal to the running process (`SIGINT` on GitHub and `SIGTERM` on GitLab). We listen for these signals and initiate a shutdown of the process. This helps save resources by shutting down as fast as possible, but in a controlled manner.
|
||||||
|
|
||||||
|
### Re-checking PR description for conflict
|
||||||
|
|
||||||
|
When `releaser-pleaser` prepares the Release Pull Request, the first step is to check if there is an existing PR already opened. It then reads from this PR to learn if the user modified the release in some way ([Release Notes](../guides/release-notes.md#for-the-release), [Pre-releases](../guides/pre-releases.md)). Based on this, it prepares the commit and the next iteration of the Release Pull Request description. The last step is to update the Release Pull Request description.
|
||||||
|
|
||||||
|
Depending on the time since the last release, a lot of API calls are made to learn about these changes; this can take between a few seconds and a few minutes. If the user makes any changes to the Release Pull Request in this time frame, they are not considered for the next iteration of the description. To make sure that we do not lose these changes, `releaser-pleaser` fetches the Release Pull Request description again right before updating it. In case it changed from the start of the process, the attempt is aborted, and the whole process is retried two times.
|
||||||
|
|
||||||
|
This does not fully eliminate the potential for data loss, but reduces the time frame from multiple seconds (up to minutes) to a few hundred milliseconds.
|
||||||
|
|
||||||
|
## Related Documentation
|
||||||
|
|
||||||
|
- **Explanation**
|
||||||
|
- [Release Pull Request](release-pr.md)
|
||||||
|
- **Guide**
|
||||||
|
- [Pre-releases](../guides/pre-releases.md)
|
||||||
|
- [Customizing Release Notes](../guides/release-notes.md)
|
||||||
|
- **Tutorial**
|
||||||
|
- [Getting started on GitHub](../tutorials/github.md)
|
||||||
|
- [Getting started on GitLab](../tutorials/gitlab.md)
|
||||||
|
|
||||||
|
|
@ -44,6 +44,10 @@ on:
|
||||||
- labeled
|
- labeled
|
||||||
- unlabeled
|
- unlabeled
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: releaser-pleaser
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
releaser-pleaser:
|
releaser-pleaser:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
|
||||||
1
go.mod
1
go.mod
|
|
@ -10,6 +10,7 @@ require (
|
||||||
github.com/go-git/go-git/v5 v5.16.2
|
github.com/go-git/go-git/v5 v5.16.2
|
||||||
github.com/google/go-github/v72 v72.0.0
|
github.com/google/go-github/v72 v72.0.0
|
||||||
github.com/leodido/go-conventionalcommits v0.12.0
|
github.com/leodido/go-conventionalcommits v0.12.0
|
||||||
|
github.com/lmittmann/tint v1.1.2
|
||||||
github.com/spf13/cobra v1.9.1
|
github.com/spf13/cobra v1.9.1
|
||||||
github.com/stretchr/testify v1.10.0
|
github.com/stretchr/testify v1.10.0
|
||||||
github.com/teekennedy/goldmark-markdown v0.5.1
|
github.com/teekennedy/goldmark-markdown v0.5.1
|
||||||
|
|
|
||||||
2
go.sum
2
go.sum
|
|
@ -65,6 +65,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
github.com/leodido/go-conventionalcommits v0.12.0 h1:pG01rl8Ze+mxnSSVB2wPdGASXyyU25EGwLUc0bWrmKc=
|
github.com/leodido/go-conventionalcommits v0.12.0 h1:pG01rl8Ze+mxnSSVB2wPdGASXyyU25EGwLUc0bWrmKc=
|
||||||
github.com/leodido/go-conventionalcommits v0.12.0/go.mod h1:DW+n8pQb5w/c7Vba7iGOMS3rkbPqykVlnrDykGjlsJM=
|
github.com/leodido/go-conventionalcommits v0.12.0/go.mod h1:DW+n8pQb5w/c7Vba7iGOMS3rkbPqykVlnrDykGjlsJM=
|
||||||
|
github.com/lmittmann/tint v1.1.2 h1:2CQzrL6rslrsyjqLDwD11bZ5OpLBPU+g3G/r5LSfS8w=
|
||||||
|
github.com/lmittmann/tint v1.1.2/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE=
|
||||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package rp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
|
|
||||||
|
|
@ -18,6 +19,14 @@ const (
|
||||||
PullRequestBranchFormat = "releaser-pleaser--branches--%s"
|
PullRequestBranchFormat = "releaser-pleaser--branches--%s"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
PullRequestConflictAttempts = 3
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrorPullRequestConflict = errors.New("conflict: pull request description was changed while releaser-pleaser was running")
|
||||||
|
)
|
||||||
|
|
||||||
type ReleaserPleaser struct {
|
type ReleaserPleaser struct {
|
||||||
forge forge.Forge
|
forge forge.Forge
|
||||||
logger *slog.Logger
|
logger *slog.Logger
|
||||||
|
|
@ -57,7 +66,7 @@ func (rp *ReleaserPleaser) Run(ctx context.Context) error {
|
||||||
return fmt.Errorf("failed to create pending releases: %w", err)
|
return fmt.Errorf("failed to create pending releases: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = rp.runReconcileReleasePR(ctx)
|
err = rp.runReconcileReleasePRWithRetries(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to reconcile release pull request: %w", err)
|
return fmt.Errorf("failed to reconcile release pull request: %w", err)
|
||||||
}
|
}
|
||||||
|
|
@ -143,6 +152,36 @@ func (rp *ReleaserPleaser) createPendingRelease(ctx context.Context, pr *release
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// runReconcileReleasePRWithRetries retries runReconcileReleasePR up to PullRequestConflictAttempts times, but only
|
||||||
|
// when a ErrorPullRequestConflict was encountered.
|
||||||
|
func (rp *ReleaserPleaser) runReconcileReleasePRWithRetries(ctx context.Context) error {
|
||||||
|
logger := rp.logger.With("method", "runReconcileReleasePRWithRetries", "totalAttempts", PullRequestConflictAttempts)
|
||||||
|
var err error
|
||||||
|
|
||||||
|
for i := range PullRequestConflictAttempts {
|
||||||
|
logger := logger.With("attempt", i+1)
|
||||||
|
logger.DebugContext(ctx, "attempting runReconcileReleasePR")
|
||||||
|
|
||||||
|
err = rp.runReconcileReleasePR(ctx)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, ErrorPullRequestConflict) {
|
||||||
|
logger.WarnContext(ctx, "detected conflict while updating pull request description, retrying")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (rp *ReleaserPleaser) runReconcileReleasePR(ctx context.Context) error {
|
func (rp *ReleaserPleaser) runReconcileReleasePR(ctx context.Context) error {
|
||||||
logger := rp.logger.With("method", "runReconcileReleasePR")
|
logger := rp.logger.With("method", "runReconcileReleasePR")
|
||||||
|
|
||||||
|
|
@ -305,6 +344,23 @@ func (rp *ReleaserPleaser) runReconcileReleasePR(ctx context.Context) error {
|
||||||
}
|
}
|
||||||
logger.InfoContext(ctx, "opened pull request", "pr.title", pr.Title, "pr.id", pr.ID, "pr.url", rp.forge.PullRequestURL(pr.ID))
|
logger.InfoContext(ctx, "opened pull request", "pr.title", pr.Title, "pr.id", pr.ID, "pr.url", rp.forge.PullRequestURL(pr.ID))
|
||||||
} else {
|
} else {
|
||||||
|
// Check if the pull request was updated while releaser-pleaser was running.
|
||||||
|
// This avoids a conflict where the user updated the PR while releaser-pleaser already pulled the info, and
|
||||||
|
// releaser-pleaser subsequently reverts the users changes. There is still a minimal time window for this to
|
||||||
|
// happen between us checking the PR again and submitting our changes.
|
||||||
|
|
||||||
|
logger.DebugContext(ctx, "checking for conflict in pr description", "pr.id", pr.ID)
|
||||||
|
recheckPR, err := rp.forge.PullRequestForBranch(ctx, rpBranch)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if recheckPR == nil {
|
||||||
|
return fmt.Errorf("PR was deleted while releaser-pleaser was running")
|
||||||
|
}
|
||||||
|
if recheckPR.Description != pr.Description {
|
||||||
|
return ErrorPullRequestConflict
|
||||||
|
}
|
||||||
|
|
||||||
pr.SetTitle(rp.targetBranch, nextVersion)
|
pr.SetTitle(rp.targetBranch, nextVersion)
|
||||||
|
|
||||||
overrides, err := pr.GetOverrides()
|
overrides, err := pr.GetOverrides()
|
||||||
|
|
|
||||||
|
|
@ -26,11 +26,21 @@ spec:
|
||||||
releaser-pleaser:
|
releaser-pleaser:
|
||||||
stage: $[[ inputs.stage ]]
|
stage: $[[ inputs.stage ]]
|
||||||
needs: $[[ inputs.needs ]]
|
needs: $[[ inputs.needs ]]
|
||||||
|
|
||||||
rules:
|
rules:
|
||||||
# There is no way to run a pipeline when the MR description is updated :(
|
# There is no way to run a pipeline when the MR description is updated :(
|
||||||
- if: $CI_COMMIT_BRANCH == "$[[ inputs.branch ]]"
|
- if: $CI_COMMIT_BRANCH == "$[[ inputs.branch ]]"
|
||||||
|
|
||||||
|
# If a newer releaser-pleaser job runs, this one may be cancelled without problem, releaser-pleaser is idempotent.
|
||||||
|
# This only works if the user enables "auto-cancel redundant pipelines", which we do tell them to, because this is
|
||||||
|
# intrusive and up to the user.
|
||||||
|
interruptible: true
|
||||||
|
|
||||||
|
# No need to have multiple releaser-pleaser jobs running at the same time. They all act on the same global state.
|
||||||
|
resource_group: releaser-pleaser
|
||||||
|
|
||||||
image:
|
image:
|
||||||
name: ghcr.io/apricote/releaser-pleaser:v0.5.1 # x-releaser-pleaser-version
|
name: ghcr.io/apricote/releaser-pleaser:v0.6.0 # x-releaser-pleaser-version
|
||||||
entrypoint: [ "" ]
|
entrypoint: [ "" ]
|
||||||
variables:
|
variables:
|
||||||
GITLAB_TOKEN: $[[ inputs.token ]]
|
GITLAB_TOKEN: $[[ inputs.token ]]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue