From ad9d5a3d19acc278c972a3b356f924e11abed1c6 Mon Sep 17 00:00:00 2001 From: Hua Audio Date: Mon, 9 Mar 2026 05:37:31 +0100 Subject: [PATCH] feat(ci/cd) Add nightly build workflow (#1226) * Feat/nightly build (#2) * feat: add nightly build workflow - Add nightly.yml GitHub Actions workflow for daily builds - Schedule: daily at 2 AM UTC - Build using GoReleaser snapshot mode - Upload artifacts to GitHub Releases as pre-release - Create nightly Docker tags - Clean old nightly releases (keep last 30) - Add research documentation for nightly build setup * fix: correct yaml syntax error in nightly workflow * feat: restore nightly build workflow --------- Co-authored-by: Hua * fix: use explicit tags instead of metadata-action * Refactor nightly build workflow for clarity and efficiency Refactor nightly build workflow to improve clarity and efficiency. Update job names, streamline version generation, and enhance Docker build process. * remove unused research docs * Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * incorporate review suggestions * Update .github/workflows/nightly.yml Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update .github/workflows/nightly.yml Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * correct release naming * update base version regular * Update .github/workflows/nightly.yml Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update .github/workflows/nightly.yml Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update docker metadata and pass version as env * Update release note * Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update .github/workflows/nightly.yml Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update prerelease flag and rolling release * Update to set provenance to false --------- Co-authored-by: Hua Co-authored-by: zhangmikoto Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .github/workflows/nightly.yml | 167 ++++++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 .github/workflows/nightly.yml diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml new file mode 100644 index 000000000..ca4edc2ab --- /dev/null +++ b/.github/workflows/nightly.yml @@ -0,0 +1,167 @@ +name: Nightly Build + +on: + schedule: + - cron: '0 0 * * *' + workflow_dispatch: + +permissions: + contents: read + +jobs: + generate-version: + name: Generate Version + runs-on: ubuntu-latest + outputs: + version: ${{ steps.version.outputs.version }} + tag: ${{ steps.version.outputs.tag }} + steps: + - name: Checkout + uses: actions/checkout@v6 + with: + fetch-depth: 0 + + - name: Generate version + id: version + run: | + DATE=$(date -u +%Y%m%d) + SHA=$(git rev-parse --short=8 HEAD) + BASE_VERSION=$(git describe --tags --match "v*" --exclude "*nightly*" --abbrev=0 2>/dev/null || true) + if [ -z "$BASE_VERSION" ] || [ "$BASE_VERSION" = "v0.0.0" ]; then + VERSION="nightly-${DATE}-${SHA}" + else + VERSION="${BASE_VERSION}-nightly-${DATE}-${SHA}" + fi + TAG="nightly-${DATE}-${SHA}" + echo "version=${VERSION}" >> "$GITHUB_OUTPUT" + echo "tag=${TAG}" >> "$GITHUB_OUTPUT" + + build: + name: Build + runs-on: ubuntu-latest + needs: generate-version + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Setup Go + uses: actions/setup-go@v6 + with: + go-version-file: go.mod + + - name: Build + env: + VERSION: ${{ needs.generate-version.outputs.version }} + run: make build-all VERSION="$VERSION" + + - name: Upload artifacts + uses: actions/upload-artifact@v6 + with: + name: picoclaw-binaries + path: build + + build-docker: + name: Build Docker + runs-on: ubuntu-latest + needs: generate-version + permissions: + contents: read + packages: write + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to GHCR + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract Docker metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ghcr.io/${{ github.repository }} + tags: | + type=raw,value=${{ needs.generate-version.outputs.tag }} + type=raw,value=${{ needs.generate-version.outputs.version }} + type=raw,value=nightly + + - name: Build and push + uses: docker/build-push-action@v6 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max + platforms: linux/amd64,linux/arm64,linux/riscv64 + provenance: false + + release: + name: Release + runs-on: ubuntu-latest + needs: [generate-version, build, build-docker] + permissions: + contents: write + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Download artifacts + uses: actions/download-artifact@v6 + with: + name: picoclaw-binaries + path: ./build + + - name: Create release + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + TAG="${{ needs.generate-version.outputs.tag }}" + TITLE="${{ needs.generate-version.outputs.version }}" + NOTES=$'Nightly build for **${{ needs.generate-version.outputs.version }}**\n\nThis is an automated build and may be unstable. Use with caution.' + + if gh release view "$TAG" >/dev/null 2>&1; then + echo "Release $TAG already exists, updating metadata and assets..." + gh release edit "$TAG" \ + --title "$TITLE" \ + --notes "$NOTES" \ + --prerelease + gh release upload "$TAG" build/* --clobber + else + echo "Creating new release $TAG..." + gh release create "$TAG" \ + --title "$TITLE" \ + --notes "$NOTES" \ + --target "${{ github.sha }}" \ + --prerelease \ + build/* + fi + + echo "Updating rolling 'nightly' release..." + gh release delete nightly --cleanup-tag -y >/dev/null 2>&1 || true + sleep 2 + gh release create nightly \ + --title "Nightly Build" \ + --notes "$NOTES" \ + --target "${{ github.sha }}" \ + --prerelease \ + build/* + + echo "Cleaning up old nightly releases (keeping only the most recent)..." + gh release list --limit 100 --json tagName -q '.[].tagName | select(startswith("nightly-"))' | tail -n +2 | while read -r old_tag; do + if [ -n "$old_tag" ] && [ "$old_tag" != "$TAG" ]; then + echo "Deleting old nightly release: $old_tag" + gh release delete "$old_tag" --cleanup-tag -y || true + fi + done