Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
065342a
[ci] Add GPG-signed DEB packages (containerized)
PlatCore Apr 6, 2026
9e865ae
[ci] Use sudo for root-owned build artifact cleanup in DEB workflow
PlatCore Apr 6, 2026
c75d09f
Rewrite build-deb.sh to use lib-build-common.sh
PlatCore Apr 6, 2026
baaabbf
Update validate-deb.sh to use shared smoke-test.sh
PlatCore Apr 6, 2026
035cec3
Add lib-build-deb.sh, remove build-deb.sh
PlatCore Apr 7, 2026
c3196e3
Update validate-deb.sh to use shared validation helpers
PlatCore Apr 7, 2026
d2e9d21
Update DEB tasks and workflow to use shared infrastructure
PlatCore Apr 7, 2026
e904e9c
Make new packaging scripts executable
PlatCore Apr 7, 2026
f16cadf
Fix script injection in setup-packaging and add DEB dependencies
PlatCore Apr 7, 2026
b1b9b6e
Add setup-packaging path trigger to packaging workflow PR filters
PlatCore Apr 7, 2026
87b031d
[ci] Fix DEB workflow: use task for setup, add packaging overlay
PlatCore Apr 13, 2026
34df389
[ci] Fix DEB workflow: call workflow-setup-packaging.sh directly
PlatCore Apr 16, 2026
2ebc79e
docs: add DEB packaging design note
PlatCore Apr 30, 2026
433085f
Add DEB dispatcher hooks to build-package.sh and detect_host_arch
PlatCore May 5, 2026
bf8d230
Use ${BINARY_PATH} in DEB nfpm templates
PlatCore May 14, 2026
6b29686
Use ubuntu-22.04-arm runner for arm64 DEB build
PlatCore May 14, 2026
40fa72a
Switch DEB signing to nfpm-native; drop dpkg-sig
PlatCore May 14, 2026
dace995
Clean-up release workflow
PlatCore May 15, 2026
a34805a
Deduplicate format-specific build tasks via shared build-package task
PlatCore May 15, 2026
3dc2bf6
Forward VERSION and TAG via env
PlatCore May 15, 2026
55ed429
Rename packaging vars for consistent format prefix
PlatCore May 15, 2026
5f17525
Consolidate RPM/DEB design docs into linux-packaging.md
PlatCore May 15, 2026
9af0a87
Drop stale packaging path filter from workflows
PlatCore May 15, 2026
14f763e
Document passphrased ephemeral package signing
PlatCore May 19, 2026
8c997e6
Remove unnecessary nfpm expansion
PlatCore May 19, 2026
429b486
Avoid shell interpolation in DEB S3 upload
PlatCore May 19, 2026
114b350
Collapse {RPM,DEB}_GPG_KEY_FILE into single GPG_KEY_FILE
PlatCore May 20, 2026
6822dd5
Rename build-builder-docker-image to build-rpm-builder-docker-image
PlatCore May 20, 2026
c9be4e5
Default GPG_KEY_FILE before testing it
PlatCore May 20, 2026
c8da318
Fix stale .PACKAGING_HOST_ARCH ref in validate-rpms
PlatCore May 20, 2026
dc37562
Align RPM key consumers with RPM-GPG-KEY-avalanchego filename
PlatCore May 20, 2026
e9ce4ef
Move DEB S3 upload to a release-only job without OIDC on PR builds
PlatCore May 20, 2026
bbe2c5b
Discard stdout while sourcing subnet-evm constants.sh
PlatCore May 20, 2026
59954a3
Update validate-deb.sh to smoke-test.sh's 3-arg contract
PlatCore May 22, 2026
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
59 changes: 59 additions & 0 deletions .github/packaging/Dockerfile.deb
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Build container for DEB packaging of avalanchego and subnet-evm.
#
# Based on Ubuntu 22.04 (jammy) so the produced binary's glibc floor
# matches the oldest supported target release. Source tree is bind-mounted
# at runtime, not COPY'd.
#
# Usage (via build-builder-image.sh with DOCKERFILE=Dockerfile.deb):
# DOCKERFILE=Dockerfile.deb .github/packaging/scripts/build-builder-image.sh
# docker run --rm -v .:/build -v ./build/deb:/output avalanchego-deb-builder ...

