CI: restructure release workflows
Some checks are pending
Continuous Integration / Pre-build checks (push) Waiting to run
Continuous Integration / Build compile-clang-sanitizers (push) Blocked by required conditions
Continuous Integration / Build compile-clang (push) Blocked by required conditions
Continuous Integration / Build compile-gcc (push) Blocked by required conditions
Continuous Integration / Build compile-gcc-O1 (push) Blocked by required conditions
Continuous Integration / Build compile-gcc-O3 (push) Blocked by required conditions
Continuous Integration / check-compiled-source (compile-gcc) (push) Blocked by required conditions
Continuous Integration / Run unit tests (push) Blocked by required conditions
Continuous Integration / Run unit tests-1 (push) Blocked by required conditions
Continuous Integration / Build 32-bit (size_t != 64-bit warnings) (push) Blocked by required conditions
Continuous Integration / Run fuzz regression tests (push) Blocked by required conditions
Continuous Integration / Check we can downgrade the node (push) Blocked by required conditions
Continuous Integration / Check we can downgrade the node-1 (push) Blocked by required conditions
Continuous Integration / Check we can downgrade the node-2 (push) Blocked by required conditions
Continuous Integration / First Integration Tests (1/6) (push) Blocked by required conditions
Continuous Integration / First Integration Tests (2/6) (push) Blocked by required conditions
Continuous Integration / First Integration Tests (3/6) (push) Blocked by required conditions
Continuous Integration / First Integration Tests (4/6) (push) Blocked by required conditions
Continuous Integration / First Integration Tests (5/6) (push) Blocked by required conditions
Continuous Integration / First Integration Tests (6/6) (push) Blocked by required conditions
Continuous Integration / Test CLN dual-fund Full Integration (push) Blocked by required conditions
Continuous Integration / Test CLN liquid Full Integration (push) Blocked by required conditions
Continuous Integration / Test CLN postgres Full Integration (push) Blocked by required conditions
Continuous Integration / Valgrind Test CLN (1/12) (push) Blocked by required conditions
Continuous Integration / Valgrind Test CLN (10/12) (push) Blocked by required conditions
Continuous Integration / Valgrind Test CLN (11/12) (push) Blocked by required conditions
Continuous Integration / Valgrind Test CLN (12/12) (push) Blocked by required conditions
Continuous Integration / Valgrind Test CLN (2/12) (push) Blocked by required conditions
Continuous Integration / Valgrind Test CLN (3/12) (push) Blocked by required conditions
Continuous Integration / Valgrind Test CLN (4/12) (push) Blocked by required conditions
Continuous Integration / Valgrind Test CLN (5/12) (push) Blocked by required conditions
Continuous Integration / Valgrind Test CLN (6/12) (push) Blocked by required conditions
Continuous Integration / Valgrind Test CLN (7/12) (push) Blocked by required conditions
Continuous Integration / Valgrind Test CLN (8/12) (push) Blocked by required conditions
Continuous Integration / Valgrind Test CLN (9/12) (push) Blocked by required conditions
Continuous Integration / ASan/UBSan (1/6) (push) Blocked by required conditions
Continuous Integration / ASan/UBSan (2/6) (push) Blocked by required conditions
Continuous Integration / ASan/UBSan (3/6) (push) Blocked by required conditions
Continuous Integration / ASan/UBSan (4/6) (push) Blocked by required conditions
Continuous Integration / ASan/UBSan (5/6) (push) Blocked by required conditions
Continuous Integration / ASan/UBSan (6/6) (push) Blocked by required conditions
Continuous Integration / Update examples in doc schemas (push) Blocked by required conditions
Continuous Integration / Test minimum supported BTC v25.0 with clang (push) Blocked by required conditions
Continuous Integration / CI completion (push) Blocked by required conditions
Release Rust 🦀 / release_rust (push) Waiting to run

Binaries, docker images, and python packages are now separated into
build and publish flows. First everything gets built and if every build
step succeeds the publish step can continue.
Also fan out the docker build into a matrix to speed up the workflow.

