Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .github/dependabot.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
version: 2
updates:
- package-ecosystem: gomod
directory: /
schedule:
interval: weekly

- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
159 changes: 159 additions & 0 deletions .github/workflows/nightly.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
name: Nightly Release

on:
schedule:
# Run at 02:00 UTC every day
- cron: '0 2 * * *'
workflow_dispatch:

concurrency:
group: nightly-release
cancel-in-progress: true

jobs:
check-and-create-nightly:
runs-on: ubuntu-latest
permissions:
contents: write
outputs:
nightly_version: ${{ env.NIGHTLY_VERSION }}
skip_nightly: ${{ env.SKIP_NIGHTLY }}
changelog_body: ${{ env.CHANGELOG_BODY }}
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 0

- name: Check for unreleased commits
id: check_commits
run: |
# Find the latest release tag (any x.y.z release)
LATEST_RELEASE=$(git tag -l 'v*.*.*' --sort=-version:refname | grep -v 'prerelease' | grep -v '^nightly' | head -n1)

if [ -z "$LATEST_RELEASE" ]; then
echo "No existing releases found, creating first nightly"
COMMITS_SINCE_RELEASE=$(git rev-list HEAD --count)
LATEST_RELEASE_COMMIT=""
else
echo "Latest release: $LATEST_RELEASE"
COMMITS_SINCE_RELEASE=$(git rev-list ${LATEST_RELEASE}..HEAD --count)
LATEST_RELEASE_COMMIT="$LATEST_RELEASE"
fi

echo "Commits since latest release: $COMMITS_SINCE_RELEASE"

if [ "$COMMITS_SINCE_RELEASE" -eq "0" ]; then
echo "No new commits since latest release, skipping nightly"
echo "SKIP_NIGHTLY=true" >> "$GITHUB_ENV"
exit 0
fi

CURRENT_COMMIT=$(git rev-parse HEAD)

# Check for existing nightly with same commit
EXISTING_NIGHTLY_COMMIT=""
if git rev-parse --verify nightly >/dev/null 2>&1; then
EXISTING_NIGHTLY_COMMIT=$(git rev-list -n 1 nightly 2>/dev/null || echo "")
fi

if [ "$EXISTING_NIGHTLY_COMMIT" = "$CURRENT_COMMIT" ]; then
echo "Nightly release already exists for current commit"
echo "SKIP_NIGHTLY=true" >> "$GITHUB_ENV"
exit 0
fi

# Use fixed nightly tag name
NIGHTLY_VERSION="nightly"
echo "NIGHTLY_VERSION=$NIGHTLY_VERSION" >> "$GITHUB_ENV"
echo "Creating nightly release: $NIGHTLY_VERSION"

- name: Extract changelog for nightly
id: changelog
if: env.SKIP_NIGHTLY != 'true'
run: |
# Extract the Unreleased section from CHANGELOG.md using make target
CHANGELOG_CONTENT=$(make extract-changelog-unreleased)

# Save to environment variable, handling multiline content
{
echo 'CHANGELOG_BODY<<EOF'
echo "$CHANGELOG_CONTENT"
echo 'EOF'
} >> "$GITHUB_ENV"

- name: Delete existing nightly release and tag
if: env.SKIP_NIGHTLY != 'true'
run: |
# Delete existing nightly release if it exists
if gh release view nightly >/dev/null 2>&1; then
echo "Deleting existing nightly release"
gh release delete nightly --yes
fi

# Delete existing nightly tag if it exists
if git rev-parse --verify nightly >/dev/null 2>&1; then
echo "Deleting existing nightly tag"
git tag -d nightly
if ! git push origin :refs/tags/nightly; then
echo "Warning: Failed to delete remote nightly tag" >&2
exit 1
fi
fi
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Create nightly release
if: env.SKIP_NIGHTLY != 'true'
run: |
VERSION="${{ env.NIGHTLY_VERSION }}"
CURRENT_DATE=$(date -u +%Y-%m-%d)
SHORT_COMMIT=$(git rev-parse --short HEAD)

echo "Creating nightly release: $VERSION"
gh release create "$VERSION" \
--title "Nightly Release ($CURRENT_DATE - $SHORT_COMMIT)" \
--notes "${{ env.CHANGELOG_BODY }}" \
--prerelease
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

