Compare commits

..

5 commits

Author SHA1 Message Date
4cc45ea244
chore(main): release v0.4.0 (#62)
Co-authored-by: releaser-pleaser <>
2024-09-25 13:06:06 +02:00
89dc9e3fe8
feat(gitlab): support self-managed instances (#75)
Support self-managed gitlab instances by reading the GitLab CI environment
variables.
2024-09-25 12:41:11 +02:00
55083f2a59
docs: guide for extra-files (#74) 2024-09-25 12:09:27 +02:00
08505a55cd
ci(mirror): fix missing lfs files on push (#73) 2024-09-25 09:35:59 +00:00
1a370c39dc
docs: GitLab tutorial and CI/CD component reference (#72) 2024-09-25 11:23:04 +02:00
14 changed files with 269 additions and 20 deletions

View file

@ -15,6 +15,8 @@ jobs:
with: with:
# Need all to fetch all tags so we can push them # Need all to fetch all tags so we can push them
fetch-depth: 0 fetch-depth: 0
# Required so they can be pushed too
lfs: true
- name: Add Remote - name: Add Remote
env: env:

View file

@ -1,5 +1,28 @@
# Changelog # Changelog
## [v0.4.0](https://github.com/apricote/releaser-pleaser/releases/tag/v0.4.0)
### ✨ Highlights
#### GitLab Support
You can now use `releaser-pleaser` with projects hosted on GitLab.com and self-managed GitLab installations. Check out the new [tutorial](https://apricote.github.io/releaser-pleaser/tutorials/gitlab.html) to get started.
### Features
- add support for GitLab repositories (#49)
- add shell to container image (#59)
- **gitlab**: add CI/CD component (#55)
- **changelog**: omit version heading in forge release notes
- **gitlab**: support self-managed instances (#75)
### Bug Fixes
- **parser**: continue on unparsable commit message (#48)
- **cli**: command name in help output (#52)
- **parser**: invalid handling of empty lines (#53)
- multiple extra-files are not evaluated properly (#61)
## [v0.4.0-beta.1](https://github.com/apricote/releaser-pleaser/releases/tag/v0.4.0-beta.1) ## [v0.4.0-beta.1](https://github.com/apricote/releaser-pleaser/releases/tag/v0.4.0-beta.1)
### Features ### Features

View file

@ -1,7 +1,14 @@
# releaser-pleaser # releaser-pleaser
`releaser-pleaser` is a tool designed to automate versioning and changelog management for your projects. Building on the concepts of [ <p align="center">
`release-please`](https://github.com/googleapis/release-please), it streamlines the release process through GitHub Actions or GitLab CI. <code>releaser-pleaser</code> is a tool designed to automate versioning and changelog management for your projects. Building on the concepts of <a href="https://github.com/googleapis/release-please"><code>release-please</code></a>, it streamlines the release process through GitHub Actions or GitLab CI.
</p>
<p align="center">
<a href="https://apricote.github.io/releaser-pleaser" target="_blank"><img src="https://img.shields.io/badge/Documentation-brightgreen?style=flat-square" alt="Badge: Documentation"/></a>
<a href="https://github.com/apricote/releaser-pleaser/releases" target="_blank"><img src="https://img.shields.io/github/v/release/apricote/releaser-pleaser?sort=semver&display_name=release&style=flat-square&color=green" alt="Badge: Stable Release"/></a>
<img src="https://img.shields.io/badge/License-GPL--3.0-green?style=flat-square" alt="Badge: License GPL-3.0"/>
</p>
## Features ## Features
@ -15,10 +22,6 @@
`releaser-pleaser` simplifies release management, allowing maintainers to focus on development while ensuring consistent and well-documented releases. `releaser-pleaser` simplifies release management, allowing maintainers to focus on development while ensuring consistent and well-documented releases.
## Status
This project is still under active development. You can not reasonably use it right now and not all features advertised above work. Keep your eyes open for any releases.
## Relation to `release-please` ## Relation to `release-please`
After using After using

View file

@ -21,7 +21,7 @@ inputs:
outputs: {} outputs: {}
runs: runs:
using: 'docker' using: 'docker'
image: ghcr.io/apricote/releaser-pleaser:v0.4.0-beta.1 # x-releaser-pleaser-version image: ghcr.io/apricote/releaser-pleaser:v0.4.0 # x-releaser-pleaser-version
args: args:
- run - run
- --forge=github - --forge=github

View file

@ -5,7 +5,7 @@
# Tutorials # Tutorials
- [Getting started on GitHub](tutorials/github.md) - [Getting started on GitHub](tutorials/github.md)
- [Getting started on GitLab]() - [Getting started on GitLab](tutorials/gitlab.md)
# Explanation # Explanation
@ -16,13 +16,14 @@
- [Customizing Release Notes](guides/release-notes.md) - [Customizing Release Notes](guides/release-notes.md)
- [Pre-releases](guides/pre-releases.md) - [Pre-releases](guides/pre-releases.md)
- [Workflow Permissions on GitHub](guides/github-workflow-permissions.md) - [Workflow Permissions on GitHub](guides/github-workflow-permissions.md)
- [Updating arbitrary files](guides/updating-arbitrary-files.md)
# Reference # Reference
- [Glossary](reference/glossary.md) - [Glossary](reference/glossary.md)
- [Pull Request Options](reference/pr-options.md) - [Pull Request Options](reference/pr-options.md)
- [GitHub Action](reference/github-action.md) - [GitHub Action](reference/github-action.md)
- [GitLab CI]() - [GitLab CI/CD Component](reference/gitlab-cicd-component.md)
--- ---

View file

@ -0,0 +1,63 @@
# Updating arbitrary files
In some situations it makes sense to have the current version committed in files in the repository:
- Documentation examples
- A source-code file that has the version for user agents and introspection
- Reference to a container image tag that is built from the repository
`releaser-pleaser` can automatically update these references in the [Release PR](../explanation/release-pr.md).
## Markers
The line that needs to be updated must have the marker `x-releaser-pleaser-version` somewhere after the version that should be updated.
For example:
```go
// version/version.go
package version
const Version = "v1.0.0" // x-releaser-pleaser-version
```
## Extra Files
You need to tell `releaser-pleaser` which files it should update. This happens through the CI-specific configuration.
### GitHub Action
In the GitHub Action you can set the `extra-files` input with a list of the files. They need to be formatted as a single multi-line string with one file path per line:
```yaml
jobs:
releaser-pleaser:
steps:
- uses: apricote/releaser-pleaser@v0.4.0
with:
extra-files: |
version.txt
version/version.go
docker-compose.yml
```
### GitLab CI/CD Component
In the GitLab CI/CD Component you can set the `extra-files` input with a list of files. They need to be formatted as a single multi-line string with one file path per line:
```yaml
include:
- component: $CI_SERVER_FQDN/apricote/releaser-pleaser/run@v0.4.0
inputs:
extra-files: |
version.txt
version/version.go
docker-compose.yml
```
## Related Documentation
- **Reference**
- [GitHub Action](../reference/github-action.md#inputs)
- [GitLab CI/CD Component](../reference/gitlab-cicd-component.md#inputs)

View file

@ -0,0 +1,23 @@
# GitLab CI/CD Component
## Reference
The CI/CD component is available as `$CI_SERVER_FQDN/apricote/releaser-pleaser/run` on gitlab.com.
It is being distributed through the CI/CD Catalog: [apricote/releaser-pleaser](https://gitlab.com/explore/catalog/apricote/releaser-pleaser).
## Versions
The `apricote/releaser-pleaser` action is released together with `releaser-pleaser` and they share the version number.
The component does not support floating tags (e.g. `v1`) right now ([#31](https://github.com/apricote/releaser-pleaser/issues/31)). You have to use the full version or commit SHA instead: `apricote/releaser-pleaser@v0.4.0`.
## Inputs
The following inputs are supported by the component.
| Input | Description | Default | Example |
| ---------------------- | :-------------------------------------------------------- | ------: | -------------------------------------------------------------------: |
| `branch` | This branch is used as the target for releases. | `main` | `master` |
| `token` (**required**) | GitLab access token for creating and updating release PRs | | `$RELEASER_PLEASER_TOKEN` |
| `extra-files` | List of files that are scanned for version references. | `""` | <pre><code>version/version.go<br>deploy/deployment.yaml</code></pre> |

View file

@ -1,6 +1,6 @@
# GitHub # Getting started on GitHub
In this tutorial we show how to install `releaser-pleaser` in your GitHub project. In this tutorial you will learn how to set up `releaser-pleaser` in your GitHub project with GitHub Actions.
## 1. Repository Settings ## 1. Repository Settings
@ -52,7 +52,7 @@ jobs:
pull-requests: write pull-requests: write
steps: steps:
- name: releaser-pleaser - name: releaser-pleaser
uses: apricote/releaser-pleaser@v0.2.0 uses: apricote/releaser-pleaser@v0.4.0
``` ```
## 3. Release Pull Request ## 3. Release Pull Request

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:31b485bbe031443c4bfa0d39514dc7e5d524925aa877848def93ee40f69a1897
size 146496

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b853625854582a66ab2438f11e6001a88bcb276225abed536ba68617bde324db
size 57583

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:0ce9b9826229851e961ef55d91cb9ba91ca9ca4d955a932d9ff6b10d04788c29
size 41048

94
docs/tutorials/gitlab.md Normal file
View file

@ -0,0 +1,94 @@
# Getting started on GitLab
In this tutorial you will learn how to set up `releaser-pleaser` in your GitLab project with GitLab CI.
> In `releaser-pleaser` documentation we mostly use "Pull Request" (GitHub wording) instead of "Merge Request" (GitLab wording). The GitLab-specific pages are an exception and use "Merge Request".
## 1. Project Settings
### 1.1. Merge Requests
`releaser-pleaser` requires _Fast-forward merges_ and _squashing_. With other merge options it can not reliably find the right merge request for every commit on `main`.
Open your project settings to page _Merge Requests_:
> `https://gitlab.com/YOUR-PATH/YOUR-PROJECT/-/settings/merge_requests`
In the "Merge method" section select "Fast-forward merge":
![Screenshot of the required merge method settings](./gitlab-settings-merge-method.png)
In the "Squash commits when merging" section select "Require":
![Screenshot of the required squash settings](./gitlab-settings-squash.png)
## 2. API Access Token
`releaser-pleaser` uses the GitLab API to create the [release merge request](../explanation/release-pr.md) and subsequent releases for you. The default `GITLAB_TOKEN` available in CI jobs does not have enough permissions for this, so we need to create an Access Token and make it available in a CI variable.
## 2.1. Create Project Access Token
Open your project settings to page _Access tokens_:
> `https://gitlab.com/YOUR-PATH/YOUR-PROJECT/-/settings/access_tokens`
Create a token with these settings:
- **Name**: `releaser-pleaser`
- **Role**: `Maintainer`
- **Scopes**: `api`, `read_repository`, `write_repository`
Copy the created token for the next step.
![Screenshot of the access token settings](./gitlab-access-token.png)
## 2.2. Save token in CI variable
Open your project settings to page _CI/CD_:
> `https://gitlab.com/YOUR-PATH/YOUR-PROJECT/-/settings/ci_cd`
In the section "Variables" click on the "Add variable" button to open the form for a new variable. Use these settings to create the new variable:
- **Type**: Variable
- **Visibility**: Masked
- **Flags**: Uncheck "Protect variable" if your `main` branch is not protected
- **Key**: `RELEASER_PLEASER_TOKEN`
- **Value**: The project access token from the previous step
## 3. GitLab CI/CD
`releaser-pleaser` is published as a [GitLab CI/CD Component](https://docs.gitlab.com/ee/ci/components/): https://gitlab.com/explore/catalog/apricote/releaser-pleaser
Create or open your `.gitlab-ci.yml` and add the following include to your configuration:
```yaml
stages: [build]
include:
- component: $CI_SERVER_FQDN/apricote/releaser-pleaser/run@v0.4.0-beta.1
inputs:
token: $RELEASER_PLEASER_TOKEN
```
> You can set the `stage` input if you want to run `releaser-pleaser` during a different stage.
<div class="warning">
If you want to use `releaser-pleaser` on a self-managed GitLab instance, you need to mirror the GitLab.com component to your instance. See the official [GitLab documentation for details](https://docs.gitlab.com/ee/ci/components/#use-a-gitlabcom-component-in-a-self-managed-instance).
</div>
## 4. Release Merge Request
Once the `releaser-pleaser` job runs for the first time, you can check the logs to see what it did.
If you have releasable commits since the last tag, `releaser-pleaser` opens a release merge request for the proposed release.
Once you merge this merge request, `releaser-pleaser` automatically creates a Git tag and GitLab Release with the proposed version and changelog.
## Related Documentation
- **Explanation**
- [Release Pull Request](../explanation/release-pr.md)
- **Reference**
- [GitLab CI/CD Component](../reference/gitlab-cicd-component.md)

View file

@ -24,7 +24,13 @@ const (
PRStateOpen = "opened" PRStateOpen = "opened"
PRStateMerged = "merged" PRStateMerged = "merged"
PRStateEventClose = "close" PRStateEventClose = "close"
EnvAPIToken = "GITLAB_TOKEN" // nolint:gosec // Not actually a hardcoded credential EnvAPIToken = "GITLAB_TOKEN" // nolint:gosec // Not actually a hardcoded credential
// The following vars are from https://docs.gitlab.com/ee/ci/variables/predefined_variables.html
EnvAPIURL = "CI_API_V4_URL"
EnvProjectURL = "CI_PROJECT_URL"
EnvProjectPath = "CI_PROJECT_PATH" EnvProjectPath = "CI_PROJECT_PATH"
) )
@ -36,19 +42,23 @@ type GitLab struct {
} }
func (g *GitLab) RepoURL() string { func (g *GitLab) RepoURL() string {
if g.options.ProjectURL != "" {
return g.options.ProjectURL
}
return fmt.Sprintf("https://gitlab.com/%s", g.options.Path) return fmt.Sprintf("https://gitlab.com/%s", g.options.Path)
} }
func (g *GitLab) CloneURL() string { func (g *GitLab) CloneURL() string {
return fmt.Sprintf("https://gitlab.com/%s.git", g.options.Path) return fmt.Sprintf("%s.git", g.RepoURL())
} }
func (g *GitLab) ReleaseURL(version string) string { func (g *GitLab) ReleaseURL(version string) string {
return fmt.Sprintf("https://gitlab.com/%s/-/releases/%s", g.options.Path, version) return fmt.Sprintf("%s/-/releases/%s", g.RepoURL(), version)
} }
func (g *GitLab) PullRequestURL(id int) string { func (g *GitLab) PullRequestURL(id int) string {
return fmt.Sprintf("https://gitlab.com/%s/-/merge_requests/%d", g.options.Path, id) return fmt.Sprintf("%s/-/merge_requests/%d", g.RepoURL(), id)
} }
func (g *GitLab) GitAuth() transport.AuthMethod { func (g *GitLab) GitAuth() transport.AuthMethod {
@ -393,20 +403,41 @@ func gitlabMRToReleasePullRequest(pr *gitlab.MergeRequest) *releasepr.ReleasePul
func (g *Options) autodiscover() { func (g *Options) autodiscover() {
// Read settings from GitLab-CI env vars // Read settings from GitLab-CI env vars
if apiURL := os.Getenv(EnvAPIURL); apiURL != "" {
g.APIURL = apiURL
}
if apiToken := os.Getenv(EnvAPIToken); apiToken != "" { if apiToken := os.Getenv(EnvAPIToken); apiToken != "" {
g.APIToken = apiToken g.APIToken = apiToken
} }
if projectURL := os.Getenv(EnvProjectURL); projectURL != "" {
g.ProjectURL = projectURL
}
if projectPath := os.Getenv(EnvProjectPath); projectPath != "" { if projectPath := os.Getenv(EnvProjectPath); projectPath != "" {
g.Path = projectPath g.Path = projectPath
} }
}
func (g *Options) ClientOptions() []gitlab.ClientOptionFunc {
options := []gitlab.ClientOptionFunc{}
if g.APIURL != "" {
options = append(options, gitlab.WithBaseURL(g.APIURL))
}
return options
} }
type Options struct { type Options struct {
forge.Options forge.Options
ProjectURL string
Path string Path string
APIURL string
APIToken string APIToken string
} }
@ -414,7 +445,7 @@ func New(log *slog.Logger, options *Options) (*GitLab, error) {
log = log.With("forge", "gitlab") log = log.With("forge", "gitlab")
options.autodiscover() options.autodiscover()
client, err := gitlab.NewClient(options.APIToken) client, err := gitlab.NewClient(options.APIToken, options.ClientOptions()...)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -24,7 +24,7 @@ releaser-pleaser:
# 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 ]]"
image: image:
name: ghcr.io/apricote/releaser-pleaser:v0.4.0-beta.1 # x-releaser-pleaser-version name: ghcr.io/apricote/releaser-pleaser:v0.4.0 # x-releaser-pleaser-version
entrypoint: [""] entrypoint: [""]
variables: variables:
GITLAB_TOKEN: $[[ inputs.token ]] GITLAB_TOKEN: $[[ inputs.token ]]