FROM ubuntu:22.04

ARG GO_VERSION=INVALID
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned previously, only ARGs defined outside a FROM block require INVALID to silence a docker warning.

ARG GO_CHECKSUM=INVALID
ARG TARGETARCH

ENV DEBIAN_FRONTEND=noninteractive

# Install build dependencies
# - gcc: required for cgo (CGO_ENABLED=1 in scripts/constants.sh)
# - gettext: envsubst for nfpm config template expansion
# - gnupg: GPG key import for nfpm-native DEB signing
# - git: version detection in build scripts
# - curl: downloading Go and nfpm
RUN apt-get update && apt-get install -y \
gcc \
gettext \
gnupg \
git \
curl \
&& rm -rf /var/lib/apt/lists/*

# Install Go (with SHA256 verification)
RUN curl -fsSL -o /tmp/go.tar.gz \
"https://go.dev/dl/go${GO_VERSION}.linux-${TARGETARCH}.tar.gz" \
&& echo "${GO_CHECKSUM} /tmp/go.tar.gz" | sha256sum -c - \
&& tar -C /usr/local -xzf /tmp/go.tar.gz \
&& rm /tmp/go.tar.gz
ENV PATH="/usr/local/go/bin:${PATH}"

# Install nfpm (with SHA256 verification via checksums.txt)
ARG NFPM_VERSION=2.41.1
# nfpm releases use x86_64 and arm64 (not aarch64)
RUN case "${TARGETARCH}" in \
amd64) NFPM_ARCH="x86_64" ;; \
arm64) NFPM_ARCH="arm64" ;; \
*) echo "Unsupported arch: ${TARGETARCH}" && exit 1 ;; \
esac && \
NFPM_TARBALL="nfpm_${NFPM_VERSION}_Linux_${NFPM_ARCH}.tar.gz" && \
curl -fsSL -o /tmp/nfpm.tar.gz \
"https://github.com/goreleaser/nfpm/releases/download/v${NFPM_VERSION}/${NFPM_TARBALL}" && \
curl -fsSL -o /tmp/checksums.txt \
"https://github.com/goreleaser/nfpm/releases/download/v${NFPM_VERSION}/checksums.txt" && \
EXPECTED=$(grep " ${NFPM_TARBALL}$" /tmp/checksums.txt | awk '{print $1}') && \
echo "${EXPECTED} /tmp/nfpm.tar.gz" | sha256sum -c - && \
tar -C /usr/local/bin -xzf /tmp/nfpm.tar.gz nfpm && \
rm /tmp/nfpm.tar.gz /tmp/checksums.txt

WORKDIR /build
168 changes: 126 additions & 42 deletions .github/packaging/Taskfile.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# RPM packaging tasks for avalanchego and subnet-evm.
# Packaging tasks for avalanchego and subnet-evm (RPM and DEB).
#
# Builds RPMs inside a Rocky Linux 9 container (glibc 2.34) with GPG signing.
# RPMs are built inside a Rocky Linux 9 container (glibc 2.34).
# DEBs are built inside an Ubuntu 22.04 container (glibc 2.35).
# Both formats are signed inline by nfpm.
# PACKAGING_TAG defaults to v0.0.0 for local testing; set for release builds.

version: '3'
Expand All @@ -14,7 +16,7 @@ vars:
PACKAGING_GO_VERSION:
sh: go list -m -f '{{ "{{.GoVersion}}" }}' | head -1
# Map uname -m to RPM arch names (arm64 -> aarch64).
PACKAGING_HOST_ARCH:
PACKAGING_RPM_HOST_ARCH:
sh: |
arch=$(uname -m)
case "${arch}" in
Expand All @@ -28,8 +30,19 @@ vars:
# Default tag for local testing; overridden by CI for release builds.
PACKAGING_TAG:
sh: echo "${PACKAGING_TAG:-v0.0.0}"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is it necessary to use sh here?

PACKAGING_DOCKER_IMAGE: avalanchego-rpm-builder
PACKAGING_OUTPUT_DIR: '{{.REPO_ROOT}}/build/rpm'
# Map uname -m to DEB arch names (x86_64 -> amd64).
PACKAGING_DEB_HOST_ARCH:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe put this right after the RPM equivalent for consistency?

sh: |
arch=$(uname -m)
case "${arch}" in
x86_64) echo "amd64" ;;
aarch64|arm64) echo "arm64" ;;
*) echo "${arch}" ;;
esac
PACKAGING_RPM_DOCKER_IMAGE: avalanchego-rpm-builder
PACKAGING_DEB_DOCKER_IMAGE: avalanchego-deb-builder
PACKAGING_RPM_OUTPUT_DIR: '{{.REPO_ROOT}}/build/rpm'
PACKAGING_DEB_OUTPUT_DIR: '{{.REPO_ROOT}}/build/deb'

tasks:
default:
Expand All @@ -43,70 +56,76 @@ tasks:
- task: build-avalanchego-rpm
- task: build-subnet-evm-rpm

build-builder-docker-image:
build-rpm-builder-docker-image:
desc: Builds the RPM builder Docker image
internal: true
env:
GO_VERSION: '{{.PACKAGING_GO_VERSION}}'
DOCKER_IMAGE: '{{.PACKAGING_DOCKER_IMAGE}}'
DOCKER_IMAGE: '{{.PACKAGING_RPM_DOCKER_IMAGE}}'
CONTEXT_DIR: '{{.REPO_ROOT}}/.github/packaging'
DOCKERFILE: Dockerfile.rpm
cmds:
- cmd: '{{.REPO_ROOT}}/.github/packaging/scripts/build-builder-image.sh'

build-avalanchego-rpm:
desc: Builds RPM for avalanchego
build-package:
desc: Builds a package in the supplied builder Docker image
internal: true
vars:
PACKAGE_ARCH: '{{.PACKAGE_ARCH | default .PACKAGING_HOST_ARCH}}'
RPM_TAG: '{{.PACKAGING_TAG}}'
PASSPHRASE_ENV: 'NFPM_{{.NFPM_PACKAGER | upper}}_PASSPHRASE'
env:
GPG_KEY_PASSPHRASE: '{{.GPG_KEY_PASSPHRASE}}'
deps: [build-builder-docker-image]
VERSION: '{{trimPrefix "v" .TAG}}'
TAG: '{{.TAG}}'
cmds:
- cmd: mkdir -p {{.PACKAGING_OUTPUT_DIR}}
- cmd: mkdir -p {{.OUTPUT_DIR}}
- cmd: >-
docker run --rm
-v {{.REPO_ROOT}}:/build
-v {{.PACKAGING_OUTPUT_DIR}}:/output
-v {{.OUTPUT_DIR}}:/output
{{if .GPG_KEY_FILE}}-v {{.GPG_KEY_FILE}}:{{.GPG_KEY_FILE}}:ro{{end}}
-e PKG_FORMAT=RPM
-e PACKAGE=avalanchego
-e VERSION={{trimPrefix "v" .RPM_TAG}}
-e TAG={{.RPM_TAG}}
-e NFPM_PACKAGER={{.NFPM_PACKAGER}}
-e PACKAGE={{.PACKAGE}}
-e VERSION
-e TAG
-e PACKAGE_ARCH={{.PACKAGE_ARCH}}
-e OUTPUT_DIR=/output
-e AVALANCHEGO_COMMIT={{.PACKAGING_GIT_COMMIT}}
{{if .GPG_KEY_FILE}}-e GPG_KEY_FILE={{.GPG_KEY_FILE}}{{end}}
{{if .GPG_KEY_PASSPHRASE}}-e GPG_KEY_PASSPHRASE{{end}}
{{.PACKAGING_DOCKER_IMAGE}}
{{.DOCKER_IMAGE}}
.github/packaging/scripts/build-package.sh

build-avalanchego-rpm:
desc: Builds RPM for avalanchego
vars:
PACKAGE_ARCH: '{{.PACKAGE_ARCH | default .RPM_ARCH | default .PACKAGING_RPM_HOST_ARCH}}'
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is .RPM_ARCH defined?

deps: [build-rpm-builder-docker-image]
cmds:
- task: build-package
vars:
PACKAGE: avalanchego
NFPM_PACKAGER: rpm
TAG: '{{.PACKAGING_TAG}}'
PACKAGE_ARCH: '{{.PACKAGE_ARCH}}'
OUTPUT_DIR: '{{.PACKAGING_RPM_OUTPUT_DIR}}'
DOCKER_IMAGE: '{{.PACKAGING_RPM_DOCKER_IMAGE}}'
GPG_KEY_FILE: '{{.GPG_KEY_FILE | default ""}}'

build-subnet-evm-rpm:
desc: Builds RPM for subnet-evm
vars:
PACKAGE_ARCH: '{{.PACKAGE_ARCH | default .PACKAGING_HOST_ARCH}}'
RPM_TAG: '{{.PACKAGING_TAG}}'
env:
GPG_KEY_PASSPHRASE: '{{.GPG_KEY_PASSPHRASE}}'
deps: [build-builder-docker-image]
PACKAGE_ARCH: '{{.PACKAGE_ARCH | default .RPM_ARCH | default .PACKAGING_RPM_HOST_ARCH}}'
deps: [build-rpm-builder-docker-image]
cmds:
- cmd: mkdir -p {{.PACKAGING_OUTPUT_DIR}}
- cmd: >-
docker run --rm
-v {{.REPO_ROOT}}:/build
-v {{.PACKAGING_OUTPUT_DIR}}:/output
{{if .GPG_KEY_FILE}}-v {{.GPG_KEY_FILE}}:{{.GPG_KEY_FILE}}:ro{{end}}
-e PKG_FORMAT=RPM
-e PACKAGE=subnet-evm
-e VERSION={{trimPrefix "v" .RPM_TAG}}
-e TAG={{.RPM_TAG}}
-e PACKAGE_ARCH={{.PACKAGE_ARCH}}
-e OUTPUT_DIR=/output
-e AVALANCHEGO_COMMIT={{.PACKAGING_GIT_COMMIT}}
{{if .GPG_KEY_FILE}}-e GPG_KEY_FILE={{.GPG_KEY_FILE}}{{end}}
{{if .GPG_KEY_PASSPHRASE}}-e GPG_KEY_PASSPHRASE{{end}}
{{.PACKAGING_DOCKER_IMAGE}}
.github/packaging/scripts/build-package.sh
- task: build-package
vars:
PACKAGE: subnet-evm
NFPM_PACKAGER: rpm
TAG: '{{.PACKAGING_TAG}}'
PACKAGE_ARCH: '{{.PACKAGE_ARCH}}'
OUTPUT_DIR: '{{.PACKAGING_RPM_OUTPUT_DIR}}'
DOCKER_IMAGE: '{{.PACKAGING_RPM_DOCKER_IMAGE}}'
GPG_KEY_FILE: '{{.GPG_KEY_FILE | default ""}}'

test-build-rpms:
desc: Builds and validates RPMs end-to-end
Expand All @@ -119,6 +138,71 @@ tasks:
env:
TAG: '{{.PACKAGING_TAG}}'
GIT_COMMIT: '{{.PACKAGING_GIT_COMMIT}}'
PACKAGE_ARCH: '{{.PACKAGE_ARCH | default .PACKAGING_HOST_ARCH}}'
PACKAGE_ARCH: '{{.PACKAGE_ARCH | default .PACKAGING_RPM_HOST_ARCH}}'
cmds:
- cmd: '{{.REPO_ROOT}}/.github/packaging/scripts/validate-rpm.sh'

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thoughts on being consistent with other taskfiles in keeping tasks in sorted order? While there is some merit to the partitioning proposed here, I think it may be advantageous to make it easy to eyeball the implementations of a given task for each type of packaging to enable spotting obvious inconsistencies.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't appear to have been addressed.

# ── DEB packaging tasks ──────────────────────────────────────────

build-debs:
desc: Builds DEBs for both avalanchego and subnet-evm
cmds:
- task: build-avalanchego-deb
- task: build-subnet-evm-deb

build-deb-builder-docker-image:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does this task include the package type but the rpm equivalent does not?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 56c8c20

Renamed build-builder-docker-imagebuild-rpm-builder-docker-image so every format-specific task carries the same {rpm,deb} prefix. The internal generic task build-package stays format-agnostic.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe be consistent in using a package-type suffix (e.g. -deb or -rpm) so that the tasks order consistently when sorted?

desc: Builds the DEB builder Docker image
internal: true
env:
GO_VERSION: '{{.PACKAGING_GO_VERSION}}'
DOCKER_IMAGE: '{{.PACKAGING_DEB_DOCKER_IMAGE}}'
CONTEXT_DIR: '{{.REPO_ROOT}}/.github/packaging'
DOCKERFILE: Dockerfile.deb
cmds:
- cmd: '{{.REPO_ROOT}}/.github/packaging/scripts/build-builder-image.sh'

build-avalanchego-deb:
desc: Builds DEB for avalanchego
vars:
PACKAGE_ARCH: '{{.PACKAGE_ARCH | default .DEB_ARCH | default .PACKAGING_DEB_HOST_ARCH}}'
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is DEB_ARCH defined?

deps: [build-deb-builder-docker-image]
cmds:
- task: build-package
vars:
PACKAGE: avalanchego
NFPM_PACKAGER: deb
TAG: '{{.PACKAGING_TAG}}'
PACKAGE_ARCH: '{{.PACKAGE_ARCH}}'
OUTPUT_DIR: '{{.PACKAGING_DEB_OUTPUT_DIR}}'
DOCKER_IMAGE: '{{.PACKAGING_DEB_DOCKER_IMAGE}}'
GPG_KEY_FILE: '{{.GPG_KEY_FILE | default ""}}'

build-subnet-evm-deb:
desc: Builds DEB for subnet-evm
vars:
PACKAGE_ARCH: '{{.PACKAGE_ARCH | default .DEB_ARCH | default .PACKAGING_DEB_HOST_ARCH}}'
deps: [build-deb-builder-docker-image]
cmds:
- task: build-package
vars:
PACKAGE: subnet-evm
NFPM_PACKAGER: deb
TAG: '{{.PACKAGING_TAG}}'
PACKAGE_ARCH: '{{.PACKAGE_ARCH}}'
OUTPUT_DIR: '{{.PACKAGING_DEB_OUTPUT_DIR}}'
DOCKER_IMAGE: '{{.PACKAGING_DEB_DOCKER_IMAGE}}'
GPG_KEY_FILE: '{{.GPG_KEY_FILE | default ""}}'

test-build-debs:
desc: Builds and validates DEBs end-to-end
cmds:
- task: build-debs
- task: validate-debs

validate-debs:
desc: Validates built DEBs by installing and smoke testing in fresh containers
env:
TAG: '{{.PACKAGING_TAG}}'
GIT_COMMIT: '{{.PACKAGING_GIT_COMMIT}}'
cmds:
- cmd: '{{.REPO_ROOT}}/.github/packaging/scripts/validate-deb.sh'
19 changes: 19 additions & 0 deletions .github/packaging/nfpm/avalanchego-deb.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: avalanchego
arch: "${PACKAGE_ARCH}"
version: "${VERSION}"
maintainer: "Ava Labs <security@avalabs.org>"
description: "AvalancheGo node — the official Avalanche protocol implementation"
homepage: "https://github.com/ava-labs/avalanchego"
license: "BSD-3-Clause"
depends:
- "libc6 (>= 2.34)"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be 2.35 as per the taskfile? Same comment for the subnet-evm file.

contents:
- src: "${BINARY_PATH}"
dst: /usr/local/bin/avalanchego
file_info:
mode: 0755
changelog: "${NFPM_CHANGELOG}"
deb:
compression: gzip
signature:
key_file: "${NFPM_SIGNING_KEY}"
20 changes: 20 additions & 0 deletions .github/packaging/nfpm/subnet-evm-deb.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: subnet-evm
arch: "${PACKAGE_ARCH}"
version: "${VERSION}"
maintainer: "Ava Labs <security@avalabs.org>"
description: "Subnet-EVM plugin for AvalancheGo"
homepage: "https://github.com/ava-labs/avalanchego"
license: "BSD-3-Clause"
depends:
- "libc6 (>= 2.34)"
contents:
- src: "${BINARY_PATH}"
# SUBNET_EVM_VM_ID is sourced from graft/subnet-evm/scripts/default-vm-data.sh
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not referencing the correct script.

dst: /usr/local/lib/avalanchego/plugins/${SUBNET_EVM_VM_ID}
file_info:
mode: 0755
changelog: "${NFPM_CHANGELOG}"
deb:
compression: gzip
signature:
key_file: "${NFPM_SIGNING_KEY}"
Loading
Loading