Nightly #76
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: Nightly | |
| on: | |
| schedule: | |
| # 06:00 UTC every day | |
| - cron: "0 6 * * *" | |
| workflow_dispatch: | |
| permissions: | |
| contents: write | |
| env: | |
| CARGO_TERM_COLOR: always | |
| jobs: | |
| build: | |
| name: Build nightly | |
| runs-on: ubuntu-latest | |
| outputs: | |
| skip: ${{ steps.check.outputs.skip }} | |
| commits: ${{ steps.check.outputs.commits }} | |
| date: ${{ steps.meta.outputs.date }} | |
| short_sha: ${{ steps.meta.outputs.short_sha }} | |
| full_sha: ${{ steps.meta.outputs.full_sha }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Check for changes since last nightly | |
| id: check | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| LAST=$(gh release view nightly --json createdAt --jq .createdAt 2>/dev/null || echo "1970-01-01T00:00:00Z") | |
| COMMITS=$(git log --since="${LAST}" --oneline | wc -l) | |
| echo "commits=${COMMITS}" >> "$GITHUB_OUTPUT" | |
| if [ "${COMMITS}" -eq 0 ] && [ "${{ github.event_name }}" != "workflow_dispatch" ]; then | |
| echo "skip=true" >> "$GITHUB_OUTPUT" | |
| echo "No new commits since last nightly — skipping" | |
| else | |
| echo "skip=false" >> "$GITHUB_OUTPUT" | |
| echo "${COMMITS} new commit(s) since last nightly" | |
| fi | |
| - name: Set metadata | |
| id: meta | |
| if: steps.check.outputs.skip != 'true' | |
| run: | | |
| echo "date=$(date -u +%Y%m%d)" >> "$GITHUB_OUTPUT" | |
| echo "short_sha=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT" | |
| echo "full_sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT" | |
| - name: Set up Docker Buildx | |
| if: steps.check.outputs.skip != 'true' | |
| uses: docker/setup-buildx-action@v4 | |
| - name: Build portable binaries (Ubuntu 22.04+ compatible) | |
| if: steps.check.outputs.skip != 'true' | |
| uses: docker/build-push-action@v7 | |
| with: | |
| context: . | |
| file: deploy/Dockerfile.manylinux | |
| target: dist | |
| push: false | |
| outputs: type=local,dest=./dist | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| - name: Package binaries | |
| if: steps.check.outputs.skip != 'true' | |
| run: | | |
| DATE="${{ steps.meta.outputs.date }}" | |
| SHORT_SHA="${{ steps.meta.outputs.short_sha }}" | |
| DIST="spur-nightly-${DATE}-${SHORT_SHA}-linux-amd64" | |
| mkdir -p "${DIST}/bin" | |
| for bin in spur spurctld spurd spurdbd spurrestd; do | |
| cp "dist/bin/${bin}" "${DIST}/bin/" | |
| done | |
| cd "${DIST}/bin" | |
| for cmd in sbatch srun squeue scancel sinfo sacct scontrol; do | |
| ln -s spur "${cmd}" | |
| done | |
| cd ../.. | |
| mkdir -p "${DIST}/etc" | |
| cp deploy/native-host/spur.conf "${DIST}/etc/spur.conf.example" | |
| tar czf "${DIST}.tar.gz" "${DIST}" | |
| sha256sum "${DIST}.tar.gz" > "${DIST}.tar.gz.sha256" | |
| - name: Upload artifact | |
| if: steps.check.outputs.skip != 'true' | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: spur-nightly-linux-amd64 | |
| path: | | |
| spur-*.tar.gz | |
| spur-*.tar.gz.sha256 | |
| verify: | |
| name: Verify on ${{ matrix.name }} | |
| needs: build | |
| if: needs.build.outputs.skip != 'true' | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - distro: "ubuntu:20.04" | |
| name: "Ubuntu 20.04" | |
| - distro: "ubuntu:22.04" | |
| name: "Ubuntu 22.04" | |
| - distro: "ubuntu:24.04" | |
| name: "Ubuntu 24.04" | |
| - distro: "ubuntu:26.04" | |
| name: "Ubuntu 26.04 (beta)" | |
| experimental: true | |
| - distro: "almalinux:8" | |
| name: "RHEL 8 (AlmaLinux)" | |
| continue-on-error: ${{ matrix.experimental || false }} | |
| steps: | |
| - uses: actions/download-artifact@v8 | |
| with: | |
| name: spur-nightly-linux-amd64 | |
| - name: Test binaries on ${{ matrix.name }} | |
| run: | | |
| tar xzf spur-*.tar.gz | |
| BINDIR=$(ls -d spur-*/bin | head -1) | |
| docker run --rm -v "$(pwd)/${BINDIR}:/test:ro" ${{ matrix.distro }} bash -c ' | |
| set -e | |
| echo "=== $(cat /etc/os-release | grep PRETTY_NAME | cut -d\" -f2) ===" | |
| echo "glibc: $(ldd --version 2>&1 | head -1)" | |
| for bin in spur spurctld spurd spurdbd spurrestd; do | |
| /test/${bin} --help > /dev/null 2>&1 | |
| echo " ${bin}: OK" | |
| done | |
| echo "All binaries verified" | |
| ' | |
| release: | |
| name: Publish nightly | |
| needs: [build, verify] | |
| if: needs.build.outputs.skip != 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: actions/download-artifact@v8 | |
| with: | |
| name: spur-nightly-linux-amd64 | |
| - name: Update nightly release | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| DATE: ${{ needs.build.outputs.date }} | |
| SHORT_SHA: ${{ needs.build.outputs.short_sha }} | |
| FULL_SHA: ${{ needs.build.outputs.full_sha }} | |
| COMMITS: ${{ needs.build.outputs.commits }} | |
| run: | | |
| # Delete existing nightly release + tag | |
| gh release delete nightly --yes --cleanup-tag 2>/dev/null || true | |
| # Create fresh nightly release | |
| gh release create nightly \ | |
| --title "Spur nightly (${DATE} · ${SHORT_SHA})" \ | |
| --notes "$(cat <<EOF | |
| **Automated nightly build** from \`main\` at $(date -u +"%Y-%m-%d %H:%M UTC"). | |
| Commit: [\`${SHORT_SHA}\`](https://github.com/${{ github.repository }}/commit/${FULL_SHA}) | |
| ${COMMITS} commit(s) since previous nightly. | |
| ### Install | |
| \`\`\`bash | |
| curl -fsSL https://raw.githubusercontent.com/${{ github.repository }}/main/install.sh | bash -s -- nightly | |
| \`\`\` | |
| EOF | |
| )" \ | |
| --prerelease \ | |
| spur-*.tar.gz spur-*.tar.gz.sha256 |