From 0294128195b729566e46d4b0537e5f1901a7ce3b Mon Sep 17 00:00:00 2001 From: Victor Gutierrez Calderon Date: Wed, 1 Apr 2026 17:51:56 +0200 Subject: [PATCH] feat: add nightly releases via GoReleaser and Homebrew tap Add nightly build infrastructure that creates daily prerelease tags (e.g., v0.5.2-nightly.20260401) and routes them to separate entire-nightly cask/scoop entries using GoReleaser's .Prerelease template variable for conditional skip_upload. Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/nightly.yml | 46 +++++++++++++++++++++++++++++++++++ .github/workflows/release.yml | 24 ++++++++++++++---- .goreleaser.yaml | 30 ++++++++++++++++++++++- 3 files changed, 94 insertions(+), 6 deletions(-) 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..0c52e9698 --- /dev/null +++ b/.github/workflows/nightly.yml @@ -0,0 +1,46 @@ +name: Nightly Release + +on: + schedule: + - cron: "0 6 * * *" # 06:00 UTC daily + workflow_dispatch: + +permissions: + contents: write + +jobs: + create-nightly-tag: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + with: + fetch-depth: 0 + + - name: Create nightly tag if new commits exist + run: | + LAST_NIGHTLY=$(git tag -l 'v*-nightly.*' --sort=-v:refname | head -1) + if [ -n "$LAST_NIGHTLY" ]; then + COMMITS=$(git rev-list "${LAST_NIGHTLY}..HEAD" --count) + if [ "$COMMITS" -eq 0 ]; then + echo "No new commits since ${LAST_NIGHTLY}, skipping." + exit 0 + fi + fi + + LATEST_STABLE=$(git describe --tags --abbrev=0 --match 'v[0-9]*' --exclude '*-*' 2>/dev/null) + if [ -z "$LATEST_STABLE" ]; then + echo "::error::No stable version tag found" + exit 1 + fi + + DATE=$(date -u +%Y%m%d) + TAG="${LATEST_STABLE}-nightly.${DATE}" + + if git rev-parse "${TAG}" >/dev/null 2>&1; then + echo "Tag ${TAG} already exists, skipping." + exit 0 + fi + + echo "Creating nightly tag: ${TAG}" + git tag "${TAG}" + git push origin "${TAG}" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 99b19b3f4..ca36a6ad9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -30,13 +30,27 @@ jobs: homebrew-tap scoop-bucket - - name: Extract release notes from CHANGELOG.md + - name: Extract release notes run: | VERSION="${GITHUB_REF_NAME#v}" - awk -v ver="$VERSION" 'BEGIN{header="^## \\[" ver "\\]"} $0 ~ header{found=1; next} /^## \[/{if(found) exit} found{print}' CHANGELOG.md > "$RUNNER_TEMP/release_notes.md" - if [ ! -s "$RUNNER_TEMP/release_notes.md" ]; then - echo "::error::No changelog entry found for version ${VERSION} in CHANGELOG.md" - exit 1 + + if [[ "$VERSION" == *-* ]]; then + # Prerelease (nightly): generate notes from git log + LATEST_STABLE=$(git describe --tags --abbrev=0 --match 'v[0-9]*' --exclude '*-*' HEAD^ 2>/dev/null || echo "") + echo "## Nightly Build (${GITHUB_REF_NAME})" > "$RUNNER_TEMP/release_notes.md" + echo "" >> "$RUNNER_TEMP/release_notes.md" + if [ -n "$LATEST_STABLE" ]; then + echo "Changes since ${LATEST_STABLE}:" >> "$RUNNER_TEMP/release_notes.md" + echo "" >> "$RUNNER_TEMP/release_notes.md" + git log --oneline "${LATEST_STABLE}..HEAD" --no-merges >> "$RUNNER_TEMP/release_notes.md" + fi + else + # Stable release: require CHANGELOG entry + awk -v ver="$VERSION" 'BEGIN{header="^## \\[" ver "\\]"} $0 ~ header{found=1; next} /^## \[/{if(found) exit} found{print}' CHANGELOG.md > "$RUNNER_TEMP/release_notes.md" + if [ ! -s "$RUNNER_TEMP/release_notes.md" ]; then + echo "::error::No changelog entry found for version ${VERSION} in CHANGELOG.md" + exit 1 + fi fi - name: Run GoReleaser diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 0191ad1b0..9687ff485 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -75,6 +75,17 @@ scoops: homepage: "https://github.com/entireio/cli" description: "CLI for Entire" license: MIT + skip_upload: '{{ if .Prerelease }}true{{ end }}' + + - name: entire-nightly + repository: + owner: entireio + name: scoop-bucket + token: "{{ .Env.TAP_GITHUB_TOKEN }}" + homepage: "https://github.com/entireio/cli" + description: "CLI for Entire (nightly build)" + license: MIT + skip_upload: '{{ if not .Prerelease }}true{{ end }}' homebrew_casks: - name: entire @@ -91,9 +102,26 @@ homebrew_casks: bash: "completions/entire.bash" zsh: "completions/entire.zsh" fish: "completions/entire.fish" + skip_upload: '{{ if .Prerelease }}true{{ end }}' + + - name: entire-nightly + repository: + owner: entireio + name: homebrew-tap + token: "{{ .Env.TAP_GITHUB_TOKEN }}" + directory: Casks + homepage: "https://github.com/entireio/cli" + description: "CLI for Entire (nightly build)" + binaries: + - entire + completions: + bash: "completions/entire.bash" + zsh: "completions/entire.zsh" + fish: "completions/entire.fish" + skip_upload: '{{ if not .Prerelease }}true{{ end }}' announce: discord: - enabled: '{{ and (isEnvSet "DISCORD_WEBHOOK_ID") (isEnvSet "DISCORD_WEBHOOK_TOKEN") }}' + enabled: '{{ and (not .Prerelease) (isEnvSet "DISCORD_WEBHOOK_ID") (isEnvSet "DISCORD_WEBHOOK_TOKEN") }}' message_template: "Beep, boop. **Entire CLI {{ .Tag }}** is out!\n\n{{ .ReleaseURL }}\n\nSee https://docs.entire.io/cli/installation for help installing and updating." author: "Entire"