Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 28 additions & 8 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -103,14 +103,14 @@ jobs:
gpg_fingerprint: ${{ steps.import_gpg.outputs.fingerprint }}

steps:
- uses: actions/create-github-app-token@v2
- uses: actions/create-github-app-token@fee1f7d63c2ff003460e3d139729b119787bc349 # v2
id: app-token
with:
app-id: ${{ secrets.LERIAN_STUDIO_MIDAZ_PUSH_BOT_APP_ID }}
private-key: ${{ secrets.LERIAN_STUDIO_MIDAZ_PUSH_BOT_PRIVATE_KEY }}

- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
fetch-depth: 0
token: ${{ steps.app-token.outputs.token }}
Expand All @@ -121,7 +121,7 @@ jobs:
git reset --hard origin/${{ github.ref_name }}

- name: Import GPG key
uses: crazy-max/ghaction-import-gpg@v7
uses: crazy-max/ghaction-import-gpg@2dc316deee8e90f13e1a351ab510b4d5bc0c82cd # v7
id: import_gpg
with:
gpg_private_key: ${{ secrets.LERIAN_CI_CD_USER_GPG_KEY }}
Expand All @@ -133,7 +133,7 @@ jobs:
git_commit_gpgsign: true

- name: Setup Node.js
uses: actions/setup-node@v6
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
with:
node-version: '20'

Expand All @@ -147,8 +147,13 @@ jobs:
npm install --save-dev \
@semantic-release/exec

# ----------------- Snapshot tags before release -----------------
- name: Snapshot tags before release
id: pre-tags
uses: LerianStudio/github-actions-shared-workflows/src/config/release-tag-snapshot@develop

- name: Semantic Release
uses: cycjimmy/semantic-release-action@v6
uses: cycjimmy/semantic-release-action@b12c8f6015dc215fe37bc154d4ad456dd3833c90 # v6
id: semantic
continue-on-error: true
with:
Expand All @@ -165,17 +170,32 @@ jobs:
GIT_COMMITTER_NAME: ${{ secrets.LERIAN_CI_CD_USER_NAME }}
GIT_COMMITTER_EMAIL: ${{ secrets.LERIAN_CI_CD_USER_EMAIL }}

# ----------------- Detect release via git tag -----------------
- name: Detect if release was published
if: always() && steps.semantic.outcome == 'failure'
id: detect-release
uses: LerianStudio/github-actions-shared-workflows/src/config/release-tag-check@develop
with:
previous-tag: ${{ steps.pre-tags.outputs.latest-tag }}

# ----------------- Backmerge Fallback -----------------
- name: Backmerge PR fallback
if: steps.semantic.outcome == 'failure' && steps.semantic.outputs.new_release_published == 'true'
if: |
always() && steps.semantic.outcome == 'failure' && (
steps.semantic.outputs.new_release_published == 'true' ||
steps.detect-release.outputs.release-published == 'true'
)
uses: LerianStudio/github-actions-shared-workflows/src/config/backmerge-pr@develop
with:
github-token: ${{ steps.app-token.outputs.token }}
source-branch: ${{ github.ref_name }}
version: ${{ steps.semantic.outputs.new_release_version }}
version: ${{ steps.semantic.outputs.new_release_version || steps.detect-release.outputs.release-version }}

- name: Fail if release itself failed
if: steps.semantic.outcome == 'failure' && steps.semantic.outputs.new_release_published != 'true'
if: |
always() && steps.semantic.outcome == 'failure' &&
steps.semantic.outputs.new_release_published != 'true' &&
steps.detect-release.outputs.release-published != 'true'
run: |
echo "::error::Semantic release failed before publishing a new version"
exit 1
Expand Down
61 changes: 61 additions & 0 deletions src/config/release-tag-check/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td><img src="https://github.com/LerianStudio.png" width="72" alt="Lerian" /></td>
<td><h1>release-tag-check</h1></td>
</tr>
</table>

Compares the current latest semver (`v*`) tag against a snapshot captured by [`release-tag-snapshot`](../release-tag-snapshot/) to detect whether a new release was published. This is useful when the release action exits with failure due to post-release steps (e.g., backmerge plugin) but the release itself was successful.

## Inputs

| Input | Description | Required | Default |
|-------|-------------|----------|---------|
| `previous-tag` | The tag captured by `release-tag-snapshot` before the release step | Yes | |

## Outputs

| Output | Description |
|--------|-------------|
| `release-published` | `true` if a new tag was created since the snapshot, `false` otherwise |
| `release-version` | The new release version (without `v` prefix), empty if no new release |

