Skip to content

zlib-release

zlib-release #73

Workflow file for this run

name: Nanvix CI
on:
schedule:
- cron: "0 0 * * *"
push:
branches:
- nanvix/**
pull_request:
branches:
- nanvix/**
workflow_dispatch:
repository_dispatch:
# Triggered by zlib when it completes a release (dependency chain)
types: [zlib-release]
permissions:
contents: write
actions: write
issues: write
jobs:
# Extract Nanvix SHA once - all matrix builds use the same Nanvix release
get-nanvix-info:
runs-on: ubuntu-latest
outputs:
sha: ${{ steps.extract.outputs.sha }}
sha_full: ${{ steps.extract.outputs.sha_full }}
steps:
- name: Download Nanvix Release Info
id: extract
run: |
set -euo pipefail
# Download Nanvix release artifacts list
curl -fsSL https://raw.githubusercontent.com/nanvix/nanvix/refs/heads/dev/scripts/get-nanvix.sh | bash -s -- --force nanvix-artifacts
# Find any artifact to extract the SHA
ARTIFACT_FILE=$(find nanvix-artifacts -maxdepth 1 -type f -name "*.tar.bz2" | head -1)
if [[ -z "$ARTIFACT_FILE" ]]; then
echo "::error::No Nanvix artifact found"
exit 1
fi
# Extract Nanvix commit SHA from artifact filename
NANVIX_SHA_FULL=$(basename "$ARTIFACT_FILE" | sed -E 's/.*-([a-f0-9]{40})\.tar\.bz2$/\1/')
NANVIX_SHA="${NANVIX_SHA_FULL::7}"
echo "Nanvix commit SHA: $NANVIX_SHA_FULL (short: $NANVIX_SHA)"
echo "sha=$NANVIX_SHA" >> "$GITHUB_OUTPUT"
echo "sha_full=$NANVIX_SHA_FULL" >> "$GITHUB_OUTPUT"
build:
needs: get-nanvix-info
runs-on: ubuntu-latest
outputs:
zlib_tag: ${{ steps.zlib-dep.outputs.zlib_tag }}
strategy:
fail-fast: false
matrix:
include:
- platform: hyperlight
process-mode: multi-process
- platform: hyperlight
process-mode: single-process
- platform: microvm
process-mode: single-process
- platform: microvm
process-mode: multi-process
name: ${{ matrix.platform }}-${{ matrix.process-mode }}
container:
image: nanvix/toolchain:latest-minimal
options: --device /dev/kvm
defaults:
run:
shell: bash
env:
NANVIX_SHA: ${{ needs.get-nanvix-info.outputs.sha }}
NANVIX_SHA_FULL: ${{ needs.get-nanvix-info.outputs.sha_full }}
USER: runner
steps:
- uses: actions/checkout@v4
- name: Download and Extract Nanvix Release
run: |
set -euo pipefail
# Download all Nanvix release artifacts
curl -fsSL https://raw.githubusercontent.com/nanvix/nanvix/refs/heads/dev/scripts/get-nanvix.sh | bash -s -- --force nanvix-artifacts
# Find and extract the artifact matching platform and process-mode
ARTIFACT_PATTERN="${{ matrix.platform }}.*${{ matrix.process-mode }}.*\.tar\.bz2"
ARTIFACT_FILE=$(find nanvix-artifacts -maxdepth 1 -type f -name "*.tar.bz2" | grep -E "$ARTIFACT_PATTERN" | head -1)
if [[ -z "$ARTIFACT_FILE" ]]; then
echo "::error::No ${{ matrix.platform }} ${{ matrix.process-mode }} artifact found"
exit 1
fi
mkdir -p nanvix-artifacts/extracted
tar -xjf "$ARTIFACT_FILE" -C nanvix-artifacts/extracted
NANVIX_HOME=$(find nanvix-artifacts/extracted -maxdepth 2 -type d -name "bin" -exec dirname {} \; | head -1)
mkdir -p "$NANVIX_HOME/include"
echo "NANVIX_HOME=$NANVIX_HOME" >> "$GITHUB_ENV"
- name: Download and Install zlib Dependency
id: zlib-dep
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
echo "Downloading zlib for ${{ matrix.platform }}-${{ matrix.process-mode }} (Nanvix SHA: $NANVIX_SHA)..."
ZLIB_ARTIFACT="zlib-${{ matrix.platform }}-${{ matrix.process-mode }}.tar.bz2"
mkdir -p zlib-dep
# Get list of zlib releases and find one built with matching Nanvix SHA
# Release tags follow format: {commit-sha}-nanvix-{nanvix-sha}
echo "Looking for zlib release built with Nanvix SHA $NANVIX_SHA..."
ZLIB_RELEASES=$(curl -fsSL -H "Authorization: Bearer ${GH_TOKEN}" \
"https://api.github.com/repos/nanvix/zlib/releases?per_page=50" 2>/dev/null || echo "[]")
# Find a release with tag ending in -nanvix-{NANVIX_SHA}
MATCHING_RELEASE_TAG=""
for tag in $(echo "$ZLIB_RELEASES" | jq -r '.[].tag_name' 2>/dev/null); do
if [[ "$tag" == *"-nanvix-${NANVIX_SHA}" ]]; then
MATCHING_RELEASE_TAG="$tag"
echo "Found matching zlib release: $tag"
break
fi
done
# If no matching release found, fall back to latest
if [[ -z "$MATCHING_RELEASE_TAG" ]]; then
echo "::warning::No zlib release found matching Nanvix SHA $NANVIX_SHA, falling back to latest"
ZLIB_URL="https://github.com/nanvix/zlib/releases/latest/download/${ZLIB_ARTIFACT}"
# Get the actual tag of latest release for recording
MATCHING_RELEASE_TAG=$(curl -fsSL -H "Authorization: Bearer ${GH_TOKEN}" \
"https://api.github.com/repos/nanvix/zlib/releases/latest" 2>/dev/null | jq -r '.tag_name // "latest"')
else
ZLIB_URL="https://github.com/nanvix/zlib/releases/download/${MATCHING_RELEASE_TAG}/${ZLIB_ARTIFACT}"
fi
# Record the exact zlib tag used for downstream consumers
echo "ZLIB_TAG=${MATCHING_RELEASE_TAG}" >> "$GITHUB_ENV"
echo "zlib_tag=${MATCHING_RELEASE_TAG}" >> "$GITHUB_OUTPUT"
echo "Recording zlib dependency tag: ${MATCHING_RELEASE_TAG}"
echo "Downloading zlib from: $ZLIB_URL"
if curl -fsSL -o "zlib-dep/${ZLIB_ARTIFACT}" "$ZLIB_URL"; then
tar -xjf "zlib-dep/${ZLIB_ARTIFACT}" -C zlib-dep
# Find extracted directory and copy files to sysroot
ZLIB_DIR=$(find zlib-dep -mindepth 1 -maxdepth 1 -type d -name "zlib-*" | head -1)
if [[ -n "$ZLIB_DIR" ]]; then
echo "Installing zlib from $ZLIB_DIR to $NANVIX_HOME..."
cp -f "${ZLIB_DIR}/lib/libz.a" "${NANVIX_HOME}/lib/" 2>/dev/null || true
cp -f "${ZLIB_DIR}/include/"*.h "${NANVIX_HOME}/include/" 2>/dev/null || true
echo "zlib installed successfully"
else
echo "::warning::Could not find extracted zlib directory"
fi
else
echo "::error::Could not download zlib release"
exit 1
fi
- name: Build
run: |
make -f Makefile.nanvix CONFIG_NANVIX=y NANVIX_HOME="$NANVIX_HOME" NANVIX_TOOLCHAIN="/opt/nanvix" all
- name: Test
run: |
make -f Makefile.nanvix CONFIG_NANVIX=y NANVIX_HOME="$NANVIX_HOME" NANVIX_TOOLCHAIN="/opt/nanvix" test
- name: Package Artifacts
run: |
set -euo pipefail
ARTIFACT_NAME="sqlite-${{ matrix.platform }}-${{ matrix.process-mode }}"
DIST_DIR="dist/${ARTIFACT_NAME}"
mkdir -p "${DIST_DIR}/bin" "${DIST_DIR}/lib" "${DIST_DIR}/include"
# Copy executables
cp -f sqlite3.elf "${DIST_DIR}/bin/" 2>/dev/null || true
# Copy libraries
cp -f .libs/libsqlite3.a "${DIST_DIR}/lib/" 2>/dev/null || cp -f libsqlite3.a "${DIST_DIR}/lib/" 2>/dev/null || true
# Copy headers
cp -f sqlite3.h "${DIST_DIR}/include/" 2>/dev/null || true
# Create tarball
tar -cjf "dist/${ARTIFACT_NAME}.tar.bz2" -C dist "${ARTIFACT_NAME}"
echo "ARTIFACT_TARBALL=dist/${ARTIFACT_NAME}.tar.bz2" >> "$GITHUB_ENV"
- name: Upload Build Artifacts
uses: actions/upload-artifact@v4
with:
name: sqlite-${{ matrix.platform }}-${{ matrix.process-mode }}
path: ${{ env.ARTIFACT_TARBALL }}
retention-days: 7
release:
needs: [get-nanvix-info, build]
if: github.event_name != 'pull_request'
runs-on: ubuntu-latest
env:
NANVIX_SHA: ${{ needs.get-nanvix-info.outputs.sha }}
NANVIX_SHA_FULL: ${{ needs.get-nanvix-info.outputs.sha_full }}
steps:
- uses: actions/checkout@v4
- name: Download All Artifacts
uses: actions/download-artifact@v4
with:
path: release-artifacts
pattern: sqlite-*
- name: Prepare Release Assets
run: |
set -euo pipefail
mkdir -p release-assets
find release-artifacts -name "*.tar.bz2" -exec cp {} release-assets/ \;
ls -la release-assets/
- name: Get Dependency Tags
id: deps
env:
ZLIB_TAG: ${{ needs.build.outputs.zlib_tag }}
run: |
set -euo pipefail
# Dependency tags come from job outputs (all matrix builds use the same)
echo "Using zlib tag from job outputs: ${ZLIB_TAG}"
# Extract commit SHA from tag (format: {commit-sha}-nanvix-{nanvix-sha})
ZLIB_SHA=$(echo "$ZLIB_TAG" | sed -E 's/^([a-f0-9]+)-nanvix-.*$/\1/')
echo "zlib_tag=${ZLIB_TAG}" >> "$GITHUB_OUTPUT"
echo "zlib_sha=${ZLIB_SHA}" >> "$GITHUB_OUTPUT"
echo "Using zlib tag: ${ZLIB_TAG} (SHA: ${ZLIB_SHA})"
- name: Get Nanvix Release Info
id: nanvix-release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
echo "Using Nanvix SHA from job outputs: $NANVIX_SHA (full: $NANVIX_SHA_FULL)"
# Query Nanvix release API for additional metadata
API_URL="https://api.github.com/repos/nanvix/nanvix/releases/tags/latest"
RELEASE_INFO=$(curl -fsSL -H "Authorization: Bearer ${GH_TOKEN}" "$API_URL")
NANVIX_NAME=$(echo "$RELEASE_INFO" | jq -r '.name // "latest"')
NANVIX_PUBLISHED=$(echo "$RELEASE_INFO" | jq -r '.published_at')
echo "name=${NANVIX_NAME}" >> "$GITHUB_OUTPUT"
echo "published=${NANVIX_PUBLISHED}" >> "$GITHUB_OUTPUT"
- name: Create Latest Release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NANVIX_NAME: ${{ steps.nanvix-release.outputs.name }}
NANVIX_PUBLISHED: ${{ steps.nanvix-release.outputs.published }}
ZLIB_TAG: ${{ steps.deps.outputs.zlib_tag }}
ZLIB_SHA: ${{ steps.deps.outputs.zlib_sha }}
run: |
# Release tag format: {commit-sha}-nanvix-{nanvix-sha}
# This enables easy lookup of releases built with a specific Nanvix version
RELEASE_TAG="${GITHUB_SHA::7}-nanvix-${NANVIX_SHA}"
# Delete existing release if it exists (idempotent re-runs)
if gh release view "$RELEASE_TAG" &>/dev/null; then
echo "Deleting existing release: $RELEASE_TAG"
gh release delete "$RELEASE_TAG" --yes --cleanup-tag || true
fi
gh release create "$RELEASE_TAG" \
--title "Build ${GITHUB_SHA::7}" \
--notes "Automated build from branch ${{ github.ref_name }} at commit ${{ github.sha }}.
**Build Information:**
- Workflow Run: [#${{ github.run_number }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})
- Commit: [${{ github.sha }}](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }})
- Date: $(date -u +"%Y-%m-%d %H:%M:%S UTC")
**Nanvix Release:**
- Name: ${NANVIX_NAME}
- Published: ${NANVIX_PUBLISHED}
- Commit: [${NANVIX_SHA_FULL}](https://github.com/nanvix/nanvix/commit/${NANVIX_SHA_FULL})
**Dependencies:**
- zlib: [\`${ZLIB_TAG}\`](https://github.com/nanvix/zlib/releases/tag/${ZLIB_TAG})" \
--latest \
release-assets/*.tar.bz2
# Trigger dependent workflows (cpython depends on sqlite)
- name: Trigger Dependent Workflows
if: success()
env:
GH_TOKEN: ${{ secrets.DISPATCH_TOKEN }}
run: |
echo "Triggering cpython workflow..."
gh api repos/nanvix/cpython/dispatches \
-X POST \
-H "Accept: application/vnd.github+json" \
-f event_type="sqlite-release" \
-f "client_payload[nanvix_sha]=${NANVIX_SHA}" \
-f "client_payload[sqlite_tag]=${GITHUB_SHA::7}-nanvix-${NANVIX_SHA}" \
-f "client_payload[zlib_tag]=${ZLIB_TAG}" || echo "::warning::Failed to trigger cpython workflow"
report-failure:
needs:
- build
if: >-
${{ always() &&
(github.event_name == 'repository_dispatch' || github.event_name == 'schedule' || github.event_name == 'push') &&
needs.build.result == 'failure' }}
runs-on: ubuntu-latest
steps:
- name: Create failure issue
uses: actions/github-script@v7
env:
BUILD_RESULT: ${{ needs.build.result }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const runUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`;
const owner = context.repo.owner;
const repo = context.repo.repo;
const title = `CI failure (run ${context.runNumber})`;
const body = [
`The sqlite CI workflow failed.`,
`- Trigger: ${context.eventName}`,
`- Run: [#${context.runNumber}](${runUrl})`,
`- SHA: ${context.sha}`,
`- build: ${process.env.BUILD_RESULT}`,
'',
'Please investigate and take any corrective actions.'
].join('\n');
await github.rest.issues.create({
owner,
repo,
title,
body,
assignees: ['ppenna']
});