mirror of
https://github.com/netbirdio/netbird.git
synced 2026-10-03 12:09:09 +02:00
* [infrastructure] Create the preflight artifacts directory before submitting * [infrastructure] Add a workflow to certify UBI images on demand Move the Red Hat certification job into redhat-certify.yml so it can be run by hand for any released version and component, or for all of them. release.yml calls it with component "all" on stable tags. Component IDs now come from REDHAT_CERT_ID_<COMPONENT> repository variables. With "all", components without a variable are skipped. * [infrastructure] Fail Red Hat certification on missing IDs or timeout Fail before certifying when a selected component's REDHAT_CERT_ID_* variable is missing, listing every missing variable. Filter the Pyxis poll by tag so older versions are found past the first page, and fail the job when both architectures are not certified within 10 minutes.
981 lines
42 KiB
YAML
981 lines
42 KiB
YAML
name: Release
|
|
|
|
on:
|
|
push:
|
|
tags:
|
|
- "v*"
|
|
branches:
|
|
- main
|
|
- "release-*"
|
|
pull_request:
|
|
|
|
env:
|
|
SIGN_PIPE_VER: "v0.1.8"
|
|
GORELEASER_VER: "v2.16.0"
|
|
PRODUCT_NAME: "NetBird"
|
|
COPYRIGHT: "NetBird GmbH"
|
|
flags: ""
|
|
SKIP_PUBLISH: "true"
|
|
SKIP_DOCKER_PUSH: "false"
|
|
|
|
concurrency:
|
|
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.head_ref || github.actor_id }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
release_freebsd_port:
|
|
name: "FreeBSD Port / Build & Test"
|
|
runs-on: ubuntu-22.04
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- name: Generate FreeBSD port diff
|
|
run: bash -x release_files/freebsd-port-diff.sh
|
|
|
|
- name: Generate FreeBSD port issue body
|
|
run: bash -x release_files/freebsd-port-issue-body.sh
|
|
|
|
- name: Check if diff was generated
|
|
id: check_diff
|
|
run: |
|
|
if ls netbird-*.diff 1> /dev/null 2>&1; then
|
|
echo "diff_exists=true" >> $GITHUB_OUTPUT
|
|
else
|
|
echo "diff_exists=false" >> $GITHUB_OUTPUT
|
|
echo "No diff file generated (port may already be up to date)"
|
|
fi
|
|
|
|
- name: Extract version
|
|
if: steps.check_diff.outputs.diff_exists == 'true'
|
|
id: version
|
|
run: |
|
|
VERSION=$(ls netbird-*.diff | sed 's/netbird-\(.*\)\.diff/\1/')
|
|
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
|
echo "Generated files for version: $VERSION"
|
|
cat netbird-*.diff
|
|
|
|
- name: Read Go version from go.mod
|
|
id: goversion
|
|
run: echo "version=$(awk '/^go / {print $2}' go.mod)" >> "$GITHUB_OUTPUT"
|
|
|
|
- name: Test FreeBSD port
|
|
if: steps.check_diff.outputs.diff_exists == 'true'
|
|
env:
|
|
GO_VERSION: ${{ steps.goversion.outputs.version }}
|
|
uses: vmactions/freebsd-vm@b84ab5559b5a1bb4b8ee2737d2506a16e1737636 # v1.4.8
|
|
with:
|
|
usesh: true
|
|
copyback: false
|
|
release: "15.1"
|
|
envs: "GO_VERSION"
|
|
prepare: |
|
|
# Install required packages
|
|
pkg install -y git curl portlint
|
|
|
|
# Install Go for building
|
|
GO_TARBALL="go${GO_VERSION}.freebsd-amd64.tar.gz"
|
|
GO_URL="https://go.dev/dl/$GO_TARBALL"
|
|
curl -LO "$GO_URL"
|
|
tar -C /usr/local -xzf "$GO_TARBALL"
|
|
|
|
# Clone ports tree (shallow, only what we need)
|
|
git clone --depth 1 --filter=blob:none https://git.FreeBSD.org/ports.git /usr/ports
|
|
cd /usr/ports
|
|
|
|
run: |
|
|
set -e -x
|
|
export PATH=$PATH:/usr/local/go/bin
|
|
|
|
# Find the diff file
|
|
echo "Finding diff file..."
|
|
DIFF_FILE=$(find $PWD -name "netbird-*.diff" -type f 2>/dev/null | head -1)
|
|
echo "Found: $DIFF_FILE"
|
|
|
|
if [[ -z "$DIFF_FILE" ]]; then
|
|
echo "ERROR: Could not find diff file"
|
|
find ~ -name "*.diff" -type f 2>/dev/null || true
|
|
exit 1
|
|
fi
|
|
|
|
# Apply the generated diff from /usr/ports (diff has a/security/netbird/... paths)
|
|
cd /usr/ports
|
|
patch -p1 -V none < "$DIFF_FILE"
|
|
|
|
# Show patched Makefile
|
|
version=$(cat security/netbird/Makefile | grep -E '^DISTVERSION=' | awk '{print $NF}')
|
|
|
|
cd /usr/ports/security/netbird
|
|
export BATCH=yes
|
|
make package
|
|
pkg add ./work/pkg/netbird-*.pkg
|
|
|
|
netbird version | grep "$version"
|
|
|
|
echo "FreeBSD port test completed successfully!"
|
|
|
|
- name: Upload FreeBSD port files
|
|
if: steps.check_diff.outputs.diff_exists == 'true'
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a #v7.0.1
|
|
with:
|
|
name: freebsd-port-files
|
|
path: |
|
|
./netbird-*-issue.txt
|
|
./netbird-*.diff
|
|
retention-days: 30
|
|
|
|
release:
|
|
runs-on: ubuntu-24.04-8-core
|
|
outputs:
|
|
release_artifact_url: ${{ steps.upload_release.outputs.artifact-url }}
|
|
linux_packages_artifact_url: ${{ steps.upload_linux_packages.outputs.artifact-url }}
|
|
windows_packages_artifact_url: ${{ steps.upload_windows_packages.outputs.artifact-url }}
|
|
macos_packages_artifact_url: ${{ steps.upload_macos_packages.outputs.artifact-url }}
|
|
ghcr_images: ${{ steps.tag_and_push_images.outputs.images_markdown }}
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
with:
|
|
fetch-depth: 0 # It is required for GoReleaser to work properly
|
|
persist-credentials: false
|
|
|
|
- name: Parse semver string
|
|
id: semver_parser
|
|
uses: netbirdio/shared-actions/actions/parse-semver@be5df6047383da2236e02243cceb857d8567c27e # v0.0.2
|
|
|
|
- name: Set snapshot flag
|
|
if: ${{ !startsWith(github.ref, 'refs/tags/v') }}
|
|
run: |
|
|
echo "flags=--snapshot" >> $GITHUB_ENV
|
|
|
|
- name: Set build vars
|
|
if: ${{ startsWith(github.ref, 'refs/tags/v') }}
|
|
run: |
|
|
if [[ "x-${{ steps.semver_parser.outputs.prerelease }}" == "x-" && "x-${{ github.repository }}" == "x-netbirdio/netbird" ]]; then
|
|
echo "x-${{ github.repository }}"
|
|
echo "x-${{ steps.semver_parser.outputs.prerelease }}"
|
|
echo "SKIP_PUBLISH=false" >> $GITHUB_ENV
|
|
else
|
|
echo "x-${{ github.repository }}"
|
|
echo "x-${{ steps.semver_parser.outputs.prerelease }}"
|
|
fi
|
|
|
|
if [[ "x-${{ github.repository }}" != "x-netbirdio/netbird" ]]; then
|
|
echo "SKIP_DOCKER_PUSH=true" >> $GITHUB_ENV
|
|
fi
|
|
|
|
- name: Set up Go
|
|
uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0
|
|
with:
|
|
go-version-file: "go.mod"
|
|
cache: false
|
|
- name: Cache Go modules
|
|
uses: actions/cache/restore@2c8a9bd7457de244a408f35966fab2fb45fda9c8 # v6.0.0
|
|
with:
|
|
path: |
|
|
~/go/pkg/mod
|
|
~/.cache/go-build
|
|
key: ${{ runner.os }}-go-releaser-${{ hashFiles('**/go.sum') }}
|
|
restore-keys: |
|
|
${{ runner.os }}-go-releaser-
|
|
- name: Install modules
|
|
run: go mod tidy
|
|
- name: run openapi generator
|
|
run: bash shared/management/http/api/generate.sh
|
|
- name: check git status
|
|
run: git --no-pager diff --exit-code
|
|
- name: Generate RPM changelog from git tags
|
|
# nfpm embeds changelog.yml into the RPM; Red Hat software certification
|
|
# requires a changelog. Generated, not committed (see .gitignore).
|
|
# chglog is a go.mod tool directive, so go.sum pins it and its deps.
|
|
run: bash release_files/rpm-changelog.sh
|
|
- name: Fill the RPM ISA provide version
|
|
# nfpm cannot emit rpmbuild's ISA provide and GoReleaser cannot template it.
|
|
run: bash release_files/rpm-provides.sh
|
|
- name: Set up Node.js
|
|
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
|
with:
|
|
node-version: '22'
|
|
- name: Install proxy web dependencies for license collection
|
|
# proxy/collect-licenses.sh reads the UI's license terms from node_modules.
|
|
working-directory: proxy/web
|
|
run: npm ci --ignore-scripts
|
|
- name: Set up QEMU
|
|
uses: docker/setup-qemu-action@06116385d9baf250c9f4dcb4858b16962ea869c3 #v4.1.0
|
|
- name: Set up Docker Buildx
|
|
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 #v4.1.0
|
|
- name: Login to Docker hub
|
|
if: github.event_name != 'pull_request'
|
|
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
|
|
with:
|
|
username: ${{ secrets.DOCKER_USER }}
|
|
password: ${{ secrets.DOCKER_TOKEN }}
|
|
- name: Log in to the GitHub container registry
|
|
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
|
|
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
|
|
with:
|
|
registry: ghcr.io
|
|
username: ${{ github.actor }}
|
|
password: ${{ secrets.CI_DOCKER_PUSH_GITHUB_TOKEN }}
|
|
- name: Install OS build dependencies
|
|
run: sudo apt update && sudo apt install -y -q gcc-arm-linux-gnueabihf gcc-aarch64-linux-gnu
|
|
|
|
- name: Decode GPG signing key
|
|
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
|
|
env:
|
|
GPG_RPM_PRIVATE_KEY: ${{ secrets.GPG_RPM_PRIVATE_KEY }}
|
|
run: |
|
|
echo "$GPG_RPM_PRIVATE_KEY" | base64 -d > /tmp/gpg-rpm-signing-key.asc
|
|
echo "GPG_RPM_KEY_FILE=/tmp/gpg-rpm-signing-key.asc" >> $GITHUB_ENV
|
|
|
|
- name: Install goversioninfo
|
|
run: go install github.com/josephspurrier/goversioninfo/cmd/goversioninfo@b66839b # v1.7.0
|
|
- name: Generate windows syso amd64
|
|
run: goversioninfo -icon client/ui/build/windows/icon.ico -manifest client/manifest.xml -product-name ${{ env.PRODUCT_NAME }} -copyright "${{ env.COPYRIGHT }}" -ver-major ${{ steps.semver_parser.outputs.major }} -ver-minor ${{ steps.semver_parser.outputs.minor }} -ver-patch ${{ steps.semver_parser.outputs.patch }} -ver-build 0 -file-version ${{ steps.semver_parser.outputs.fullversion }}.0 -product-version ${{ steps.semver_parser.outputs.fullversion }}.0 -o client/resources_windows_amd64.syso
|
|
- name: Generate windows syso arm64
|
|
run: goversioninfo -arm -64 -icon client/ui/build/windows/icon.ico -manifest client/manifest.xml -product-name ${{ env.PRODUCT_NAME }} -copyright "${{ env.COPYRIGHT }}" -ver-major ${{ steps.semver_parser.outputs.major }} -ver-minor ${{ steps.semver_parser.outputs.minor }} -ver-patch ${{ steps.semver_parser.outputs.patch }} -ver-build 0 -file-version ${{ steps.semver_parser.outputs.fullversion }}.0 -product-version ${{ steps.semver_parser.outputs.fullversion }}.0 -o client/resources_windows_arm64.syso
|
|
- name: Run GoReleaser
|
|
id: goreleaser
|
|
uses: goreleaser/goreleaser-action@5daf1e915a5f0af01ddbcd89a43b8061ff4f1a89 # v7.2.2
|
|
with:
|
|
version: ${{ env.GORELEASER_VER }}
|
|
args: release --config .goreleaser.generated.yaml --clean ${{ env.flags }}
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
HOMEBREW_TAP_GITHUB_TOKEN: ${{ secrets.HOMEBREW_TAP_GITHUB_TOKEN }}
|
|
UPLOAD_DEBIAN_SECRET: ${{ secrets.PKG_UPLOAD_SECRET }}
|
|
UPLOAD_YUM_SECRET: ${{ secrets.PKG_UPLOAD_SECRET }}
|
|
GPG_RPM_KEY_FILE: ${{ env.GPG_RPM_KEY_FILE }}
|
|
# One per nfpm id: GoReleaser looks the passphrase up as NFPM_<ID>_PASSPHRASE.
|
|
NFPM_NETBIRD_RPM_AMD64_PASSPHRASE: ${{ secrets.GPG_RPM_PASSPHRASE }}
|
|
NFPM_NETBIRD_RPM_ARM64_PASSPHRASE: ${{ secrets.GPG_RPM_PASSPHRASE }}
|
|
NFPM_NETBIRD_RPM_ARM_PASSPHRASE: ${{ secrets.GPG_RPM_PASSPHRASE }}
|
|
NFPM_NETBIRD_RPM_386_PASSPHRASE: ${{ secrets.GPG_RPM_PASSPHRASE }}
|
|
SKIP_PUBLISH: ${{ env.SKIP_PUBLISH }}
|
|
SKIP_DOCKER_PUSH: ${{ env.SKIP_DOCKER_PUSH }}
|
|
- name: Verify RPM signatures
|
|
run: |
|
|
docker run --rm -v $(pwd)/dist:/dist fedora:41 bash -c '
|
|
dnf install -y -q rpm-sign curl >/dev/null 2>&1
|
|
curl -sSL https://pkgs.netbird.io/yum/repodata/repomd.xml.key -o /tmp/rpm-pub.key
|
|
rpm --import /tmp/rpm-pub.key
|
|
echo "=== Verifying RPM signatures ==="
|
|
for rpm_file in /dist/*amd64*.rpm; do
|
|
[ -f "$rpm_file" ] || continue
|
|
echo "--- $(basename $rpm_file) ---"
|
|
rpm -K "$rpm_file"
|
|
done
|
|
'
|
|
- name: Clean up GPG key
|
|
if: always()
|
|
run: rm -f /tmp/gpg-rpm-signing-key.asc
|
|
- name: Tag and push images (amd64 only)
|
|
id: tag_and_push_images
|
|
if: |
|
|
(github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository) ||
|
|
(github.event_name == 'push' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release-')))
|
|
run: |
|
|
set -euo pipefail
|
|
|
|
# $GITHUB_REF / $GITHUB_EVENT_NAME are read from the runner
|
|
# environment rather than substituted into this script with the
|
|
# workflow expression syntax: branch names may legally contain
|
|
# $(…), and interpolating github.ref would execute it.
|
|
resolve_tags() {
|
|
if [[ "$GITHUB_EVENT_NAME" == "pull_request" ]]; then
|
|
echo "pr-${{ github.event.pull_request.number }}"
|
|
elif [[ "$GITHUB_REF" == "refs/heads/main" ]]; then
|
|
echo "main sha-$(git rev-parse --short HEAD)"
|
|
else
|
|
# Release branches get an immutable sha-* tag only — the floating
|
|
# "main" tag must never move from a release branch.
|
|
echo "sha-$(git rev-parse --short HEAD)"
|
|
fi
|
|
}
|
|
|
|
ghcr_package_url() {
|
|
local image="$1" package encoded_package
|
|
package="${image#ghcr.io/}"
|
|
package="${package#*/}"
|
|
package="${package%%:*}"
|
|
encoded_package="${package//\//%2F}"
|
|
echo "https://github.com/orgs/netbirdio/packages/container/package/${encoded_package}"
|
|
}
|
|
|
|
image_refs=()
|
|
|
|
tag_and_push() {
|
|
local src="$1" img_name tag dst variant=""
|
|
img_name="${src%%:*}"
|
|
# Variants share a repository with their default image, so keep
|
|
# their tag suffixes. Order matters: the first matching pattern wins.
|
|
case "$src" in
|
|
*-rootless-ubi-amd64) variant="-rootless-ubi" ;;
|
|
*-rootless-amd64) variant="-rootless" ;;
|
|
*-ubi-amd64) variant="-ubi" ;;
|
|
esac
|
|
for tag in $(resolve_tags); do
|
|
dst="${img_name}:${tag}${variant}"
|
|
echo "Tagging ${src} -> ${dst}"
|
|
docker tag "$src" "$dst"
|
|
docker push "$dst"
|
|
image_refs+=("$dst")
|
|
done
|
|
}
|
|
|
|
cat > /tmp/goreleaser-artifacts.json <<'JSON'
|
|
${{ steps.goreleaser.outputs.artifacts }}
|
|
JSON
|
|
|
|
# dockers_v2 artifacts have no top-level goarch field, so match the
|
|
# per-platform -amd64 tag suffix instead; it works for both the old
|
|
# dockers and the new dockers_v2 image naming.
|
|
mapfile -t src_images < <(
|
|
jq -r '.[] | select(.type == "Docker Image") | .name | select(startswith("ghcr.io/") and endswith("-amd64"))' /tmp/goreleaser-artifacts.json
|
|
)
|
|
|
|
for src in "${src_images[@]}"; do
|
|
tag_and_push "$src"
|
|
done
|
|
|
|
{
|
|
echo "images_markdown<<EOF"
|
|
if [[ ${#image_refs[@]} -eq 0 ]]; then
|
|
echo "_No GHCR images were pushed._"
|
|
else
|
|
printf '%s\n' "${image_refs[@]}" | sort -u | while read -r image; do
|
|
printf -- '- [`%s`](%s)\n' "$image" "$(ghcr_package_url "$image")"
|
|
done
|
|
fi
|
|
echo "EOF"
|
|
} >> "$GITHUB_OUTPUT"
|
|
- name: upload non tags for debug purposes
|
|
id: upload_release
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a #v7.0.1
|
|
with:
|
|
name: release
|
|
path: dist/
|
|
retention-days: 7
|
|
- name: upload linux packages
|
|
id: upload_linux_packages
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a #v7.0.1
|
|
with:
|
|
name: linux-packages
|
|
path: dist/netbird_linux**
|
|
retention-days: 7
|
|
- name: upload windows packages
|
|
id: upload_windows_packages
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a #v7.0.1
|
|
with:
|
|
name: windows-packages
|
|
path: dist/netbird_windows**
|
|
retention-days: 7
|
|
- name: upload macos packages
|
|
id: upload_macos_packages
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a #v7.0.1
|
|
with:
|
|
name: macos-packages
|
|
path: dist/netbird_darwin**
|
|
retention-days: 7
|
|
|
|
# Certify the UBI images in the Red Hat Ecosystem Catalog on stable tags.
|
|
# See redhat-certify.yml, which can also be run by hand for any released version.
|
|
redhat_certification:
|
|
name: "Red Hat"
|
|
needs: release
|
|
if: |
|
|
github.repository == 'netbirdio/netbird' &&
|
|
startsWith(github.ref, 'refs/tags/v') &&
|
|
!contains(github.ref_name, '-')
|
|
permissions:
|
|
contents: read
|
|
uses: ./.github/workflows/redhat-certify.yml
|
|
with:
|
|
component: all
|
|
version: ${{ github.ref_name }}
|
|
secrets:
|
|
PYXIS_API_TOKEN: ${{ secrets.PYXIS_API_TOKEN }}
|
|
|
|
release_ui:
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
release_ui_artifact_url: ${{ steps.upload_release_ui.outputs.artifact-url }}
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
with:
|
|
fetch-depth: 0 # It is required for GoReleaser to work properly
|
|
persist-credentials: false
|
|
|
|
- name: Parse semver string
|
|
id: semver_parser
|
|
uses: netbirdio/shared-actions/actions/parse-semver@be5df6047383da2236e02243cceb857d8567c27e # v0.0.2
|
|
|
|
- name: Set snapshot flag
|
|
if: ${{ !startsWith(github.ref, 'refs/tags/v') }}
|
|
run: |
|
|
echo "flags=--snapshot" >> $GITHUB_ENV
|
|
|
|
- name: Set build vars
|
|
if: ${{ startsWith(github.ref, 'refs/tags/v') }}
|
|
run: |
|
|
if [[ "x-${{ steps.semver_parser.outputs.prerelease }}" == "x-" && "x-${{ github.repository }}" == "x-netbirdio/netbird" ]]; then
|
|
echo "x-${{ github.repository }}"
|
|
echo "x-${{ steps.semver_parser.outputs.prerelease }}"
|
|
echo "SKIP_PUBLISH=false" >> $GITHUB_ENV
|
|
else
|
|
echo "x-${{ github.repository }}"
|
|
echo "x-${{ steps.semver_parser.outputs.prerelease }}"
|
|
fi
|
|
|
|
- name: Set up Go
|
|
uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0
|
|
with:
|
|
go-version-file: "go.mod"
|
|
cache: false
|
|
- name: Cache Go modules
|
|
uses: actions/cache@2c8a9bd7457de244a408f35966fab2fb45fda9c8 # v6.0.0
|
|
with:
|
|
path: |
|
|
~/go/pkg/mod
|
|
~/.cache/go-build
|
|
key: ${{ runner.os }}-ui-go-releaser-${{ hashFiles('**/go.sum') }}
|
|
restore-keys: |
|
|
${{ runner.os }}-ui-go-releaser-
|
|
|
|
- name: Install modules
|
|
run: go mod tidy
|
|
|
|
- name: check git status
|
|
run: git --no-pager diff --exit-code
|
|
|
|
- name: Set up Node.js
|
|
uses: actions/setup-node@v7
|
|
with:
|
|
node-version: '22'
|
|
|
|
- name: Set up pnpm
|
|
uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
|
|
with:
|
|
version: 11
|
|
|
|
- name: Install dependencies
|
|
run: sudo apt update && sudo apt install -y -q libgtk-4-dev libwebkitgtk-6.0-dev libsoup-3.0-dev gcc-mingw-w64-x86-64
|
|
|
|
- name: Decode GPG signing key
|
|
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
|
|
env:
|
|
GPG_RPM_PRIVATE_KEY: ${{ secrets.GPG_RPM_PRIVATE_KEY }}
|
|
run: |
|
|
echo "$GPG_RPM_PRIVATE_KEY" | base64 -d > /tmp/gpg-rpm-signing-key.asc
|
|
echo "GPG_RPM_KEY_FILE=/tmp/gpg-rpm-signing-key.asc" >> $GITHUB_ENV
|
|
|
|
- name: Install LLVM-MinGW for ARM64 cross-compilation
|
|
run: |
|
|
cd /tmp
|
|
wget -q https://github.com/mstorsjo/llvm-mingw/releases/download/20250709/llvm-mingw-20250709-ucrt-ubuntu-22.04-x86_64.tar.xz
|
|
echo "60cafae6474c7411174cff1d4ba21a8e46cadbaeb05a1bace306add301628337 llvm-mingw-20250709-ucrt-ubuntu-22.04-x86_64.tar.xz" | sha256sum -c
|
|
tar -xf llvm-mingw-20250709-ucrt-ubuntu-22.04-x86_64.tar.xz
|
|
echo "/tmp/llvm-mingw-20250709-ucrt-ubuntu-22.04-x86_64/bin" >> $GITHUB_PATH
|
|
- name: Install goversioninfo
|
|
run: go install github.com/josephspurrier/goversioninfo/cmd/goversioninfo@b66839b # v1.7.0
|
|
- name: Install wails3 CLI
|
|
# Version derived from go.mod so the binding generator always matches
|
|
# the wails runtime the binary links against.
|
|
run: |
|
|
WAILS_VERSION=$(go list -m -f '{{.Version}}' github.com/wailsapp/wails/v3)
|
|
go install github.com/wailsapp/wails/v3/cmd/wails3@$WAILS_VERSION
|
|
- name: Generate windows syso amd64
|
|
run: goversioninfo -64 -icon client/ui/build/windows/icon.ico -manifest client/ui/build/windows/wails.exe.manifest -product-name ${{ env.PRODUCT_NAME }}-"UI" -copyright "${{ env.COPYRIGHT }}" -ver-major ${{ steps.semver_parser.outputs.major }} -ver-minor ${{ steps.semver_parser.outputs.minor }} -ver-patch ${{ steps.semver_parser.outputs.patch }} -ver-build 0 -file-version ${{ steps.semver_parser.outputs.fullversion }}.0 -product-version ${{ steps.semver_parser.outputs.fullversion }}.0 -o client/ui/resources_windows_amd64.syso
|
|
- name: Generate windows syso arm64
|
|
run: goversioninfo -arm -64 -icon client/ui/build/windows/icon.ico -manifest client/ui/build/windows/wails.exe.manifest -product-name ${{ env.PRODUCT_NAME }}-"UI" -copyright "${{ env.COPYRIGHT }}" -ver-major ${{ steps.semver_parser.outputs.major }} -ver-minor ${{ steps.semver_parser.outputs.minor }} -ver-patch ${{ steps.semver_parser.outputs.patch }} -ver-build 0 -file-version ${{ steps.semver_parser.outputs.fullversion }}.0 -product-version ${{ steps.semver_parser.outputs.fullversion }}.0 -o client/ui/resources_windows_arm64.syso
|
|
|
|
- name: Run GoReleaser
|
|
uses: goreleaser/goreleaser-action@5daf1e915a5f0af01ddbcd89a43b8061ff4f1a89 # v7.2.2
|
|
with:
|
|
version: ${{ env.GORELEASER_VER }}
|
|
args: release --config .goreleaser_ui.yaml --clean ${{ env.flags }}
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
HOMEBREW_TAP_GITHUB_TOKEN: ${{ secrets.HOMEBREW_TAP_GITHUB_TOKEN }}
|
|
UPLOAD_DEBIAN_SECRET: ${{ secrets.PKG_UPLOAD_SECRET }}
|
|
UPLOAD_YUM_SECRET: ${{ secrets.PKG_UPLOAD_SECRET }}
|
|
GPG_RPM_KEY_FILE: ${{ env.GPG_RPM_KEY_FILE }}
|
|
NFPM_NETBIRD_UI_RPM_PASSPHRASE: ${{ secrets.GPG_RPM_PASSPHRASE }}
|
|
SKIP_PUBLISH: ${{ env.SKIP_PUBLISH }}
|
|
- name: Verify RPM signatures
|
|
run: |
|
|
docker run --rm -v $(pwd)/dist:/dist fedora:41 bash -c '
|
|
dnf install -y -q rpm-sign curl >/dev/null 2>&1
|
|
curl -sSL https://pkgs.netbird.io/yum/repodata/repomd.xml.key -o /tmp/rpm-pub.key
|
|
rpm --import /tmp/rpm-pub.key
|
|
echo "=== Verifying RPM signatures ==="
|
|
for rpm_file in /dist/*.rpm; do
|
|
[ -f "$rpm_file" ] || continue
|
|
echo "--- $(basename $rpm_file) ---"
|
|
rpm -K "$rpm_file"
|
|
done
|
|
'
|
|
- name: Clean up GPG key
|
|
if: always()
|
|
run: rm -f /tmp/gpg-rpm-signing-key.asc
|
|
- name: upload non tags for debug purposes
|
|
id: upload_release_ui
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a #v7.0.1
|
|
with:
|
|
name: release-ui
|
|
path: dist/
|
|
retention-days: 3
|
|
|
|
release_ui_gtk3:
|
|
# Legacy GTK3/WebKit2GTK 4.1 UI build for distros without WebKitGTK 6.0
|
|
# (Ubuntu 22.04, Debian 12, RHEL 9, Fedora <=39). Runs on ubuntu-22.04 so
|
|
# the binary links against the oldest supported glibc.
|
|
runs-on: ubuntu-22.04
|
|
outputs:
|
|
release_ui_gtk3_artifact_url: ${{ steps.upload_release_ui_gtk3.outputs.artifact-url }}
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
with:
|
|
fetch-depth: 0 # It is required for GoReleaser to work properly
|
|
persist-credentials: false
|
|
|
|
- name: Parse semver string
|
|
id: semver_parser
|
|
uses: netbirdio/shared-actions/actions/parse-semver@be5df6047383da2236e02243cceb857d8567c27e # v0.0.2
|
|
|
|
- name: Set snapshot flag
|
|
if: ${{ !startsWith(github.ref, 'refs/tags/v') }}
|
|
run: |
|
|
echo "flags=--snapshot" >> $GITHUB_ENV
|
|
|
|
- name: Set build vars
|
|
if: ${{ startsWith(github.ref, 'refs/tags/v') }}
|
|
run: |
|
|
if [[ "x-${{ steps.semver_parser.outputs.prerelease }}" == "x-" && "x-${{ github.repository }}" == "x-netbirdio/netbird" ]]; then
|
|
echo "x-${{ github.repository }}"
|
|
echo "x-${{ steps.semver_parser.outputs.prerelease }}"
|
|
echo "SKIP_PUBLISH=false" >> $GITHUB_ENV
|
|
else
|
|
echo "x-${{ github.repository }}"
|
|
echo "x-${{ steps.semver_parser.outputs.prerelease }}"
|
|
fi
|
|
|
|
- name: Set up Go
|
|
uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0
|
|
with:
|
|
go-version-file: "go.mod"
|
|
cache: false
|
|
- name: Cache Go modules
|
|
# Restore-only from the release_ui cache written by trusted runs; the
|
|
# module cache is identical (same go.sum) and stale build-cache
|
|
# entries just miss.
|
|
uses: actions/cache/restore@2c8a9bd7457de244a408f35966fab2fb45fda9c8 # v6.0.0
|
|
with:
|
|
path: |
|
|
~/go/pkg/mod
|
|
~/.cache/go-build
|
|
key: ${{ runner.os }}-ui-go-releaser-${{ hashFiles('**/go.sum') }}
|
|
restore-keys: |
|
|
${{ runner.os }}-ui-go-releaser-
|
|
|
|
- name: Install modules
|
|
run: go mod tidy
|
|
|
|
- name: check git status
|
|
run: git --no-pager diff --exit-code
|
|
|
|
- name: Set up Node.js
|
|
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
|
with:
|
|
node-version: '22'
|
|
|
|
- name: Set up pnpm
|
|
uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
|
|
with:
|
|
version: 11
|
|
|
|
- name: Install dependencies
|
|
run: sudo apt update && sudo apt install -y -q libgtk-3-dev libwebkit2gtk-4.1-dev
|
|
|
|
- name: Decode GPG signing key
|
|
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
|
|
env:
|
|
GPG_RPM_PRIVATE_KEY: ${{ secrets.GPG_RPM_PRIVATE_KEY }}
|
|
run: |
|
|
echo "$GPG_RPM_PRIVATE_KEY" | base64 -d > /tmp/gpg-rpm-signing-key.asc
|
|
echo "GPG_RPM_KEY_FILE=/tmp/gpg-rpm-signing-key.asc" >> $GITHUB_ENV
|
|
|
|
- name: Install wails3 CLI
|
|
# Version derived from go.mod so the binding generator always matches
|
|
# the wails runtime the binary links against.
|
|
# -tags gtk3: the CLI links the wails runtime's cgo packages, and the
|
|
# default tags request gtk4/webkitgtk-6.0 pkg-config entries that do
|
|
# not exist on ubuntu-22.04.
|
|
run: |
|
|
WAILS_VERSION=$(go list -m -f '{{.Version}}' github.com/wailsapp/wails/v3)
|
|
go install -tags gtk3 github.com/wailsapp/wails/v3/cmd/wails3@$WAILS_VERSION
|
|
|
|
- name: Run GoReleaser
|
|
uses: goreleaser/goreleaser-action@5daf1e915a5f0af01ddbcd89a43b8061ff4f1a89 # v7.2.2
|
|
with:
|
|
version: ${{ env.GORELEASER_VER }}
|
|
args: release --config .goreleaser_ui_gtk3.yaml --clean ${{ env.flags }}
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
UPLOAD_DEBIAN_SECRET: ${{ secrets.PKG_UPLOAD_SECRET }}
|
|
UPLOAD_YUM_SECRET: ${{ secrets.PKG_UPLOAD_SECRET }}
|
|
GPG_RPM_KEY_FILE: ${{ env.GPG_RPM_KEY_FILE }}
|
|
NFPM_NETBIRD_UI_RPM_GTK3_PASSPHRASE: ${{ secrets.GPG_RPM_PASSPHRASE }}
|
|
SKIP_PUBLISH: ${{ env.SKIP_PUBLISH }}
|
|
- name: Verify RPM signatures
|
|
run: |
|
|
docker run --rm -v $(pwd)/dist:/dist fedora:41 bash -c '
|
|
dnf install -y -q rpm-sign curl >/dev/null 2>&1
|
|
curl -sSL https://pkgs.netbird.io/yum/repodata/repomd.xml.key -o /tmp/rpm-pub.key
|
|
rpm --import /tmp/rpm-pub.key
|
|
echo "=== Verifying RPM signatures ==="
|
|
for rpm_file in /dist/*.rpm; do
|
|
[ -f "$rpm_file" ] || continue
|
|
echo "--- $(basename $rpm_file) ---"
|
|
rpm -K "$rpm_file"
|
|
done
|
|
'
|
|
- name: Clean up GPG key
|
|
if: always()
|
|
run: rm -f /tmp/gpg-rpm-signing-key.asc
|
|
- name: upload non tags for debug purposes
|
|
id: upload_release_ui_gtk3
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a #v7.0.1
|
|
with:
|
|
name: release-ui-gtk3
|
|
path: dist/
|
|
retention-days: 3
|
|
|
|
release_ui_darwin:
|
|
runs-on: macos-latest
|
|
outputs:
|
|
release_ui_darwin_artifact_url: ${{ steps.upload_release_ui_darwin.outputs.artifact-url }}
|
|
steps:
|
|
- if: ${{ !startsWith(github.ref, 'refs/tags/v') }}
|
|
run: echo "flags=--snapshot" >> $GITHUB_ENV
|
|
- name: Checkout
|
|
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
with:
|
|
fetch-depth: 0 # It is required for GoReleaser to work properly
|
|
persist-credentials: false
|
|
- name: Set up Go
|
|
uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0
|
|
with:
|
|
go-version-file: "go.mod"
|
|
cache: false
|
|
- name: Cache Go modules
|
|
uses: actions/cache@2c8a9bd7457de244a408f35966fab2fb45fda9c8 # v6.0.0
|
|
with:
|
|
path: |
|
|
~/go/pkg/mod
|
|
~/.cache/go-build
|
|
key: ${{ runner.os }}-ui-go-releaser-darwin-${{ hashFiles('**/go.sum') }}
|
|
restore-keys: |
|
|
${{ runner.os }}-ui-go-releaser-darwin-
|
|
- name: Install modules
|
|
run: go mod tidy
|
|
- name: check git status
|
|
run: git --no-pager diff --exit-code
|
|
- name: Set up Node.js
|
|
uses: actions/setup-node@v7
|
|
with:
|
|
node-version: '22'
|
|
- name: Set up pnpm
|
|
uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
|
|
with:
|
|
version: 11
|
|
- name: Install wails3 CLI
|
|
# Version derived from go.mod so the binding generator always matches
|
|
# the wails runtime the binary links against.
|
|
run: |
|
|
WAILS_VERSION=$(go list -m -f '{{.Version}}' github.com/wailsapp/wails/v3)
|
|
go install github.com/wailsapp/wails/v3/cmd/wails3@$WAILS_VERSION
|
|
- name: Run GoReleaser
|
|
id: goreleaser
|
|
uses: goreleaser/goreleaser-action@5daf1e915a5f0af01ddbcd89a43b8061ff4f1a89 # v7.2.2
|
|
with:
|
|
version: ${{ env.GORELEASER_VER }}
|
|
args: release --config .goreleaser_ui_darwin.yaml --clean ${{ env.flags }}
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
- name: upload non tags for debug purposes
|
|
id: upload_release_ui_darwin
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a #v7.0.1
|
|
with:
|
|
name: release-ui-darwin
|
|
path: dist/
|
|
retention-days: 3
|
|
|
|
test_windows_installer:
|
|
name: "Windows Installer / Build Test"
|
|
runs-on: windows-2022
|
|
needs: [release, release_ui]
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- arch: amd64
|
|
wintun_arch: amd64
|
|
- arch: arm64
|
|
wintun_arch: arm64
|
|
defaults:
|
|
run:
|
|
shell: powershell
|
|
env:
|
|
PackageWorkdir: netbird_windows_${{ matrix.arch }}
|
|
downloadPath: '${{ github.workspace }}\temp'
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- name: Parse semver string
|
|
id: semver_parser
|
|
uses: netbirdio/shared-actions/actions/parse-semver@be5df6047383da2236e02243cceb857d8567c27e # v0.0.2
|
|
|
|
- name: Add 7-Zip to PATH
|
|
run: echo "C:\Program Files\7-Zip" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
|
|
|
|
- name: Download release artifacts
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
name: release
|
|
path: release
|
|
|
|
- name: Download UI release artifacts
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
name: release-ui
|
|
path: release-ui
|
|
|
|
- name: Stage binaries into dist
|
|
run: |
|
|
$workdir = "dist\${{ env.PackageWorkdir }}"
|
|
New-Item -ItemType Directory -Force -Path $workdir | Out-Null
|
|
$client = Get-ChildItem -Recurse -Path release -Filter "netbird_*_windows_${{ matrix.arch }}.tar.gz" | Select-Object -First 1
|
|
$ui = Get-ChildItem -Recurse -Path release-ui -Filter "netbird-ui-windows_*_windows_${{ matrix.arch }}.tar.gz" | Select-Object -First 1
|
|
if (-not $client) { Write-Host "::error::client tarball not found for ${{ matrix.arch }}"; exit 1 }
|
|
if (-not $ui) { Write-Host "::error::ui tarball not found for ${{ matrix.arch }}"; exit 1 }
|
|
Write-Host "Client: $($client.FullName)"
|
|
Write-Host "UI: $($ui.FullName)"
|
|
tar -zvxf $client.FullName -C $workdir
|
|
tar -zvxf $ui.FullName -C $workdir
|
|
Get-ChildItem $workdir
|
|
|
|
- name: Download wintun
|
|
id: download-wintun
|
|
uses: netbirdio/shared-actions/actions/win-download-and-verify@be5df6047383da2236e02243cceb857d8567c27e # v0.0.2
|
|
with:
|
|
url: https://pkgs.netbird.io/wintun/wintun-0.14.1.zip
|
|
destination: ${{ env.downloadPath }}\wintun.zip
|
|
sha256: 07c256185d6ee3652e09fa55c0b673e2624b565e02c4b9091c79ca7d2f24ef51
|
|
|
|
- name: Decompress wintun files
|
|
run: tar -xvf "${{ env.downloadPath }}\wintun.zip" -C ${{ env.downloadPath }}
|
|
|
|
- name: Move wintun.dll into dist
|
|
run: mv ${{ env.downloadPath }}\wintun\bin\${{ matrix.wintun_arch }}\wintun.dll ${{ github.workspace }}\dist\${{ env.PackageWorkdir }}\
|
|
|
|
- name: Download EnVar plugin for NSIS
|
|
uses: netbirdio/shared-actions/actions/win-download-and-verify@be5df6047383da2236e02243cceb857d8567c27e # v0.0.2
|
|
with:
|
|
url: https://pkgs.netbird.io/nsis/EnVar_plugin.zip
|
|
destination: ${{ github.workspace }}\envar_plugin.zip
|
|
sha256: e9aa92de351345ed82795251d838f1ae9041ba35af9d381a5780c7843b01f56a
|
|
|
|
- name: Extract EnVar plugin
|
|
run: 7z x -o"${{ github.workspace }}/NSIS_Plugins" "${{ github.workspace }}/envar_plugin.zip"
|
|
|
|
- name: Download ShellExecAsUser plugin for NSIS (amd64 only)
|
|
if: matrix.arch == 'amd64'
|
|
uses: netbirdio/shared-actions/actions/win-download-and-verify@be5df6047383da2236e02243cceb857d8567c27e # v0.0.2
|
|
with:
|
|
url: https://pkgs.netbird.io/nsis/ShellExecAsUser_amd64-Unicode.7z
|
|
destination: ${{ github.workspace }}\ShellExecAsUser_amd64-Unicode.7z
|
|
sha256: 0a55ea25c7330a92cec028eda8afcaf1b1a7092e0dfb77c21c8f654564b4ff9d
|
|
|
|
- name: Extract ShellExecAsUser plugin (amd64 only)
|
|
if: matrix.arch == 'amd64'
|
|
run: 7z x -o"${{ github.workspace }}/NSIS_Plugins" "${{ github.workspace }}/ShellExecAsUser_amd64-Unicode.7z"
|
|
|
|
- name: Set up Go for wails3 CLI
|
|
uses: actions/setup-go@v6
|
|
with:
|
|
go-version-file: "go.mod"
|
|
cache: false
|
|
|
|
- name: Install wails3 CLI
|
|
# Version derived from go.mod so the bootstrapper payload always
|
|
# matches the wails runtime the binary links against.
|
|
shell: bash
|
|
run: |
|
|
WAILS_VERSION=$(go list -m -f '{{.Version}}' github.com/wailsapp/wails/v3)
|
|
go install github.com/wailsapp/wails/v3/cmd/wails3@$WAILS_VERSION
|
|
|
|
- name: Stage WebView2 bootstrapper for installers
|
|
# Both client/installer.nsis and client/netbird.wxs reference
|
|
# client/MicrosoftEdgeWebview2Setup.exe. wails3 writes it there.
|
|
# The signing pipeline (netbirdio/sign-pipelines) does the same
|
|
# step for release builds; this mirrors it for PR sanity testing.
|
|
shell: bash
|
|
run: wails3 generate webview2bootstrapper -dir client
|
|
|
|
- name: Build NSIS installer
|
|
shell: pwsh
|
|
env:
|
|
APPVER: ${{ steps.semver_parser.outputs.major }}.${{ steps.semver_parser.outputs.minor }}.${{ steps.semver_parser.outputs.patch }}.${{ github.run_id }}
|
|
run: |
|
|
$nsisPluginDir = "C:\Program Files (x86)\NSIS\Plugins\x86-unicode"
|
|
$srcPlugins = "${{ github.workspace }}\NSIS_Plugins\Plugins"
|
|
Get-ChildItem -Path $srcPlugins -Recurse -Filter *.dll |
|
|
Copy-Item -Destination $nsisPluginDir -Force
|
|
& "C:\Program Files (x86)\NSIS\makensis.exe" /V4 "/DARCH=${{ matrix.arch }}" client\installer.nsis
|
|
if ($LASTEXITCODE -ne 0) { throw "makensis failed with exit code $LASTEXITCODE" }
|
|
|
|
- name: Rename NSIS installer
|
|
run: mv netbird-installer.exe netbird_installer_test_windows_${{ matrix.arch }}.exe
|
|
|
|
- name: Install WiX
|
|
run: |
|
|
dotnet tool install --global wix --version 6.0.2
|
|
wix extension add WixToolset.Util.wixext/6.0.2
|
|
|
|
- name: Build MSI installer
|
|
env:
|
|
NETBIRD_VERSION: "${{ steps.semver_parser.outputs.fullversion }}"
|
|
run: wix build -arch ${{ matrix.arch == 'amd64' && 'x64' || 'arm64' }} -ext WixToolset.Util.wixext -o netbird_installer_test_windows_${{ matrix.arch }}.msi .\client\netbird.wxs -d ProcessorArchitecture=${{ matrix.arch == 'amd64' && 'x64' || 'arm64' }} -d ArchSuffix=${{ matrix.arch }}
|
|
|
|
- name: Upload installer artifacts
|
|
if: always()
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a #v7.0.1
|
|
with:
|
|
name: windows-installer-test-${{ matrix.arch }}
|
|
path: |
|
|
netbird_installer_test_windows_${{ matrix.arch }}.exe
|
|
netbird_installer_test_windows_${{ matrix.arch }}.msi
|
|
retention-days: 3
|
|
|
|
comment_release_artifacts:
|
|
name: Comment release artifacts
|
|
runs-on: ubuntu-latest
|
|
needs: [release, release_ui, release_ui_gtk3, release_ui_darwin]
|
|
if: ${{ always() && github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository }}
|
|
permissions:
|
|
contents: read
|
|
issues: write
|
|
pull-requests: write
|
|
steps:
|
|
- name: Create or update PR comment
|
|
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
|
env:
|
|
RELEASE_RESULT: ${{ needs.release.result }}
|
|
RELEASE_UI_RESULT: ${{ needs.release_ui.result }}
|
|
RELEASE_UI_GTK3_RESULT: ${{ needs.release_ui_gtk3.result }}
|
|
RELEASE_UI_DARWIN_RESULT: ${{ needs.release_ui_darwin.result }}
|
|
RELEASE_ARTIFACT_URL: ${{ needs.release.outputs.release_artifact_url }}
|
|
LINUX_PACKAGES_ARTIFACT_URL: ${{ needs.release.outputs.linux_packages_artifact_url }}
|
|
WINDOWS_PACKAGES_ARTIFACT_URL: ${{ needs.release.outputs.windows_packages_artifact_url }}
|
|
MACOS_PACKAGES_ARTIFACT_URL: ${{ needs.release.outputs.macos_packages_artifact_url }}
|
|
RELEASE_UI_ARTIFACT_URL: ${{ needs.release_ui.outputs.release_ui_artifact_url }}
|
|
RELEASE_UI_GTK3_ARTIFACT_URL: ${{ needs.release_ui_gtk3.outputs.release_ui_gtk3_artifact_url }}
|
|
RELEASE_UI_DARWIN_ARTIFACT_URL: ${{ needs.release_ui_darwin.outputs.release_ui_darwin_artifact_url }}
|
|
GHCR_IMAGES_MARKDOWN: ${{ needs.release.outputs.ghcr_images }}
|
|
with:
|
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
script: |
|
|
const marker = '<!-- netbird-release-artifacts -->';
|
|
const { owner, repo } = context.repo;
|
|
const issue_number = context.payload.pull_request.number;
|
|
const runUrl = `${context.serverUrl}/${owner}/${repo}/actions/runs/${context.runId}`;
|
|
const shortSha = context.payload.pull_request.head.sha.slice(0, 7);
|
|
|
|
const artifactCell = (url, result) => {
|
|
if (url) return `[Download](${url})`;
|
|
return result && result !== 'success' ? `_Not available (${result})_` : '_Not available_';
|
|
};
|
|
|
|
const artifacts = [
|
|
['All release artifacts', process.env.RELEASE_ARTIFACT_URL, process.env.RELEASE_RESULT],
|
|
['Linux packages', process.env.LINUX_PACKAGES_ARTIFACT_URL, process.env.RELEASE_RESULT],
|
|
['Windows packages', process.env.WINDOWS_PACKAGES_ARTIFACT_URL, process.env.RELEASE_RESULT],
|
|
['macOS packages', process.env.MACOS_PACKAGES_ARTIFACT_URL, process.env.RELEASE_RESULT],
|
|
['UI artifacts', process.env.RELEASE_UI_ARTIFACT_URL, process.env.RELEASE_UI_RESULT],
|
|
['UI GTK3 artifacts', process.env.RELEASE_UI_GTK3_ARTIFACT_URL, process.env.RELEASE_UI_GTK3_RESULT],
|
|
['UI macOS artifacts', process.env.RELEASE_UI_DARWIN_ARTIFACT_URL, process.env.RELEASE_UI_DARWIN_RESULT],
|
|
];
|
|
|
|
const artifactRows = artifacts
|
|
.map(([name, url, result]) => `| ${name} | ${artifactCell(url, result)} |`)
|
|
.join('\n');
|
|
|
|
const ghcrImages = (process.env.GHCR_IMAGES_MARKDOWN || '').trim() || '_No GHCR images were pushed._';
|
|
|
|
const body = [
|
|
marker,
|
|
'## Release artifacts',
|
|
'',
|
|
`Built for PR head \`${shortSha}\` in [workflow run #${process.env.GITHUB_RUN_NUMBER}](${runUrl}).`,
|
|
'',
|
|
'| Artifact | Link |',
|
|
'| --- | --- |',
|
|
artifactRows,
|
|
'',
|
|
'### GHCR images (amd64)',
|
|
ghcrImages,
|
|
'',
|
|
'_This comment is updated by the Release workflow. Artifact links expire according to the workflow retention policy._',
|
|
].join('\n');
|
|
|
|
const comments = await github.paginate(github.rest.issues.listComments, {
|
|
owner,
|
|
repo,
|
|
issue_number,
|
|
per_page: 100,
|
|
});
|
|
|
|
const previous = comments.find(comment =>
|
|
comment.user?.type === 'Bot' && comment.body?.includes(marker)
|
|
);
|
|
|
|
if (previous) {
|
|
await github.rest.issues.updateComment({
|
|
owner,
|
|
repo,
|
|
comment_id: previous.id,
|
|
body,
|
|
});
|
|
core.info(`Updated release artifacts comment ${previous.id}`);
|
|
} else {
|
|
const { data } = await github.rest.issues.createComment({
|
|
owner,
|
|
repo,
|
|
issue_number,
|
|
body,
|
|
});
|
|
core.info(`Created release artifacts comment ${data.id}`);
|
|
}
|
|
|
|
trigger_signer:
|
|
runs-on: ubuntu-latest
|
|
needs: [release, release_ui, release_ui_gtk3, release_ui_darwin, test_windows_installer]
|
|
if: startsWith(github.ref, 'refs/tags/')
|
|
steps:
|
|
- name: Trigger binaries sign pipelines
|
|
uses: benc-uk/workflow-dispatch@31e2b3319479a63f0ab15bf800eff9e913504e26 # v1.3.2
|
|
with:
|
|
workflow: Sign bin and installer
|
|
repo: netbirdio/sign-pipelines
|
|
ref: ${{ env.SIGN_PIPE_VER }}
|
|
token: ${{ secrets.SIGN_GITHUB_TOKEN }}
|
|
inputs: '{ "tag": "${{ github.ref }}", "skipRelease": false }'
|