Files
logos-messaging-nim/.github/workflows/pre-release.yml
T

276 lines
9.6 KiB
YAML

name: Pre-Release
on:
push:
tags:
- 'v*-rc.*'
schedule:
- cron: 13 3 * * *
workflow_dispatch:
env:
RELEASE_NAME: nightly
NODE_BINARIES: "wakunode2 logosdeliverynode chat2"
TOOLS_BINARIES: "wakucanary networkmonitor"
NPROC: 2
MAKEFLAGS: "-j${NPROC}"
NIM_PARAMS: "-d:disableMarchNative"
NIM_VERSION: '2.2.4'
NIMBLE_VERSION: '0.22.3'
jobs:
tag-name:
runs-on: ubuntu-22.04
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Vars
id: vars
run: |
# master -> nightly; other refs use their bare name, "/" replaced by "-".
# TAG=$([[ "${{github.ref}}" == "refs/heads/master" ]] && echo "${{env.RELEASE_NAME}}" || echo ${{github.ref}} | sed 's#refs/tags/##')
TAG=$([[ "${{github.ref}}" == "refs/heads/master" ]] && echo "${{env.RELEASE_NAME}}" || echo "${{github.ref_name}}" | tr '/' '-')
echo "tag=${TAG}" >> $GITHUB_OUTPUT
outputs:
tag: ${{steps.vars.outputs.tag}}
build-and-publish:
needs: tag-name
# Matrix job count for the verify step; every matrix job writes the same value.
outputs:
platform-count: ${{ strategy.job-total }}
strategy:
# Keep the other jobs running when one fails.
fail-fast: false
matrix:
# GitHub macOS runners are arm64 only; darwin/amd64 needs a cross-compilation setup.
include:
- os: ubuntu-22.04
arch: amd64
- os: macos-15
arch: arm64
runs-on: ${{ matrix.os }}
steps:
- name: Checkout code
uses: actions/checkout@v4
# macos images ship no nim/nimble; make dies at "nimble: No such file or directory".
- name: Install Nim ${{ env.NIM_VERSION }}
uses: jiro4989/setup-nim-action@v2
with:
nim-version: ${{ env.NIM_VERSION }}
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Install Nimble ${{ env.NIMBLE_VERSION }}
run: |
cd /tmp && nimble install "nimble@${{ env.NIMBLE_VERSION }}" -y
echo "$HOME/.nimble/bin" >> $GITHUB_PATH
- name: prep variables
id: vars
run: |
ARCH=${{matrix.arch}}
echo "arch=${ARCH}" >> $GITHUB_OUTPUT
NWAKU_ARTIFACT_NAME=$(echo "nwaku-${ARCH}-${{runner.os}}-${{ needs.tag-name.outputs.tag }}.tar.gz" | tr "[:upper:]" "[:lower:]")
NWAKU_TOOLS_ARTIFACT_NAME=$(echo "nwaku-tools-${ARCH}-${{runner.os}}-${{ needs.tag-name.outputs.tag }}.tar.gz" | tr "[:upper:]" "[:lower:]")
echo "nwaku=${NWAKU_ARTIFACT_NAME}" >> $GITHUB_OUTPUT
echo "nwakutools=${NWAKU_TOOLS_ARTIFACT_NAME}" >> $GITHUB_OUTPUT
- name: build artifacts
id: build
run: |
# -j1: each target starts one nimble process. Two parallel nimble
# processes corrupt the shared package metadata (nimblemeta.json).
make V=1 -j1 CI=false POSTGRES=1 $NODE_BINARIES tools
tar -cvzf ${{steps.vars.outputs.nwaku}} $(printf './build/%s ' $NODE_BINARIES)
tar -cvzf ${{steps.vars.outputs.nwakutools}} $(printf './build/%s ' $TOOLS_BINARIES)
# Each matrix job must use a unique artifact name. With one shared
# name, download-artifact@v4 keeps only the last upload and the release
# loses platforms.
- name: upload artifacts
uses: actions/upload-artifact@v4
with:
name: wakunode2-${{ matrix.os }}-${{ matrix.arch }}
path: ${{steps.vars.outputs.nwaku}}
retention-days: 2
- name: upload artifacts
uses: actions/upload-artifact@v4
with:
name: wakutools-${{ matrix.os }}-${{ matrix.arch }}
path: ${{steps.vars.outputs.nwakutools}}
retention-days: 2
build-docker-image:
needs: tag-name
# uses: logos-messaging/logos-delivery/.github/workflows/container-image.yml@master
uses: ./.github/workflows/container-image.yml
with:
image_tag: ${{ needs.tag-name.outputs.tag }}
secrets: inherit
# js-waku-node:
# needs: build-docker-image
# uses: logos-messaging/logos-delivery-js/.github/workflows/test-node.yml@master
# permissions:
# contents: read
# actions: read
# checks: write
# with:
# nim_wakunode_image: ${{ needs.build-docker-image.outputs.image }}
# test_type: node
# debug: waku*
js-waku-node-optional:
needs: build-docker-image
uses: logos-messaging/logos-delivery-js/.github/workflows/test-node.yml@master
permissions:
contents: read
actions: read
checks: write
with:
nim_wakunode_image: ${{ needs.build-docker-image.outputs.image }}
test_type: node-optional
debug: waku*
create-release-candidate:
runs-on: ubuntu-22.04
needs: [ tag-name, build-and-publish ]
permissions:
contents: write
actions: read
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: master
# merge-multiple puts all matching artifacts into one directory.
- name: download node artifacts
uses: actions/download-artifact@v4
with:
pattern: wakunode2-*
path: wakunode2
merge-multiple: true
- name: download tools artifacts
uses: actions/download-artifact@v4
with:
pattern: wakutools-*
path: wakutools
merge-multiple: true
- name: prep variables
id: vars
run: |
REF=$(echo ${{github.ref}} | sed 's#.*/##')
echo "ref=${REF}" >> $GITHUB_OUTPUT
# A fault in the release artifacts stops the release here.
- name: verify release artifacts
run: |
set -e
# One node tarball and one tools tarball for each matrix job. The count
# comes from the build job's own matrix at run time, thus a matrix
# change needs no edit here.
EXPECTED=${{ needs.build-and-publish.outputs.platform-count }}
echo "expected platform count: $EXPECTED"
# check_dir <dir> <binaries>
# e.g. check_dir wakunode2 "wakunode2 logosdeliverynode chat2"
# Every tarball in <dir> must extract and must contain each named
# binary with the CPU type that the tarball name shows.
check_dir() {
local dir="$1" # artifact directory, e.g. wakunode2
local binaries="$2" # in each tarball, e.g. "wakunode2 logosdeliverynode chat2"
echo "== $dir (binaries: $binaries) =="
ls -l "$dir"
local count
count=$(ls "$dir"/*.tar.gz | wc -l)
[ "$count" -eq "$EXPECTED" ] || { echo "FAIL: $dir: expected $EXPECTED tarballs, found $count"; exit 1; }
for tarball in "$dir"/*.tar.gz; do
echo "-- $tarball --"
# A truncated tarball stops the step here.
tar -tzf "$tarball"
local unpacked
unpacked=$(mktemp -d)
tar -xzf "$tarball" -C "$unpacked"
# The tarball name shows the correct CPU type,
# e.g. nwaku-amd64-linux-nightly.tar.gz -> binaries must be x86-64.
case "$tarball" in
*-amd64-*) want='x86-64' ;;
*-arm64-*) want='arm64|aarch64' ;; # macOS says arm64, Linux says aarch64
*) echo "FAIL: unknown arch in name: $tarball"; exit 1 ;;
esac
# file reads the bytes of each binary,
# e.g. "build/wakunode2: ELF 64-bit LSB pie executable, x86-64, ...".
# A missing, zero-size, truncated, or wrong-arch binary fails here.
for binary in $binaries; do
line=$(file "$unpacked/build/$binary" 2>/dev/null || true)
echo "$line"
echo "$line" | grep -E "executable|shared object|shared library" | grep -Eq ": .*($want)" \
|| { echo "FAIL: $binary (want: $want)"; exit 1; }
done
done
}
check_dir wakunode2 "$NODE_BINARIES"
check_dir wakutools "$TOOLS_BINARIES"
- name: generate release notes
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -x
TAG="${{ needs.tag-name.outputs.tag }}"
# NOTE: gh release create refuses to create over an existing release.
if [[ "$TAG" == "nightly" ]]; then
# Each run replaces the nightly release and its tag. gh release
# create reuses an existing tag and ignores --target.
gh release delete -y "$TAG" || true
# --exit-code: nonzero exit when the tag is absent.
if git ls-remote --exit-code origin "refs/tags/$TAG" >/dev/null; then
git push origin ":refs/tags/$TAG"
fi
git tag -d "$TAG" || true
fi
RELEASE_NOTES_TAG=$([[ "$TAG" != "nightly" ]] && echo "-t ${{steps.vars.outputs.ref}}" || echo "")
docker run \
-t \
--rm \
-v ${PWD}:/opt/sv4git/repo:z \
-u $(id -u) \
docker.io/wakuorg/sv4git:latest \
release-notes ${RELEASE_NOTES_TAG} --previous $(git tag -l --sort -creatordate | grep -e "^v[0-9]*\.[0-9]*\.[0-9]*$") |\
sed -E 's@#([0-9]+)@[#\1](https://github.com/logos-messaging/logos-delivery/issues/\1)@g' > release_notes.md
sed -i "s/^## .*/Generated at $(date)/" release_notes.md
cat release_notes.md
TARGET=$([[ "$TAG" == "nightly" ]] && echo "--target ${{steps.vars.outputs.ref}}" || echo "")
gh release create "$TAG" --prerelease ${TARGET} \
--title "$TAG" --notes-file release_notes.md \
wakunode2/* wakutools/*