Watch
1
0
Fork
You've already forked RedFlag
0
RedFlag/.gitea/workflows/nightly.yml
Fimeg f6b03f40c6 ci: publish and verify forgejo releases
Tags now cross only after the release gates. Public assets are read back anonymously and hashed; the Rust Action pin now names its advertised stable commit.
2026-08-20 12:40:47 -04:00

181 lines
7.8 KiB
YAML

name: nightly
# Rolling alpha channel. Every night, if CI is green on public HEAD and there
# are new commits since the last nightly, build lean artifacts and replace the
# `nightly` prerelease on Gitea. Versioned releases stay on
# release.yml — this channel never tags v*, never ships a manifest, and is
# therefore invisible to fleet self-upgrade. Manual installs only.
on:
schedule:
- cron: "0 9 * * *"
workflow_dispatch: {}
permissions:
contents: write
jobs:
nightly:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
ref: public
fetch-depth: 0
- name: Preflight — CI green, new commits since last nightly
id: pre
run: |
set -euo pipefail
SHA=$(git rev-parse HEAD)
SHORT=$(git rev-parse --short HEAD)
API="${GITHUB_SERVER_URL}/api/v1"
STATE=$(curl -sf -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
"$API/repos/${GITHUB_REPOSITORY}/commits/$SHA/status" \
| python3 -c "import json,sys; print(json.load(sys.stdin).get('state',''))" || echo "")
echo "HEAD=$SHA ci_state=$STATE"
if [ "$STATE" != "success" ]; then
echo "[INFO] [nightly] CI not green on public HEAD (state=$STATE) — no build tonight"
echo "go=false" >> "$GITHUB_OUTPUT"
exit 0
fi
PREV=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
"$API/repos/${GITHUB_REPOSITORY}/releases/tags/nightly" \
| python3 -c "
import json,sys
try:
r = json.load(sys.stdin)
sha = r.get('target_commitish','')
print(sha if len(sha) == 40 else '')
except Exception:
print('')")
if [ "$PREV" = "$SHA" ]; then
echo "[INFO] [nightly] public HEAD unchanged since last nightly — nothing to build"
echo "go=false" >> "$GITHUB_OUTPUT"
exit 0
fi
BASE=$(grep -P '^\s*AgentVersion\s*=' server/internal/version/versions.go | grep -oP '"\K[^"]+')
VERSION="${BASE}-nightly.$(date -u +%Y%m%d).${SHORT}"
{
echo "go=true"
echo "sha=$SHA"
echo "short=$SHORT"
echo "prev=$PREV"
echo "version=$VERSION"
} >> "$GITHUB_OUTPUT"
echo "Building nightly $VERSION (prev nightly: ${PREV:-none})"
- uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5
if: steps.pre.outputs.go == 'true'
with:
go-version-file: agent/go.mod
cache: true
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
if: steps.pre.outputs.go == 'true'
with:
node-version: 20
cache: npm
cache-dependency-path: web/package-lock.json
- uses: dtolnay/rust-toolchain@4360b52568e2003a75bf9bc1d59f33a8e3fc893c # stable
if: steps.pre.outputs.go == 'true'
- name: Build web UI and stage embed
if: steps.pre.outputs.go == 'true'
run: |
set -euo pipefail
cd web && npm ci && npm run build && cd ..
rm -rf server/internal/webui/dist
cp -r web/dist server/internal/webui/dist
test -s server/internal/webui/dist/index.html
# Agent + helper only. The server is NOT shipped on the nightly channel:
# its supported install paths are docker-compose-from-source today and the
# per-OS installers landing in v0.3.0 — both verify the signed release
# manifest, which nightly deliberately does not generate. Shipping a bare
# nightly server tarball would be an install artifact with a stub manifest,
# so it's left to the versioned (v*) channel where the manifest is real.
- name: Build agent + helper binaries (linux-amd64 + windows-amd64)
if: steps.pre.outputs.go == 'true'
run: |
set -euo pipefail
VERSION="${{ steps.pre.outputs.version }}"
mkdir -p dist
build_agent () { # $1=goos $2=suffix $3=ext
GOOS=$1 GOARCH=amd64 CGO_ENABLED=0 sh -c "
cd agent && go build -ldflags \"-s -w \
-X github.com/Fimeg/RedFlag/agent/internal/version.Version=$VERSION \
-X github.com/Fimeg/RedFlag/agent/internal/version.ConfigVersion=$VERSION \
-X github.com/Fimeg/RedFlag/agent/internal/version.BuildTime=$(date -u +%Y-%m-%dT%H:%M:%SZ)\" \
-o ../dist/redflag-agent-$2$3 ./cmd/agent/"
}
build_agent linux linux-amd64 ""
build_agent windows windows-amd64 ".exe"
cd helper && cargo build --release && cd ..
cp helper/target/release/redflag-helper dist/redflag-helper-linux-amd64
- name: Package
if: steps.pre.outputs.go == 'true'
run: |
set -euo pipefail
VERSION="${{ steps.pre.outputs.version }}"
cd dist
tar czf redflag-$VERSION-linux-amd64.tar.gz redflag-agent-linux-amd64 redflag-helper-linux-amd64
zip -q redflag-$VERSION-windows-amd64.zip redflag-agent-windows-amd64.exe
sha256sum redflag-$VERSION-linux-amd64.tar.gz redflag-$VERSION-windows-amd64.zip > checksums-$VERSION.txt
ls -la
- name: Write release notes
if: steps.pre.outputs.go == 'true'
run: |
set -euo pipefail
SHA="${{ steps.pre.outputs.sha }}"
PREV="${{ steps.pre.outputs.prev }}"
VERSION="${{ steps.pre.outputs.version }}"
{
echo "Nightly alpha build — untagged channel, replaced every night. Agent + helper test binaries only; not fleet-upgradable (no manifest). Install the server from a versioned (v*) release or build from source."
echo ""
echo "version: $VERSION"
echo "commit: $SHA"
echo "built: $(date -u +%Y-%m-%dT%H:%M:%SZ)"
echo ""
if [ -n "$PREV" ] && git cat-file -e "$PREV" 2>/dev/null; then
echo "### Since last nightly"
echo '```'
git log --oneline --no-decorate "$PREV..$SHA" | head -50
echo '```'
fi
} > notes.md
cat notes.md
- name: Publish nightly release (Gitea)
if: steps.pre.outputs.go == 'true'
run: |
set -euo pipefail
API="${GITHUB_SERVER_URL}/api/v1/repos/${GITHUB_REPOSITORY}"
TOKEN="${{ secrets.GITHUB_TOKEN }}"
SHA="${{ steps.pre.outputs.sha }}"
VERSION="${{ steps.pre.outputs.version }}"
RID=$(curl -s -H "Authorization: token $TOKEN" "$API/releases/tags/nightly" \
| python3 -c "
import json,sys
try: print(json.load(sys.stdin).get('id',''))
except Exception: print('')")
[ -n "$RID" ] && curl -s -X DELETE -H "Authorization: token $TOKEN" "$API/releases/$RID"
curl -s -o /dev/null -X DELETE -H "Authorization: token $TOKEN" "$API/tags/nightly" || true
BODY=$(python3 -c "import json; print(json.dumps(open('notes.md').read()))")
RID=$(curl -sf -X POST "$API/releases" \
-H "Authorization: token $TOKEN" -H "Content-Type: application/json" \
-d "{\"tag_name\":\"nightly\",\"target_commitish\":\"$SHA\",\"name\":\"nightly $VERSION\",\"prerelease\":true,\"draft\":false,\"body\":$BODY}" \
| python3 -c "import json,sys; print(json.load(sys.stdin)['id'])")
for f in dist/redflag-$VERSION-linux-amd64.tar.gz dist/redflag-$VERSION-windows-amd64.zip dist/checksums-$VERSION.txt; do
curl -sf -o /dev/null -X POST "$API/releases/$RID/assets?name=$(basename "$f")" \
-H "Authorization: token $TOKEN" -F "attachment=@$f"
done
echo "Gitea nightly published (release id=$RID)"