build-and-upload:
needs: check-and-create-nightly
if: needs.check-and-create-nightly.outputs.skip_nightly != 'true'
runs-on: ubuntu-latest
permissions:
contents: write
id-token: write # Permission for keyless signing
strategy:
matrix:
goos: [linux, windows, darwin]
goarch: [amd64, arm64]
steps:
- name: Checkout code
uses: actions/checkout@v6

- name: Set up Go
uses: actions/setup-go@v6
with:
go-version-file: 'go.mod'

- name: Install cosign
uses: sigstore/cosign-installer@v4.0.0

- name: Build release artifacts
env:
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
run: make build-release package-release

- name: Sign release artifacts
env:
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
run: make sign-release

- name: Upload assets to nightly release
run: make upload-release-assets VERSION="${{ needs.check-and-create-nightly.outputs.nightly_version }}"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
130 changes: 130 additions & 0 deletions .github/workflows/prerelease.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
name: Create Pre-Release

on:
push:
tags:
- 'v*.*.*-rc.*'
workflow_dispatch:
inputs:
tag:
description: 'Pre-release tag (e.g., v1.0.0-rc.1)'
required: true
type: string

jobs:
determine-version:
runs-on: ubuntu-latest
permissions:
contents: write
outputs:
prerelease_version: ${{ env.PRERELEASE_VERSION }}
changelog_body: ${{ env.CHANGELOG_BODY }}
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 0

- name: Extract version from tag
id: get_version
run: |
# Get version from tag (either from push event or manual input)
if [ "${{ github.event_name }}" = "push" ]; then
VERSION="${{ github.ref_name }}"
else
VERSION="${{ inputs.tag }}"
fi

# Validate version format using make target
make validate-prerelease-tag VERSION="$VERSION"

echo "PRERELEASE_VERSION=$VERSION" >> "$GITHUB_ENV"
echo "Pre-release version: $VERSION"

- name: Extract changelog
id: changelog
run: |
VERSION="${{ env.PRERELEASE_VERSION }}"
# Extract the base release version (without -rc.N suffix)
RELEASE_VERSION=$(echo "$VERSION" | sed 's/-rc\.[0-9]*$//')

# Extract changelog using make target (tries version-specific, then unreleased)
CHANGELOG_CONTENT=$(make extract-changelog-version VERSION="$RELEASE_VERSION" 2>/dev/null || echo "Pre-release build for ${RELEASE_VERSION}. See CHANGELOG.md for details.")

# Save to environment variable, handling multiline content
{
echo 'CHANGELOG_BODY<<EOF'
echo "$CHANGELOG_CONTENT"
echo 'EOF'
} >> "$GITHUB_ENV"

- name: Create or update pre-release
run: |
VERSION="${{ env.PRERELEASE_VERSION }}"

# Check if release already exists
if gh release view "$VERSION" >/dev/null 2>&1; then
echo "Pre-release $VERSION already exists, checking if changelog needs to be updated..."

# Get current release notes
CURRENT_NOTES=$(gh release view "$VERSION" --json body -q .body)

# Check if changelog content is already in the notes
if echo "$CURRENT_NOTES" | grep -qF "${{ env.CHANGELOG_BODY }}"; then
echo "Changelog already present in release notes, skipping update..."
else
echo "Appending changelog to existing release notes..."
NEW_NOTES="${CURRENT_NOTES}\n\n---\n\n${{ env.CHANGELOG_BODY }}"
gh release edit "$VERSION" --notes "$NEW_NOTES"
fi
else
echo "Creating pre-release $VERSION..."
gh release create "$VERSION" \
--title "$VERSION" \
--notes "${{ env.CHANGELOG_BODY }}" \
--prerelease
fi
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

build-and-upload:
needs: determine-version
runs-on: ubuntu-latest
permissions:
contents: write
id-token: write # Permission for keyless signing
strategy:
matrix:
goos: [linux, windows, darwin]
goarch: [amd64, arm64]
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 0

- name: Set up Go
uses: actions/setup-go@v6
with:
go-version-file: 'go.mod'

- name: Install cosign
uses: sigstore/cosign-installer@v4.0.0

- name: Build release artifacts
env:
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
VERSION: ${{ needs.determine-version.outputs.prerelease_version }}
run: make build-release package-release

- name: Sign release artifacts
env:
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
run: make sign-release

- name: Upload assets to release
run: make upload-release-assets VERSION="${{ needs.determine-version.outputs.prerelease_version }}"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Loading