## Usage as composite step

```yaml
- name: Snapshot tags before release
id: pre-tags
uses: LerianStudio/github-actions-shared-workflows/src/config/release-tag-snapshot@v1.x.x

- name: Semantic Release
uses: cycjimmy/semantic-release-action@<sha> # v6
id: semantic
continue-on-error: true
...

- name: Check if release was published
id: detect-release
if: always() && steps.semantic.outcome == 'failure'
uses: LerianStudio/github-actions-shared-workflows/src/config/release-tag-check@v1.x.x
with:
previous-tag: ${{ steps.pre-tags.outputs.latest-tag }}

- name: Backmerge PR fallback
if: |
always() && steps.semantic.outcome == 'failure' && (
steps.semantic.outputs.new_release_published == 'true' ||
steps.detect-release.outputs.release-published == 'true'
)
uses: LerianStudio/github-actions-shared-workflows/src/config/backmerge-pr@v1.x.x
with:
github-token: ${{ steps.app-token.outputs.token }}
source-branch: ${{ github.ref_name }}
version: ${{ steps.semantic.outputs.new_release_version || steps.detect-release.outputs.release-version }}
```

## Required permissions

```yaml
permissions:
contents: read
```
36 changes: 36 additions & 0 deletions src/config/release-tag-check/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: Release Tag Check
description: "Compares the current latest semver tag against a previous snapshot to detect if a new release was published."

inputs:
previous-tag:
description: The tag captured by release-tag-snapshot before the release step
required: true

outputs:
release-published:
description: "'true' if a new tag was created since the snapshot, 'false' otherwise"
value: ${{ steps.check.outputs.release_published }}
release-version:
description: The new release version (without v prefix), empty if no new release
value: ${{ steps.check.outputs.release_version }}

runs:
using: composite
steps:
- name: Check for new release tag
id: check
shell: bash
env:
PREVIOUS_TAG: ${{ inputs.previous-tag }}
run: |
git fetch --tags origin
NEW_TAG=$(git tag -l 'v*' --sort=-v:refname | head -1)
if [ "$NEW_TAG" != "$PREVIOUS_TAG" ] && [ -n "$NEW_TAG" ]; then
echo "release_published=true" >> "$GITHUB_OUTPUT"
VERSION="${NEW_TAG#v}"
echo "release_version=${VERSION}" >> "$GITHUB_OUTPUT"
echo "::notice::Release ${NEW_TAG} was published despite post-release failure"
else
echo "release_published=false" >> "$GITHUB_OUTPUT"
echo "release_version=" >> "$GITHUB_OUTPUT"
fi
46 changes: 46 additions & 0 deletions src/config/release-tag-snapshot/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td><img src="https://github.com/LerianStudio.png" width="72" alt="Lerian" /></td>
<td><h1>release-tag-snapshot</h1></td>
</tr>
</table>

Captures the latest semver (`v*`) tag before a release step runs. Used together with [`release-tag-check`](../release-tag-check/) to detect whether a new release was published — even when the release action reports failure due to post-release steps (e.g., backmerge).

## Inputs

None.

## Outputs

| Output | Description |
|--------|-------------|
| `latest-tag` | The latest `v*` tag before the release step, or `none` if no tags exist |

## Usage as composite step

```yaml
- name: Snapshot tags before release
id: pre-tags
uses: LerianStudio/github-actions-shared-workflows/src/config/release-tag-snapshot@v1.x.x

- name: Semantic Release
uses: cycjimmy/semantic-release-action@<sha> # v6
id: semantic
continue-on-error: true
...

- name: Check if release was published
id: detect-release
if: always() && steps.semantic.outcome == 'failure'
uses: LerianStudio/github-actions-shared-workflows/src/config/release-tag-check@v1.x.x
with:
previous-tag: ${{ steps.pre-tags.outputs.latest-tag }}
```

## Required permissions

```yaml
permissions:
contents: read
```
18 changes: 18 additions & 0 deletions src/config/release-tag-snapshot/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: Release Tag Snapshot
description: "Captures the latest semver tag before a release step runs, enabling post-release comparison."

outputs:
latest-tag:
description: The latest v* tag before the release step (or 'none' if no tags exist)
value: ${{ steps.snapshot.outputs.latest_tag }}

runs:
using: composite
steps:
- name: Snapshot latest semver tag
id: snapshot
shell: bash
run: |
git fetch --tags origin
LATEST_TAG=$(git tag -l 'v*' --sort=-v:refname | head -1)
echo "latest_tag=${LATEST_TAG:-none}" >> "$GITHUB_OUTPUT"
Loading