diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml new file mode 100644 index 0000000000..5431ea3774 --- /dev/null +++ b/.github/workflows/nightly.yml @@ -0,0 +1,129 @@ +name: Nightly Build + +on: + schedule: + - cron: "0 1 * * *" # 1 AM UTC daily + workflow_dispatch: + +jobs: + nightly: + runs-on: larger-runners + environment: gpg + permissions: + contents: read + id-token: write + packages: write + steps: + - name: Set up QEMU cross build support + uses: docker/setup-qemu-action@53851d14592bedcffcf25ea515637cff71ef929a # v3.3.0 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v3.8.0 + + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + ref: main + fetch-depth: 0 + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version-file: "go.mod" + + - name: Install cosign + uses: sigstore/cosign-installer@main + with: + cosign-release: v2.2.0 + + - name: Import GPG key + run: | + GPG_KEY_FILE=/tmp/signing-key.gpg + echo "${{ secrets.GPG_PRIVATE_KEY }}" | base64 --decode > "${GPG_KEY_FILE}" + + echo "${{ secrets.GPG_PRIVATE_KEY }}" | base64 --decode | gpg --import + GPG_FINGERPRINT=$(gpg --list-secret-keys --keyid-format LONG | awk '/^sec/{sub(/.*\//, "", $2); print $2; exit}') + + echo "GPG_FINGERPRINT=${GPG_FINGERPRINT}" >>"${GITHUB_ENV}" + echo "GPG_KEY_FILE=${GPG_KEY_FILE}" >> "${GITHUB_ENV}" + env: + GPG_TTY: /dev/ttys000 + + - name: Run GoReleaser + uses: goreleaser/goreleaser-action@5742e2a039330cbb23ebf35f046f814d4c6ff811 # v5.1.0 + with: + version: v1.21.2 + args: release --nightly --clean --timeout=60m + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Remove GPG key + if: always() + run: | + rm -rf ~/.gnupg + if [ -n "${GPG_KEY_FILE}" ]; then + rm -rf "${GPG_KEY_FILE}" + fi + + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: nightly-dist + path: dist + retention-days: 7 + + - name: Setup dependencies + run: sudo apt-get update && sudo apt-get install rclone jq + + - name: Prepare nightly artifacts + run: | + # Get today's date in YYYYMMDD format + DATE=$(date +%Y%m%d) + VERSION=$(grep -E '"version":' dist/metadata.json | cut -d'"' -f4) + COMMIT=$(git rev-parse --short HEAD) + + # Create a staging directory for upload + mkdir -p ./upload/nightlies/${DATE} + + # Copy relevant artifacts + cp dist/*.tar.gz ./upload/nightlies/${DATE}/ 2>/dev/null || true + cp dist/*.zip ./upload/nightlies/${DATE}/ 2>/dev/null || true + cp dist/*SHA256SUMS* ./upload/nightlies/${DATE}/ 2>/dev/null || true + cp dist/*.sig ./upload/nightlies/${DATE}/ 2>/dev/null || true + cp dist/*.pem ./upload/nightlies/${DATE}/ 2>/dev/null || true + cp dist/*.gpgsig ./upload/nightlies/${DATE}/ 2>/dev/null || true + + # Create latest.json + cat > ./upload/nightlies/latest.json </dev/null | xargs -n1 basename | jq -R -s -c 'split("\n")[:-1]') + } + EOF + + echo "nightly build artifacts for ${DATE} ready to upload" + echo "Version: ${VERSION}" + echo "Commit: ${COMMIT}" + + - name: Sync to R2 + run: | + set -euo pipefail + + # Use high parallelism for faster uploads + echo "Starting upload to R2..." + if ! rclone copy --checkers=512 --transfers=512 --checksum --no-traverse --verbose ./upload/ R2:${{ secrets.R2_BUCKET_NAME }}; then + echo "ERROR: Failed to upload artifacts to R2" + exit 1 + fi + + echo "Successfully uploaded nightly build artifacts to R2" + env: + RCLONE_CONFIG_R2_TYPE: s3 + RCLONE_CONFIG_R2_PROVIDER: Cloudflare + RCLONE_CONFIG_R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }} + RCLONE_CONFIG_R2_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }} + RCLONE_CONFIG_R2_ENDPOINT: ${{ secrets.R2_ENDPOINT }} + RCLONE_CONFIG_R2_ACL: public-read diff --git a/.goreleaser.yaml b/.goreleaser.yaml index ed9fefa5cb..09b9216797 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -349,6 +349,12 @@ docker_signs: snapshot: name_template: "{{ .Version }}-next" +nightly: + # Version format: 1.9.0-20250806-nightly-c5fd934 + version_template: "{{ .Version }}-{{ .Now.Format \"20060102\" }}-nightly-{{ .ShortCommit }}" + publish_release: false + name_template: "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}" + changelog: use: github-native diff --git a/RELEASE.md b/RELEASE.md index ef6c4ac26c..a3d48e7960 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -12,3 +12,6 @@ ## **Compatibility** - To check the compatibility of OpenTofu with Terraform, refer to the ([Migration guide](https://opentofu.org/docs/intro/migration/)) + +## **Nightly Builds** +- Nightly builds are currently being trialled experimentally, these builds will be removed after 30 days and are not intended for usage in production environments ever. \ No newline at end of file