Add job to extract Nanvix SHA and update build process for zlib integ… #2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Nanvix CI | |
| on: | |
| schedule: | |
| - cron: "0 0 * * *" | |
| push: | |
| branches: | |
| - nanvix/** | |
| pull_request: | |
| branches: | |
| - nanvix/** | |
| workflow_dispatch: | |
| repository_dispatch: | |
| types: [nanvix-minor-release, nanvix-major-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 | |
| 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:v0.11.x-minimal | |
| defaults: | |
| run: | |
| shell: bash | |
| 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 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) | |
| echo "NANVIX_HOME=$NANVIX_HOME" >> "$GITHUB_ENV" | |
| - name: Download and Install zlib Dependency | |
| 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}" | |
| else | |
| ZLIB_URL="https://github.com/nanvix/zlib/releases/download/${MATCHING_RELEASE_TAG}/${ZLIB_ARTIFACT}" | |
| fi | |
| 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 -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 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 }} | |
| 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}" | |
| gh release create "$RELEASE_TAG" \ | |
| --title "Build ${GITHUB_SHA::7} (Nanvix ${NANVIX_SHA})" \ | |
| --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}) | |
| - Nanvix SHA: \`${NANVIX_SHA}\` | |
| **Dependencies:** | |
| - zlib: Built with Nanvix SHA \`${NANVIX_SHA}\`" \ | |
| --latest \ | |
| release-assets/*.tar.bz2 | |
| report-minor-release-failure: | |
| needs: | |
| - build | |
| if: >- | |
| ${{ always() && github.event_name == 'repository_dispatch' && | |
| (github.event.action == 'nanvix-minor-release' || github.event.action == 'nanvix-major-release') && | |
| 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 isMajor = context.payload.action === 'nanvix-major-release'; | |
| const releaseType = isMajor ? 'major' : 'minor'; | |
| 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 = `Nanvix ${releaseType} release CI failure (run ${context.runNumber})`; | |
| const body = [ | |
| `The Nanvix ${releaseType} release CI workflow failed.`, | |
| `- 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'] | |
| }); |