@ferrflow/doc 7.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs-en/ci/github-actions.md +120 -0
- package/docs-en/ci/gitlab-ci.md +90 -0
- package/docs-en/ci/hosted-bot.md +82 -0
- package/docs-en/ci/pipeline-triggers.md +287 -0
- package/docs-en/configuration/config-file.md +1259 -0
- package/docs-en/configuration/formats.md +220 -0
- package/docs-en/configuration/monorepo.md +390 -0
- package/docs-en/installation.md +56 -0
- package/docs-en/introduction.md +56 -0
- package/docs-en/quickstart.md +66 -0
- package/docs-en/reference/api.md +106 -0
- package/docs-en/reference/cli.md +483 -0
- package/docs-en/reference/conventional-commits.md +103 -0
- package/docs-en/reference/errors.md +508 -0
- package/docs-en/verifying-releases.md +97 -0
- package/docs-fr/ci/github-actions.md +109 -0
- package/docs-fr/ci/gitlab-ci.md +77 -0
- package/docs-fr/ci/hosted-bot.md +82 -0
- package/docs-fr/ci/pipeline-triggers.md +238 -0
- package/docs-fr/configuration/config-file.md +839 -0
- package/docs-fr/configuration/formats.md +163 -0
- package/docs-fr/configuration/monorepo.md +357 -0
- package/docs-fr/installation.md +56 -0
- package/docs-fr/introduction.md +54 -0
- package/docs-fr/quickstart.md +63 -0
- package/docs-fr/reference/api.md +106 -0
- package/docs-fr/reference/cli.md +407 -0
- package/docs-fr/reference/conventional-commits.md +103 -0
- package/docs-fr/reference/errors.md +378 -0
- package/docs-fr/verifying-releases.md +97 -0
- package/docs-fr-v4/ci/github-actions.md +106 -0
- package/docs-fr-v4/ci/gitlab-ci.md +77 -0
- package/docs-fr-v4/ci/pipeline-triggers.md +214 -0
- package/docs-fr-v4/configuration/config-file.md +769 -0
- package/docs-fr-v4/configuration/formats.md +128 -0
- package/docs-fr-v4/configuration/monorepo.md +324 -0
- package/docs-fr-v4/installation.md +48 -0
- package/docs-fr-v4/introduction.md +54 -0
- package/docs-fr-v4/legal/telemetry.md +65 -0
- package/docs-fr-v4/quickstart.md +63 -0
- package/docs-fr-v4/reference/cli.md +130 -0
- package/docs-fr-v4/reference/conventional-commits.md +67 -0
- package/docs-fr-v4/reference/errors.md +372 -0
- package/docs-fr-v5/ci/github-actions.md +109 -0
- package/docs-fr-v5/ci/gitlab-ci.md +77 -0
- package/docs-fr-v5/ci/hosted-bot.md +82 -0
- package/docs-fr-v5/ci/pipeline-triggers.md +238 -0
- package/docs-fr-v5/configuration/config-file.md +812 -0
- package/docs-fr-v5/configuration/formats.md +150 -0
- package/docs-fr-v5/configuration/monorepo.md +357 -0
- package/docs-fr-v5/installation.md +56 -0
- package/docs-fr-v5/introduction.md +54 -0
- package/docs-fr-v5/legal/telemetry.md +26 -0
- package/docs-fr-v5/quickstart.md +63 -0
- package/docs-fr-v5/reference/api.md +106 -0
- package/docs-fr-v5/reference/cli.md +356 -0
- package/docs-fr-v5/reference/conventional-commits.md +88 -0
- package/docs-fr-v5/reference/errors.md +378 -0
- package/docs-fr-v5/verifying-releases.md +97 -0
- package/docs-fr-v6/ci/github-actions.md +109 -0
- package/docs-fr-v6/ci/gitlab-ci.md +77 -0
- package/docs-fr-v6/ci/hosted-bot.md +82 -0
- package/docs-fr-v6/ci/pipeline-triggers.md +238 -0
- package/docs-fr-v6/configuration/config-file.md +813 -0
- package/docs-fr-v6/configuration/formats.md +150 -0
- package/docs-fr-v6/configuration/monorepo.md +357 -0
- package/docs-fr-v6/installation.md +56 -0
- package/docs-fr-v6/introduction.md +54 -0
- package/docs-fr-v6/quickstart.md +63 -0
- package/docs-fr-v6/reference/api.md +106 -0
- package/docs-fr-v6/reference/cli.md +356 -0
- package/docs-fr-v6/reference/conventional-commits.md +88 -0
- package/docs-fr-v6/reference/errors.md +378 -0
- package/docs-fr-v6/verifying-releases.md +97 -0
- package/docs-v0/ci/github-actions.md +77 -0
- package/docs-v0/ci/gitlab-ci.md +59 -0
- package/docs-v0/configuration/config-file.md +97 -0
- package/docs-v0/configuration/formats.md +86 -0
- package/docs-v0/configuration/monorepo.md +59 -0
- package/docs-v0/installation.md +48 -0
- package/docs-v0/introduction.md +34 -0
- package/docs-v0/legal/telemetry.md +63 -0
- package/docs-v0/quickstart.md +58 -0
- package/docs-v0/reference/cli.md +95 -0
- package/docs-v0/reference/conventional-commits.md +68 -0
- package/docs-v1/ci/github-actions.md +76 -0
- package/docs-v1/ci/gitlab-ci.md +58 -0
- package/docs-v1/configuration/config-file.md +515 -0
- package/docs-v1/configuration/formats.md +115 -0
- package/docs-v1/configuration/monorepo.md +246 -0
- package/docs-v1/installation.md +48 -0
- package/docs-v1/introduction.md +39 -0
- package/docs-v1/legal/telemetry.md +63 -0
- package/docs-v1/quickstart.md +62 -0
- package/docs-v1/reference/cli.md +128 -0
- package/docs-v1/reference/conventional-commits.md +67 -0
- package/docs-v2/ci/github-actions.md +117 -0
- package/docs-v2/ci/gitlab-ci.md +90 -0
- package/docs-v2/ci/pipeline-triggers.md +263 -0
- package/docs-v2/configuration/config-file.md +806 -0
- package/docs-v2/configuration/formats.md +98 -0
- package/docs-v2/configuration/monorepo.md +324 -0
- package/docs-v2/installation.md +48 -0
- package/docs-v2/introduction.md +40 -0
- package/docs-v2/legal/telemetry.md +66 -0
- package/docs-v2/quickstart.md +63 -0
- package/docs-v2/reference/cli.md +130 -0
- package/docs-v2/reference/conventional-commits.md +67 -0
- package/docs-v2/reference/errors.md +500 -0
- package/docs-v2/self-hosting.md +101 -0
- package/docs-v3/ci/github-actions.md +117 -0
- package/docs-v3/ci/gitlab-ci.md +90 -0
- package/docs-v3/ci/pipeline-triggers.md +263 -0
- package/docs-v3/configuration/config-file.md +806 -0
- package/docs-v3/configuration/formats.md +99 -0
- package/docs-v3/configuration/monorepo.md +324 -0
- package/docs-v3/installation.md +48 -0
- package/docs-v3/introduction.md +40 -0
- package/docs-v3/legal/telemetry.md +66 -0
- package/docs-v3/quickstart.md +66 -0
- package/docs-v3/reference/cli.md +161 -0
- package/docs-v3/reference/conventional-commits.md +67 -0
- package/docs-v3/reference/errors.md +502 -0
- package/docs-v3/self-hosting.md +137 -0
- package/docs-v4/ci/github-actions.md +117 -0
- package/docs-v4/ci/gitlab-ci.md +90 -0
- package/docs-v4/ci/pipeline-triggers.md +263 -0
- package/docs-v4/configuration/config-file.md +850 -0
- package/docs-v4/configuration/formats.md +182 -0
- package/docs-v4/configuration/monorepo.md +324 -0
- package/docs-v4/installation.md +48 -0
- package/docs-v4/introduction.md +56 -0
- package/docs-v4/legal/telemetry.md +65 -0
- package/docs-v4/quickstart.md +66 -0
- package/docs-v4/reference/cli.md +161 -0
- package/docs-v4/reference/conventional-commits.md +67 -0
- package/docs-v4/reference/errors.md +502 -0
- package/docs-v4/self-hosting.md +137 -0
- package/docs-v5/ci/github-actions.md +120 -0
- package/docs-v5/ci/gitlab-ci.md +90 -0
- package/docs-v5/ci/hosted-bot.md +82 -0
- package/docs-v5/ci/pipeline-triggers.md +287 -0
- package/docs-v5/configuration/config-file.md +1133 -0
- package/docs-v5/configuration/formats.md +206 -0
- package/docs-v5/configuration/monorepo.md +390 -0
- package/docs-v5/installation.md +56 -0
- package/docs-v5/introduction.md +56 -0
- package/docs-v5/legal/telemetry.md +26 -0
- package/docs-v5/quickstart.md +66 -0
- package/docs-v5/reference/api.md +106 -0
- package/docs-v5/reference/cli.md +431 -0
- package/docs-v5/reference/conventional-commits.md +88 -0
- package/docs-v5/reference/errors.md +508 -0
- package/docs-v5/verifying-releases.md +97 -0
- package/docs-v6/ci/github-actions.md +120 -0
- package/docs-v6/ci/gitlab-ci.md +90 -0
- package/docs-v6/ci/hosted-bot.md +82 -0
- package/docs-v6/ci/pipeline-triggers.md +287 -0
- package/docs-v6/configuration/config-file.md +1134 -0
- package/docs-v6/configuration/formats.md +206 -0
- package/docs-v6/configuration/monorepo.md +390 -0
- package/docs-v6/installation.md +56 -0
- package/docs-v6/introduction.md +56 -0
- package/docs-v6/quickstart.md +66 -0
- package/docs-v6/reference/api.md +106 -0
- package/docs-v6/reference/cli.md +431 -0
- package/docs-v6/reference/conventional-commits.md +88 -0
- package/docs-v6/reference/errors.md +508 -0
- package/docs-v6/verifying-releases.md +97 -0
- package/package.json +17 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: GitHub Actions
|
|
3
|
+
description: Run FerrFlow releases automatically in GitHub Actions.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## Using the official action
|
|
7
|
+
|
|
8
|
+
The easiest way to use FerrFlow in GitHub Actions is the `FerrLabs/ferrflow@v4` action. It installs the binary and runs `ferrflow release` automatically.
|
|
9
|
+
|
|
10
|
+
```yaml title=".github/workflows/release.yml"
|
|
11
|
+
name: Release
|
|
12
|
+
|
|
13
|
+
on:
|
|
14
|
+
push:
|
|
15
|
+
branches: [main]
|
|
16
|
+
|
|
17
|
+
jobs:
|
|
18
|
+
release:
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
permissions:
|
|
21
|
+
contents: write # required to push tags and create releases
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v6
|
|
24
|
+
with:
|
|
25
|
+
fetch-depth: 0 # full history needed for commit scanning
|
|
26
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
|
27
|
+
|
|
28
|
+
- uses: FerrLabs/ferrflow@v4
|
|
29
|
+
env:
|
|
30
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
<aside class="ferr-aside ferr-aside--warning"><div class="ferr-aside__body"><p><code>fetch-depth: 0</code> is required. Without it, FerrFlow cannot find previous tags and will treat every commit as new.</p>
|
|
34
|
+
</div></aside>
|
|
35
|
+
|
|
36
|
+
## Permissions
|
|
37
|
+
|
|
38
|
+
FerrFlow needs `contents: write` to:
|
|
39
|
+
|
|
40
|
+
- Push version bump commits
|
|
41
|
+
- Create and push git tags
|
|
42
|
+
- Create GitHub Releases
|
|
43
|
+
|
|
44
|
+
If your repository has branch protection rules, create a dedicated token with the necessary permissions and pass it as `FERRFLOW_TOKEN` or configure the action's `token` input.
|
|
45
|
+
|
|
46
|
+
## Accessing the release output
|
|
47
|
+
|
|
48
|
+
The action exposes the new version as an output you can use in downstream steps:
|
|
49
|
+
|
|
50
|
+
```yaml title=".github/workflows/release.yml"
|
|
51
|
+
- uses: FerrLabs/ferrflow@v4
|
|
52
|
+
id: ferrflow
|
|
53
|
+
env:
|
|
54
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
55
|
+
|
|
56
|
+
- name: Build Docker image
|
|
57
|
+
if: steps.ferrflow.outputs.version != ''
|
|
58
|
+
run: |
|
|
59
|
+
docker build -t myimage:${{ steps.ferrflow.outputs.version }} .
|
|
60
|
+
docker push myimage:${{ steps.ferrflow.outputs.version }}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Skip CI on release commits
|
|
64
|
+
|
|
65
|
+
FerrFlow commits version bumps with `[skip ci]` in the message by default to prevent infinite loops. No extra configuration needed.
|
|
66
|
+
|
|
67
|
+
## PR preview comments
|
|
68
|
+
|
|
69
|
+
FerrFlow can post a comment on every pull request showing what versions will be bumped when the PR is merged. The comment is automatically updated on each push.
|
|
70
|
+
|
|
71
|
+
```yaml title=".github/workflows/preview.yml"
|
|
72
|
+
name: FerrFlow Preview
|
|
73
|
+
|
|
74
|
+
on:
|
|
75
|
+
pull_request:
|
|
76
|
+
|
|
77
|
+
permissions:
|
|
78
|
+
contents: read
|
|
79
|
+
pull-requests: write
|
|
80
|
+
|
|
81
|
+
jobs:
|
|
82
|
+
preview:
|
|
83
|
+
runs-on: ubuntu-latest
|
|
84
|
+
steps:
|
|
85
|
+
- uses: actions/checkout@v6
|
|
86
|
+
with:
|
|
87
|
+
fetch-depth: 0
|
|
88
|
+
- uses: FerrLabs/ferrflow@v4
|
|
89
|
+
with:
|
|
90
|
+
mode: preview
|
|
91
|
+
env:
|
|
92
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
The comment looks like:
|
|
96
|
+
|
|
97
|
+
> **FerrFlow Release Preview**
|
|
98
|
+
>
|
|
99
|
+
> | Package | Current | Next | Bump |
|
|
100
|
+
> | ------- | ------- | ------- | ----- |
|
|
101
|
+
> | api | `1.5.0` | `1.6.0` | minor |
|
|
102
|
+
> | site | `1.8.0` | `1.8.1` | patch |
|
|
103
|
+
>
|
|
104
|
+
> Based on 3 commit(s).
|
|
105
|
+
|
|
106
|
+
If no releasable changes are detected, the comment says so.
|
|
107
|
+
|
|
108
|
+
## Monorepo example
|
|
109
|
+
|
|
110
|
+
In a monorepo, FerrFlow releases each changed package in a single run:
|
|
111
|
+
|
|
112
|
+
```yaml title=".github/workflows/release.yml"
|
|
113
|
+
- uses: FerrLabs/ferrflow@v4
|
|
114
|
+
env:
|
|
115
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
116
|
+
# Creates api@v1.3.0 and site@v0.5.1 in one step if both changed
|
|
117
|
+
```
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: GitLab CI
|
|
3
|
+
description: Run FerrFlow releases automatically in GitLab CI.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## Using the Docker image
|
|
7
|
+
|
|
8
|
+
The official FerrFlow Docker image ships the binary and can be used directly as a GitLab CI job image.
|
|
9
|
+
|
|
10
|
+
```yaml title=".gitlab-ci.yml"
|
|
11
|
+
release:
|
|
12
|
+
image: ghcr.io/ferrlabs/ferrflow:latest
|
|
13
|
+
stage: release
|
|
14
|
+
script:
|
|
15
|
+
- ferrflow release
|
|
16
|
+
variables:
|
|
17
|
+
GITLAB_TOKEN: $CI_JOB_TOKEN
|
|
18
|
+
rules:
|
|
19
|
+
- if: $CI_COMMIT_BRANCH == "main"
|
|
20
|
+
when: on_success
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
<aside class="ferr-aside ferr-aside--warning"><div class="ferr-aside__body"><p>Make sure your CI runner clones with full history. Add <code>GIT_DEPTH: 0</code> to the job variables to disable shallow cloning.</p>
|
|
24
|
+
</div></aside>
|
|
25
|
+
|
|
26
|
+
## Full history
|
|
27
|
+
|
|
28
|
+
```yaml title=".gitlab-ci.yml"
|
|
29
|
+
release:
|
|
30
|
+
image: ghcr.io/ferrlabs/ferrflow:latest
|
|
31
|
+
variables:
|
|
32
|
+
GIT_DEPTH: 0 # full history — required for tag scanning
|
|
33
|
+
GITLAB_TOKEN: $CI_JOB_TOKEN
|
|
34
|
+
script:
|
|
35
|
+
- ferrflow release
|
|
36
|
+
rules:
|
|
37
|
+
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Using a deploy token
|
|
41
|
+
|
|
42
|
+
If `CI_JOB_TOKEN` doesn't have permission to push tags, create a project deploy token with `write_repository` access and store it as a CI variable:
|
|
43
|
+
|
|
44
|
+
```yaml title=".gitlab-ci.yml"
|
|
45
|
+
release:
|
|
46
|
+
image: ghcr.io/ferrlabs/ferrflow:latest
|
|
47
|
+
variables:
|
|
48
|
+
GIT_DEPTH: 0
|
|
49
|
+
GITLAB_TOKEN: $FERRFLOW_DEPLOY_TOKEN # CI variable with write_repository access
|
|
50
|
+
script:
|
|
51
|
+
- ferrflow release
|
|
52
|
+
rules:
|
|
53
|
+
- if: $CI_COMMIT_BRANCH == "main"
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## MR preview comments
|
|
57
|
+
|
|
58
|
+
FerrFlow can post a comment on every merge request showing what versions will be bumped when the MR is merged. The comment is automatically updated on each push.
|
|
59
|
+
|
|
60
|
+
```yaml title=".gitlab-ci.yml"
|
|
61
|
+
ferrflow-preview:
|
|
62
|
+
image: ghcr.io/ferrlabs/ferrflow:latest
|
|
63
|
+
stage: test
|
|
64
|
+
variables:
|
|
65
|
+
GIT_DEPTH: 0
|
|
66
|
+
GITLAB_TOKEN: $CI_JOB_TOKEN
|
|
67
|
+
script:
|
|
68
|
+
- ferrflow check --comment
|
|
69
|
+
rules:
|
|
70
|
+
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
The comment looks like:
|
|
74
|
+
|
|
75
|
+
> **FerrFlow Release Preview**
|
|
76
|
+
>
|
|
77
|
+
> | Package | Current | Next | Bump |
|
|
78
|
+
> | ------- | ------- | ------- | ----- |
|
|
79
|
+
> | api | `1.5.0` | `1.6.0` | minor |
|
|
80
|
+
>
|
|
81
|
+
> Based on 2 commit(s).
|
|
82
|
+
|
|
83
|
+
If no releasable changes are detected, the comment says so.
|
|
84
|
+
|
|
85
|
+
<aside class="ferr-aside ferr-aside--note"><div class="ferr-aside__body"><p><code>CI_JOB_TOKEN</code> has permission to post MR notes by default. If your project restricts this, use a project access token with <code>api</code> scope stored as a CI variable.</p>
|
|
86
|
+
</div></aside>
|
|
87
|
+
|
|
88
|
+
## GitLab Releases
|
|
89
|
+
|
|
90
|
+
When `GITLAB_TOKEN` is set, FerrFlow creates a GitLab Release with the generated changelog as release notes, matching the behaviour of the GitHub integration.
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Pipeline Triggers
|
|
3
|
+
description: Choose the right CI trigger strategy for your FerrFlow releases.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
FerrFlow works with any CI trigger strategy. This page covers the most common patterns, when to use each one, and how they interact with `releaseCommitMode`.
|
|
7
|
+
|
|
8
|
+
## Push to main
|
|
9
|
+
|
|
10
|
+
The simplest setup: run `ferrflow release` on every push to the default branch. FerrFlow decides whether a release is needed based on the commits since the last tag.
|
|
11
|
+
|
|
12
|
+
```yaml title=".github/workflows/release.yml"
|
|
13
|
+
name: Release
|
|
14
|
+
|
|
15
|
+
on:
|
|
16
|
+
push:
|
|
17
|
+
branches: [main]
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
release:
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
# Skip release commits to avoid infinite loops
|
|
23
|
+
if: "!startsWith(github.event.head_commit.message, 'chore(release):')"
|
|
24
|
+
permissions:
|
|
25
|
+
contents: write
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@v6
|
|
28
|
+
with:
|
|
29
|
+
fetch-depth: 0
|
|
30
|
+
token: ${{ secrets.FERRFLOW_TOKEN }}
|
|
31
|
+
|
|
32
|
+
- uses: FerrLabs/ferrflow@v4
|
|
33
|
+
env:
|
|
34
|
+
GITHUB_TOKEN: ${{ secrets.FERRFLOW_TOKEN }}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**When to use:** Most projects. Simple, predictable, fully automated.
|
|
38
|
+
|
|
39
|
+
**Trade-offs:** Every push to main triggers a workflow run, even if no release is needed. FerrFlow exits early when there are no releasable commits, so the cost is minimal.
|
|
40
|
+
|
|
41
|
+
**Works with:** `releaseCommitMode: commit` (default) or `none`.
|
|
42
|
+
|
|
43
|
+
## Tag-triggered
|
|
44
|
+
|
|
45
|
+
Run your build/deploy pipeline when FerrFlow creates a new tag. This separates the release step (tagging) from the downstream steps (building, publishing, deploying).
|
|
46
|
+
|
|
47
|
+
```yaml title=".github/workflows/build.yml"
|
|
48
|
+
name: Build & Publish
|
|
49
|
+
|
|
50
|
+
on:
|
|
51
|
+
push:
|
|
52
|
+
tags:
|
|
53
|
+
- 'v*' # single-repo: v1.2.0
|
|
54
|
+
- '*@v*' # monorepo: api@v1.2.0, site@v0.5.1
|
|
55
|
+
|
|
56
|
+
jobs:
|
|
57
|
+
build:
|
|
58
|
+
runs-on: ubuntu-latest
|
|
59
|
+
steps:
|
|
60
|
+
- uses: actions/checkout@v6
|
|
61
|
+
|
|
62
|
+
- name: Extract version from tag
|
|
63
|
+
id: version
|
|
64
|
+
run: |
|
|
65
|
+
TAG="${GITHUB_REF_NAME}"
|
|
66
|
+
VERSION="${TAG##*v}"
|
|
67
|
+
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
|
|
68
|
+
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
|
|
69
|
+
|
|
70
|
+
- name: Build
|
|
71
|
+
run: echo "Building version ${{ steps.version.outputs.version }}"
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**When to use:** When you want to decouple versioning from build/deploy. Common for Docker image builds, npm publishing, or binary releases.
|
|
75
|
+
|
|
76
|
+
**Trade-offs:** Requires two workflows: one for the release (push-to-main) and one for the downstream build (tag-triggered). Adds a few seconds of latency between the tag push and the build start.
|
|
77
|
+
|
|
78
|
+
### Monorepo: per-package builds
|
|
79
|
+
|
|
80
|
+
In a monorepo, use tag patterns to build only the package that was released:
|
|
81
|
+
|
|
82
|
+
```yaml title=".github/workflows/build.yml"
|
|
83
|
+
name: Build Package
|
|
84
|
+
|
|
85
|
+
on:
|
|
86
|
+
push:
|
|
87
|
+
tags:
|
|
88
|
+
- 'api@v*'
|
|
89
|
+
- 'site@v*'
|
|
90
|
+
|
|
91
|
+
jobs:
|
|
92
|
+
build-api:
|
|
93
|
+
if: startsWith(github.ref_name, 'api@v')
|
|
94
|
+
runs-on: ubuntu-latest
|
|
95
|
+
steps:
|
|
96
|
+
- uses: actions/checkout@v6
|
|
97
|
+
- run: echo "Building API ${{ github.ref_name }}"
|
|
98
|
+
|
|
99
|
+
build-site:
|
|
100
|
+
if: startsWith(github.ref_name, 'site@v')
|
|
101
|
+
runs-on: ubuntu-latest
|
|
102
|
+
steps:
|
|
103
|
+
- uses: actions/checkout@v6
|
|
104
|
+
- run: echo "Building site ${{ github.ref_name }}"
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
<aside class="ferr-aside ferr-aside--note"><div class="ferr-aside__body"><p>If FerrFlow releases multiple packages in a single run (e.g. <code>api@v1.3.0</code> and <code>site@v0.5.1</code>), each tag triggers its own workflow run. The builds happen in parallel automatically.</p>
|
|
108
|
+
</div></aside>
|
|
109
|
+
|
|
110
|
+
## Release-triggered
|
|
111
|
+
|
|
112
|
+
Run a pipeline when a GitHub Release is published. This works well with FerrFlow's `--draft` flag: FerrFlow creates a draft release, you review it, then publishing triggers the build.
|
|
113
|
+
|
|
114
|
+
```yaml title=".github/workflows/deploy.yml"
|
|
115
|
+
name: Deploy
|
|
116
|
+
|
|
117
|
+
on:
|
|
118
|
+
release:
|
|
119
|
+
types: [published]
|
|
120
|
+
|
|
121
|
+
jobs:
|
|
122
|
+
deploy:
|
|
123
|
+
runs-on: ubuntu-latest
|
|
124
|
+
steps:
|
|
125
|
+
- uses: actions/checkout@v6
|
|
126
|
+
with:
|
|
127
|
+
ref: ${{ github.event.release.tag_name }}
|
|
128
|
+
|
|
129
|
+
- name: Deploy
|
|
130
|
+
run: echo "Deploying ${{ github.event.release.tag_name }}"
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
**When to use:** When you want a manual review gate before deploying. Create draft releases with `ferrflow release --draft`, review the changelog, then publish.
|
|
134
|
+
|
|
135
|
+
**Trade-offs:** Adds a manual step. The draft release must be published before the deploy runs.
|
|
136
|
+
|
|
137
|
+
**Works with:** All `releaseCommitMode` values.
|
|
138
|
+
|
|
139
|
+
## Manual (workflow_dispatch)
|
|
140
|
+
|
|
141
|
+
Trigger a release on demand with an optional dry-run flag. Useful for controlled release cadences or when you don't want every merge to potentially release.
|
|
142
|
+
|
|
143
|
+
```yaml title=".github/workflows/release.yml"
|
|
144
|
+
name: Release
|
|
145
|
+
|
|
146
|
+
on:
|
|
147
|
+
workflow_dispatch:
|
|
148
|
+
inputs:
|
|
149
|
+
dry_run:
|
|
150
|
+
description: 'Dry run (no tags, no commits, no releases)'
|
|
151
|
+
type: boolean
|
|
152
|
+
default: false
|
|
153
|
+
|
|
154
|
+
jobs:
|
|
155
|
+
release:
|
|
156
|
+
runs-on: ubuntu-latest
|
|
157
|
+
permissions:
|
|
158
|
+
contents: write
|
|
159
|
+
steps:
|
|
160
|
+
- uses: actions/checkout@v6
|
|
161
|
+
with:
|
|
162
|
+
fetch-depth: 0
|
|
163
|
+
token: ${{ secrets.FERRFLOW_TOKEN }}
|
|
164
|
+
|
|
165
|
+
- uses: FerrLabs/ferrflow@v4
|
|
166
|
+
with:
|
|
167
|
+
args: ${{ inputs.dry_run == true && '--dry-run' || '' }}
|
|
168
|
+
env:
|
|
169
|
+
GITHUB_TOKEN: ${{ secrets.FERRFLOW_TOKEN }}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
**When to use:** Teams that prefer explicit release decisions over automatic releases. Also useful as a secondary workflow alongside push-to-main for ad-hoc releases.
|
|
173
|
+
|
|
174
|
+
**Trade-offs:** Requires someone to click "Run workflow" in the Actions tab. Commits can pile up between releases, producing larger changelogs.
|
|
175
|
+
|
|
176
|
+
## PR-based
|
|
177
|
+
|
|
178
|
+
Use `releaseCommitMode: pr` to have FerrFlow open a pull request with the version bump instead of committing directly. The release completes when the PR is merged.
|
|
179
|
+
|
|
180
|
+
```yaml title="ferrflow.json"
|
|
181
|
+
{ 'workspace': { 'releaseCommitMode': 'pr' } }
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
```yaml title=".github/workflows/release.yml"
|
|
185
|
+
name: Release
|
|
186
|
+
|
|
187
|
+
on:
|
|
188
|
+
push:
|
|
189
|
+
branches: [main]
|
|
190
|
+
|
|
191
|
+
jobs:
|
|
192
|
+
release:
|
|
193
|
+
runs-on: ubuntu-latest
|
|
194
|
+
if: "!startsWith(github.event.head_commit.message, 'chore(release):')"
|
|
195
|
+
permissions:
|
|
196
|
+
contents: write
|
|
197
|
+
pull-requests: write
|
|
198
|
+
steps:
|
|
199
|
+
- uses: actions/checkout@v6
|
|
200
|
+
with:
|
|
201
|
+
fetch-depth: 0
|
|
202
|
+
token: ${{ secrets.FERRFLOW_TOKEN }}
|
|
203
|
+
|
|
204
|
+
- uses: FerrLabs/ferrflow@v4
|
|
205
|
+
env:
|
|
206
|
+
GITHUB_TOKEN: ${{ secrets.FERRFLOW_TOKEN }}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
**When to use:** When you want to review version bumps before they land, or when branch protection prevents direct pushes to main.
|
|
210
|
+
|
|
211
|
+
**Trade-offs:** Adds an extra merge step. The PR must be merged before tags are created.
|
|
212
|
+
|
|
213
|
+
**Works with:** `releaseCommitMode: pr` only. Requires `pull-requests: write` permission.
|
|
214
|
+
|
|
215
|
+
## Combining strategies
|
|
216
|
+
|
|
217
|
+
A common production setup combines push-to-main for versioning with tag-triggered builds:
|
|
218
|
+
|
|
219
|
+
```yaml title=".github/workflows/release.yml"
|
|
220
|
+
# Workflow 1: Version and tag on every push to main
|
|
221
|
+
name: Release
|
|
222
|
+
on:
|
|
223
|
+
push:
|
|
224
|
+
branches: [main]
|
|
225
|
+
jobs:
|
|
226
|
+
release:
|
|
227
|
+
if: "!startsWith(github.event.head_commit.message, 'chore(release):')"
|
|
228
|
+
runs-on: ubuntu-latest
|
|
229
|
+
permissions:
|
|
230
|
+
contents: write
|
|
231
|
+
steps:
|
|
232
|
+
- uses: actions/checkout@v6
|
|
233
|
+
with:
|
|
234
|
+
fetch-depth: 0
|
|
235
|
+
token: ${{ secrets.FERRFLOW_TOKEN }}
|
|
236
|
+
- uses: FerrLabs/ferrflow@v4
|
|
237
|
+
env:
|
|
238
|
+
GITHUB_TOKEN: ${{ secrets.FERRFLOW_TOKEN }}
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
```yaml title=".github/workflows/build.yml"
|
|
242
|
+
# Workflow 2: Build and deploy when a tag is pushed
|
|
243
|
+
name: Build
|
|
244
|
+
on:
|
|
245
|
+
push:
|
|
246
|
+
tags: ['v*', '*@v*']
|
|
247
|
+
jobs:
|
|
248
|
+
build:
|
|
249
|
+
runs-on: ubuntu-latest
|
|
250
|
+
steps:
|
|
251
|
+
- uses: actions/checkout@v6
|
|
252
|
+
- run: echo "Building ${{ github.ref_name }}"
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
## Summary
|
|
256
|
+
|
|
257
|
+
| Trigger | Automatic | Review gate | Best for |
|
|
258
|
+
| ----------------- | --------- | ----------- | -------------------------- |
|
|
259
|
+
| Push to main | Yes | No | Most projects |
|
|
260
|
+
| Tag-triggered | Yes | No | Decoupled build/deploy |
|
|
261
|
+
| Release-triggered | No | Yes | Draft → review → publish |
|
|
262
|
+
| Manual | No | Yes | Controlled release cadence |
|
|
263
|
+
| PR-based | Partial | Yes | Branch protection / review |
|