Changelog-None
This commit is contained in:
daywalker90 2026-07-23 13:58:17 +02:00
parent 7f22da25a5
commit 39b7f6dfbd
10 changed files with 533 additions and 393 deletions

56
.github/workflows/check-release-tag.yml vendored Normal file
View file

@ -0,0 +1,56 @@
name: Check release tag
on:
workflow_call:
inputs:
version:
type: string
required: false
skip_validation:
type: boolean
default: false
outputs:
version:
description: "Resolved release version"
value: ${{ jobs.check.outputs.version }}
jobs:
check:
name: Validate tag against .version file and release content
runs-on: ubuntu-24.04
outputs:
version: ${{ steps.resolve.outputs.version }}
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Validate tag matches .version file
id: resolve
run: |
if [[ "${{ github.ref_type }}" != "tag" ]]; then
echo "::notice::Not triggered by a tag push (ref_type=${{ github.ref_type }}); skipping .version check."
echo "version=${{ inputs.version }}" >> "$GITHUB_OUTPUT"
exit 0
fi
if [[ ! -f .version ]]; then
echo "::error::.version file not found in repository root."
exit 1
fi
FILE_VERSION="$(tr -d '[:space:]' < .version)"
TAG_VERSION="${{ github.ref_name }}"
if [[ "$TAG_VERSION" != "$FILE_VERSION" ]]; then
echo "::error::Tag '$TAG_VERSION' does not match version in .version file ('$FILE_VERSION'). Refusing to release."
exit 1
fi
echo "Tag '$TAG_VERSION' matches .version file."
echo "version=$TAG_VERSION" >> "$GITHUB_OUTPUT"
- name: Validate release
if: ${{ !inputs.skip_validation }}
run: tools/check-release.sh --version=${{ steps.resolve.outputs.version }}

86
.github/workflows/docker-build.yml vendored Normal file
View file

@ -0,0 +1,86 @@
name: Docker build
on:
workflow_call:
inputs:
version:
type: string
required: true
dh-repository-owner:
type: string
required: true
platforms-to-build:
type: string
required: true
jobs:
# Turn the comma-separated platforms-to-build input into a JSON matrix array,
# so we can fan out per-platform without hardcoding the list twice.
plan:
name: Plan platform matrix
runs-on: ubuntu-24.04
outputs:
platforms: ${{ steps.plan.outputs.platforms }}
steps:
- id: plan
run: |
IFS=',' read -ra ARR <<< "${{ inputs.platforms-to-build }}"
JSON=$(printf '%s\n' "${ARR[@]}" | jq -R . | jq -sc .)
echo "platforms=$JSON" >> "$GITHUB_OUTPUT"
build:
name: Build ${{ matrix.target == 'lightningd-vls-signer' && 'vls' || 'normal' }} / ${{ matrix.platform }}
needs: plan
strategy:
fail-fast: false
matrix:
target:
- lightningd
- lightningd-vls-signer
platform: ${{ fromJson(needs.plan.outputs.platforms) }}
runs-on: ${{ matrix.platform == 'linux/arm64' && 'ubuntu-22.04-arm' || 'ubuntu-22.04' }}
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Set up QEMU
if: matrix.platform == 'linux/arm/v7'
uses: docker/setup-qemu-action@v4
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Log in to Docker Hub
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build single-platform image, push by digest
id: build
uses: docker/build-push-action@v7
with:
context: .
file: ./Dockerfile
target: ${{ matrix.target }}
platforms: ${{ matrix.platform }}
build-args: |
VERSION=${{ inputs.version }}
outputs: type=image,name=${{ inputs.dh-repository-owner }}/lightningd,push-by-digest=true,name-canonical=true,push=true
cache-from: type=gha,scope=${{ matrix.target }}-${{ matrix.platform }}
cache-to: type=gha,mode=max,scope=${{ matrix.target }}-${{ matrix.platform }}
- name: Save digest
run: |
mkdir -p /tmp/digests
echo "${{ steps.build.outputs.digest }}" > /tmp/digests/digest.txt
- name: Upload digest
uses: actions/upload-artifact@v7
with:
name: digest_${{ matrix.target }}_${{ strategy.job-index }}
path: /tmp/digests/digest.txt
if-no-files-found: error
retention-days: 1

67
.github/workflows/docker-publish.yml vendored Normal file
View file

@ -0,0 +1,67 @@
name: Docker publish
on:
workflow_call:
inputs:
version:
type: string
required: true
dh-repository-owner:
type: string
required: true
push-latest:
type: string
required: true
jobs:
publish:
name: Tag and publish ${{ matrix.target }}
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
include:
- target: lightningd
tag_suffix: ''
- target: lightningd-vls-signer
tag_suffix: '-vls'
steps:
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Log in to Docker Hub
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Download platform digests for this target
uses: actions/download-artifact@v8
with:
pattern: digest_${{ matrix.target }}_*
path: /tmp/digests
merge-multiple: false
- name: Set up values
run: |
DIGEST_REFS=""
for f in /tmp/digests/*/digest.txt; do
D=$(cat "$f")
DIGEST_REFS="$DIGEST_REFS ${{ inputs.dh-repository-owner }}/lightningd@${D}"
done
echo "DIGEST_REFS=$DIGEST_REFS" >> $GITHUB_ENV
if [[ "${{ inputs.push-latest }}" == "true" ]] ||
([[ "${{ github.ref_type }}" == "tag" ]] && [[ ! "${{ inputs.version }}" =~ rc ]]); then
echo "PUSHLATEST=true" >> $GITHUB_ENV
else
echo "PUSHLATEST=false" >> $GITHUB_ENV
fi
- name: Create and push real tag(s)
run: |
TAG_ARGS=(-t "${{ inputs.dh-repository-owner }}/lightningd:${{ inputs.version }}${{ matrix.tag_suffix }}")
if [[ "$PUSHLATEST" == "true" ]]; then
TAG_ARGS+=(-t "${{ inputs.dh-repository-owner }}/lightningd:latest${{ matrix.tag_suffix }}")
fi
docker buildx imagetools create "${TAG_ARGS[@]}" $DIGEST_REFS

View file

@ -1,134 +0,0 @@
name: Publish multi-platform docker images
on:
push:
tags:
- 'v[0-9]+.[0-9]+'
- 'v[0-9]+.[0-9]+.[0-9]+'
- 'v[0-9]+.[0-9]+[0-9a-z]+'
workflow_dispatch:
inputs:
version:
description: 'Release version'
required: true
repository-name:
description: 'Docker repository name'
default: 'elementsproject'
required: false
platforms-to-build:
description: 'List of platforms to build'
default: 'linux/amd64,linux/arm64,linux/arm/v7'
required: false
push-latest:
description: 'Push the latest tag also?'
default: 'false'
required: false
jobs:
build:
runs-on: ubuntu-22.04
strategy:
fail-fast: false # Let each tag finish.
matrix:
include:
- target: lightningd
tag_suffix: ''
- target: lightningd-vls-signer
tag_suffix: '-vls'
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
ref: ${{ github.ref }} # Ensures the branch triggering the workflow is checked out
fetch-depth: 0
- name: Set up QEMU
uses: docker/setup-qemu-action@v4
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Log in to Docker Hub
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Set up values for ${{ matrix.target }}
id: set-values
run: |
if [[ "${{ github.event.inputs.version }}" != "" ]]; then
echo "Input version provided"
VERSION=${{ github.event.inputs.version }}
elif [[ ${{ github.ref_type }} == "tag" ]]; then
echo "This is a tag event"
VERSION=${{ github.ref_name }}
else
echo "No version provided and no tag found."
exit 1
fi
echo "VERSION=$VERSION" >> $GITHUB_ENV
if [[ "${{ github.event.inputs.repository-name }}" != "" ]]; then
REPONAME=${{ github.event.inputs.repository-name }}
else
REPONAME="elementsproject"
fi
echo "REPONAME=$REPONAME" >> $GITHUB_ENV
if [[ "${{ github.event.inputs.platforms-to-build }}" != "" ]]; then
PLATFORMS=${{ github.event.inputs.platforms-to-build }}
else
PLATFORMS="linux/amd64,linux/arm64,linux/arm/v7"
fi
echo "PLATFORMS=$PLATFORMS" >> $GITHUB_ENV
if [[ "${{ github.event.inputs.push-latest }}" == "true" ]] ||
([[ "${{ github.ref_type }}" == "tag" ]] && [[ ! "$VERSION" =~ rc ]]); then
echo "Latest true"
PUSHLATEST="true"
else
echo "Latest false"
PUSHLATEST="false"
fi
echo "PUSHLATEST=$PUSHLATEST" >> $GITHUB_ENV
TAGS="$REPONAME/lightningd:$VERSION${{ matrix.tag_suffix }}"
if [[ "$PUSHLATEST" == "true" ]]; then
TAGS="$TAGS,$REPONAME/lightningd:latest${{ matrix.tag_suffix }}"
fi
echo "TAGS=$TAGS" >> $GITHUB_ENV
- name: Print GitHub Ref Values
run: |
echo "TARGET: ${{ matrix.target }}"
echo "TAG SUFFIX: ${{ matrix.tag_suffix }}"
echo "GITHUB REF TYPE: ${{ github.ref_type }}"
echo "GITHUB REF NAME: ${{ github.ref_name }}"
echo "EVENT INPUT VERSION: ${{ github.event.inputs.version }}"
echo "EVENT INPUT REPO: ${{ github.event.inputs.repository-name }}"
echo "EVENT INPUT PLATFORMS: ${{ github.event.inputs.platforms-to-build }}"
echo "EVENT INPUT PUSH LATEST: ${{ github.event.inputs.push-latest }}"
echo "ENV VERSION: ${{ env.VERSION }}"
echo "ENV REPO NAME: ${{ env.REPONAME }}"
echo "ENV PLATFORMS: ${{ env.PLATFORMS }}"
echo "ENV PUSH LATEST: ${{ env.PUSHLATEST }}"
echo "ENV TAGS: ${{ env.TAGS }}"
- name: Build and push Docker tag - ${{ env.TAGS }}
uses: docker/build-push-action@v7
with:
context: .
file: ./Dockerfile
target: ${{ matrix.target }}
push: true
platforms: ${{ env.PLATFORMS }}
tags: ${{ env.TAGS }}
build-args: |
VERSION=${{ env.VERSION }}
cache-from: type=gha
cache-to: type=gha,mode=max

48
.github/workflows/pypi-build.yml vendored Normal file
View file

@ -0,0 +1,48 @@
name: PyPI build
on:
workflow_call:
inputs:
version:
type: string
required: true
jobs:
build:
name: Build ${{ matrix.PACKAGE }} 🐍
runs-on: ubuntu-22.04
timeout-minutes: 120
strategy:
fail-fast: false
matrix:
include:
- PACKAGE: pyln-client
- PACKAGE: pyln-testing
- PACKAGE: pyln-proto
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.10'
- name: Install uv
uses: astral-sh/setup-uv@v8.1.0
- name: Update pyln versions
run: |
make update-pyln-versions NEW_VERSION=${{ inputs.version }}
- name: Build distribution 📦
run: uv build --package ${{ matrix.PACKAGE }}
- name: Upload distribution artifact
uses: actions/upload-artifact@v7
with:
name: dist-${{ matrix.PACKAGE }}
path: dist/
if-no-files-found: error

58
.github/workflows/pypi-publish.yml vendored Normal file
View file

@ -0,0 +1,58 @@
name: PyPI publish
on:
workflow_call:
inputs:
version:
type: string
required: true
dist-location:
type: string
required: true
jobs:
publish:
name: Publish ${{ matrix.PACKAGE }} 🐍
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
include:
- PACKAGE: pyln-client
- PACKAGE: pyln-testing
- PACKAGE: pyln-proto
steps:
- name: Download built distribution
uses: actions/download-artifact@v8
with:
name: dist-${{ matrix.PACKAGE }}
path: dist/
- name: Determine PyPI distribution location
id: set-values
run: |
if [[ "${{ inputs.dist-location }}" != "" ]]; then
DISTLOCATION="${{ inputs.dist-location }}"
elif [[ "${{ github.ref_type }}" == "tag" ]] && [[ ! "${{ inputs.version }}" =~ rc ]]; then
DISTLOCATION="prod"
else
DISTLOCATION="test"
fi
echo "DISTLOCATION=$DISTLOCATION" >> "$GITHUB_OUTPUT"
echo "EVENT DISTLOCATION: ${{ github.event.inputs.dist-location }}"
echo "Resolved dist-location: $DISTLOCATION"
- name: Install uv
uses: astral-sh/setup-uv@v8.1.0
- name: Publish distribution 📦 to Test PyPI
if: github.repository == 'ElementsProject/lightning' && steps.set-values.outputs.DISTLOCATION == 'test'
env:
UV_PUBLISH_TOKEN: ${{ secrets.TEST_PYPI_API_TOKEN }}
run: uv publish --publish-url https://test.pypi.org/legacy/ --check-url https://test.pypi.org/simple/ dist/*
- name: Publish distribution 📦 to PyPI
if: github.repository == 'ElementsProject/lightning' && steps.set-values.outputs.DISTLOCATION == 'prod'
env:
UV_PUBLISH_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
run: uv publish dist/*

View file

@ -1,96 +0,0 @@
name: Publish Python 🐍 distributions 📦 to PyPI and TestPyPI
on:
push:
tags:
- 'v[0-9]+.[0-9]+'
- 'v[0-9]+.[0-9]+.[0-9]+'
- 'v[0-9]+.[0-9]+[0-9a-z]+'
workflow_dispatch:
inputs:
dist-location:
description: 'Distribution location (test/prod)'
default: 'test'
required: false
jobs:
deploy:
name: Build and publish ${{ matrix.package }} 🐍
runs-on: ubuntu-22.04
timeout-minutes: 120
strategy:
fail-fast: true
matrix:
include:
- PACKAGE: pyln-client
WORKDIR: contrib/pyln-client
- PACKAGE: pyln-testing
WORKDIR: contrib/pyln-testing
- PACKAGE: pyln-proto
WORKDIR: contrib/pyln-proto
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
# Need to fetch entire history in order to locate the version tag
fetch-depth: 0
- name: Check version tag
run: >-
git describe --tags --always --dirty=-modded --abbrev=7
- name: Setup Version
env:
WORKDIR: ${{ matrix.WORKDIR }}
run: |
echo "VERSION=$(git describe --tags --abbrev=0).post$(git describe --tags --abbrev=1 | awk -F "-" '{print $2}')" >> $GITHUB_ENV
- name: Set up values
id: set-values
run: |
if [[ "${{ github.event.inputs.dist-location }}" != "" ]]; then
DISTLOCATION=${{ github.event.inputs.dist-location }}
elif [[ "${{ github.ref_type }}" == "tag" ]] && [[ ! "${{ github.ref_name }}" =~ rc ]]; then
DISTLOCATION="prod"
else
DISTLOCATION="test"
fi
echo "DISTLOCATION=$DISTLOCATION" >> $GITHUB_OUTPUT
echo "EVENT DISTLOCATION: ${{ github.event.inputs.dist-location }}"
echo "DISTRIBUTION LOCATION: $DISTLOCATION"
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.10'
- name: Install uv
uses: astral-sh/setup-uv@v8.1.0
- name: Update pyln versions
id: update-versions
run: |
export VERSION=$(git describe --tags --abbrev=0)
echo "Pyln VERSION: $VERSION"
make update-pyln-versions NEW_VERSION=$VERSION
- name: Publish distribution 📦 to Test PyPI
if: github.repository == 'ElementsProject/lightning' && steps.set-values.outputs.DISTLOCATION == 'test'
env:
UV_PUBLISH_TOKEN: ${{ secrets.TEST_PYPI_API_TOKEN }}
WORKDIR: ${{ matrix.WORKDIR }}
run: |
echo "Pyln VERSION: $VERSION"
uv build --package ${{ matrix.PACKAGE }}
uv publish --publish-url https://test.pypi.org/legacy/ --check-url https://test.pypi.org/simple/
- name: Publish distribution 📦 to PyPI
if: github.repository == 'ElementsProject/lightning' && steps.set-values.outputs.DISTLOCATION == 'prod'
env:
UV_PUBLISH_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
WORKDIR: ${{ matrix.WORKDIR }}
run: |
echo "UV VERSION PUBLISH: $(uv --version)"
echo "Pyln VERSION: $VERSION"
uv build --package ${{ matrix.PACKAGE }}
uv publish

67
.github/workflows/release-build.yml vendored Normal file
View file

@ -0,0 +1,67 @@
name: Release binaries build
on:
workflow_call:
inputs:
version:
type: string
required: true
skip_validation:
type: boolean
required: true
jobs:
releases:
name: Releases
runs-on: ubuntu-24.04
strategy:
fail-fast: false
matrix:
target:
- 'bin-Fedora'
- 'bin-Ubuntu-jammy'
- 'bin-Ubuntu-noble'
- 'bin-Ubuntu-resolute'
steps:
- name: Git checkout
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Build environment setup
run: |
distribution=$(echo ${{ matrix.target }} | cut -d'-' -f3)
sudo docker run --rm -v $(pwd):/build ubuntu:${distribution} bash -c "\
apt-get update && \
apt-get install -y debootstrap && \
debootstrap ${distribution} /build/${distribution}"
sudo tar -C ${distribution} -c . | docker import - ${distribution}
docker build -t cl-repro-${distribution} - < contrib/reprobuild/Dockerfile.${distribution}
if: contains(matrix.target, 'Ubuntu')
- name: Build release
run: |
if [[ "${{ inputs.skip_validation }}" == "true" ]]; then
tools/build-release.sh ${{ matrix.target }} --force-version "${{ inputs.version }}" --force-unclean --force-mtime "$(date +%Y-%m-%d)"
else
tools/build-release.sh ${{ matrix.target }}
fi
- name: Upload target artifacts
uses: actions/upload-artifact@v7
with:
path: release/
name: ${{ matrix.target }}
if-no-files-found: error
artifact:
name: Construct release artifact
needs: releases
runs-on: ubuntu-24.04
steps:
- name: Merge artifacts
uses: actions/upload-artifact/merge@v7
with:
name: c-lightning-${{ inputs.version }}
pattern: bin-*
delete-merged: true

69
.github/workflows/release-publish.yml vendored Normal file
View file

@ -0,0 +1,69 @@
name: Release publish
on:
workflow_call:
inputs:
version:
type: string
required: true
create_release:
type: boolean
required: true
jobs:
release:
name: Sign and prepare release draft
runs-on: ubuntu-24.04
steps:
- name: Git checkout
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Download artifact
uses: actions/download-artifact@v8
with:
name: c-lightning-${{ inputs.version }}
path: release/
- name: Import GPG keys
id: gpg
uses: crazy-max/ghaction-import-gpg@v7
with:
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
passphrase: ${{ secrets.GPG_PASSPHRASE }}
trust_level: 5
- name: Set default GPG key
run: echo "default-key ${{ steps.gpg.outputs.keyid }}" >> ~/.gnupg/gpg.conf
- name: Sign release
run: tools/build-release.sh --without-zip sign
- name: Upload signed artifact
uses: actions/upload-artifact@v7
with:
name: c-lightning-${{ inputs.version }}
overwrite: true
path: release/
- name: Determine release data
id: release_data
run: |
CHANGELOG_VERSION=${VERSION#v}
VERSION="${{ inputs.version }}"
CHANGELOG_VERSION=${VERSION#v}
CHANGELOG_TITLE=$(grep "## \[${CHANGELOG_VERSION}\]" CHANGELOG.md)
RELEASE_TITLE=$(echo $CHANGELOG_TITLE | cut -d'"' -f2)
echo "release_title=$RELEASE_TITLE" >> "$GITHUB_OUTPUT"
- name: Prepare release draft
if: ${{ github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && inputs.create_release) }}
uses: softprops/action-gh-release@v3
with:
name: "${{ inputs.version }} ${{ steps.release_data.outputs.release_title }}"
tag_name: ${{ inputs.version }}
draft: true
prerelease: contains(inputs.version, "-rc")
files: release/*
fail_on_unmatched_files: true

View file

@ -7,6 +7,7 @@ on:
- 'v[0-9]+.[0-9]+'
- 'v[0-9]+.[0-9]+.[0-9]+'
- 'v[0-9]+.[0-9]+[0-9a-z]+'
- 'v[0-9]+.[0-9]+.[0-9]+[0-9a-z]+'
workflow_dispatch:
inputs:
version:
@ -20,173 +21,91 @@ on:
description: Create a draft release
default: false
type: boolean
dh-repository-owner:
description: 'Dockerhub repository owner'
default: 'elementsproject'
platforms-to-build:
description: 'List of platforms to build'
default: 'linux/amd64,linux/arm64,linux/arm/v7'
push-latest:
description: 'Push the latest Docker tag'
type: boolean
default: false
dist-location:
description: 'PyPI distribution location'
type: choice
options:
- test
- prod
default: 'test'
jobs:
check:
name: Check
outputs:
version: ${{ steps.capture.outputs.version }}
check-version:
name: Verify release tag
uses: ./.github/workflows/check-release-tag.yml
with:
version: ${{ github.event.inputs.version }}
skip_validation: ${{ github.event.inputs.skip_validation == 'true' }}
docker-build:
name: Docker build
needs: check-version
uses: ./.github/workflows/docker-build.yml
with:
version: ${{ needs.check-version.outputs.version }}
dh-repository-owner: ${{ github.event.inputs.dh-repository-owner || 'elementsproject' }}
platforms-to-build: ${{ github.event.inputs.platforms-to-build || 'linux/amd64,linux/arm64,linux/arm/v7' }}
secrets: inherit
pypi-build:
name: PyPI build
needs: check-version
uses: ./.github/workflows/pypi-build.yml
with:
version: ${{ needs.check-version.outputs.version }}
secrets: inherit
release-build:
name: Release binaries build
needs: check-version
uses: ./.github/workflows/release-build.yml
with:
version: ${{ needs.check-version.outputs.version }}
skip_validation: ${{ github.event.inputs.skip_validation == 'true' }}
secrets: inherit
gate:
name: All builds succeeded
needs: [docker-build, pypi-build, release-build]
runs-on: ubuntu-24.04
steps:
- name: Git checkout
uses: actions/checkout@v6
with:
ref: ${{ github.ref }}
fetch-depth: 0
- run: echo "All three build paths succeeded — proceeding to publish."
- name: Determine version
run: |
if [[ "${{ github.event.inputs.version }}" != "" ]]; then
VERSION="${{ github.event.inputs.version }}"
elif [ "${{ github.ref_type }}" == "tag" ]; then
VERSION="${{ github.ref_name }}"
else
echo "No release version provided and no tag found."
exit 1
fi
echo "VERSION=$VERSION" >> "$GITHUB_ENV"
echo "Determined version: $VERSION"
docker-publish:
name: Docker publish
needs: [check-version, gate]
uses: ./.github/workflows/docker-publish.yml
with:
version: ${{ needs.check-version.outputs.version }}
dh-repository-owner: ${{ github.event.inputs.dh-repository-owner || 'elementsproject' }}
push-latest: ${{ github.event.inputs.push-latest }}
secrets: inherit
- name: Validate release
if: ${{ !(github.event_name == 'workflow_dispatch' && github.event.inputs.skip_validation) }}
run: tools/check-release.sh --version=${VERSION}
pypi-publish:
name: PyPI publish
needs: [check-version, gate]
uses: ./.github/workflows/pypi-publish.yml
with:
version: ${{ needs.check-version.outputs.version }}
dist-location: ${{ github.event.inputs.dist-location }}
secrets: inherit
- name: Catpure version output
id: capture
run: echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
releases:
name: Releases
needs: check
env:
version: ${{ needs.check.outputs.version }}
runs-on: ubuntu-24.04
strategy:
fail-fast: false # Let each build finish.
matrix:
target:
- 'bin-Fedora'
- 'bin-Ubuntu-jammy'
- 'bin-Ubuntu-noble'
- 'bin-Ubuntu-resolute'
steps:
- name: Git checkout
uses: actions/checkout@v6
with:
ref: ${{ github.ref }}
fetch-depth: 0
- name: Build environment setup
run: |
distribution=$(echo ${{ matrix.target }} | cut -d'-' -f3)
echo "Building base image for ${distribution}"
sudo docker run --rm -v $(pwd):/build ubuntu:${distribution} bash -c "\
apt-get update && \
apt-get install -y debootstrap && \
debootstrap ${distribution} /build/${distribution}"
sudo tar -C ${distribution} -c . | docker import - ${distribution}
# Build Docker image
docker build -t cl-repro-${distribution} - < contrib/reprobuild/Dockerfile.${distribution}
if: contains(matrix.target, 'Ubuntu')
- name: Build release
run: |
# Allow build release to execute if manually triggered for testing
if [[ "${{ github.event_name }}" == "workflow_dispatch" && "${{ github.event.inputs.skip_validation }}" == "true" ]]; then
tools/build-release.sh ${{ matrix.target }} --force-version "${{ env.version }}" --force-unclean --force-mtime "$(date +%Y-%m-%d)"
else
tools/build-release.sh ${{ matrix.target }}
fi
- name: Upload target artifacts
uses: actions/upload-artifact@v7
with:
path: release/
name: ${{ matrix.target }}
if-no-files-found: error
artifact:
name: Construct release artifact
needs:
- check
- releases
env:
version: ${{ needs.check.outputs.version }}
runs-on: ubuntu-24.04
steps:
- name: Merge artifacts
uses: actions/upload-artifact/merge@v7
with:
name: c-lightning-${{ env.version }}
pattern: bin-*
delete-merged: true
release:
name: Sign and prepare release draft
needs:
- check
- artifact
env:
version: ${{ needs.check.outputs.version }}
runs-on: ubuntu-24.04
steps:
- name: Git checkout
uses: actions/checkout@v6
with:
ref: ${{ github.ref }}
fetch-depth: 0
- name: Download artifact
uses: actions/download-artifact@v8
with:
name: c-lightning-${{ env.version }}
path: release/
- name: Import GPG keys
id: gpg
uses: crazy-max/ghaction-import-gpg@v7
with:
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
passphrase: ${{ secrets.GPG_PASSPHRASE }}
trust_level: 5
- name: Set default GPG key
run: echo "default-key ${{ steps.gpg.outputs.keyid }}" >> ~/.gnupg/gpg.conf
- name: Sign release
run: tools/build-release.sh --without-zip sign
- name: Upload signed artifact
uses: actions/upload-artifact@v7
with:
name: c-lightning-${{ env.version }}
overwrite: true
path: release/
- name: Determine release data
id: release_data
run: |
VERSION=${{ env.version }}
CHANGELOG_VERSION=${VERSION#v}
echo "CHANGELOG_VERSION=$CHANGELOG_VERSION"
echo "changelog_version=$CHANGELOG_VERSION" >> "$GITHUB_OUTPUT"
CHANGELOG_TITLE=$(grep "## \[${CHANGELOG_VERSION}\]" CHANGELOG.md)
echo "CHANGELOG_TITLE=$CHANGELOG_TITLE"
echo "changelog_title=$CHANGELOG_TITLE" >> "$GITHUB_OUTPUT"
RELEASE_TITLE=$(echo $CHANGELOG_TITLE | cut -d'"' -f2)
echo "RELEASE_TITLE=$RELEASE_TITLE"
echo "release_title=$RELEASE_TITLE" >> "$GITHUB_OUTPUT"
- name: Prepare release draft
if: ${{ github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && github.event.inputs.create_release) }}
uses: softprops/action-gh-release@v3
with:
name: "${{ env.version }} ${{ steps.release_data.outputs.release_title }}"
tag_name: ${{ env.version }}
draft: true
prerelease: contains(env.version, "-rc")
files: release/*
fail_on_unmatched_files: true
release-publish:
name: Release sign + draft
needs: [check-version, gate]
uses: ./.github/workflows/release-publish.yml
with:
version: ${{ needs.check-version.outputs.version }}
create_release: ${{ github.event.inputs.create_release == 'true' }}
secrets: inherit