mirror of
https://github.com/tiennm99/goclaw.git
synced 2026-10-13 18:15:34 +00:00
feat(ci): automate dev beta releases
This commit is contained in:
1 parent
d57d3810e4
commit
9a6fd2dec9
4 files changed
+515
-2
No files matched your search
@@ -0,0 +1,320 @@
|
||||
name: Dev CI and Beta Release
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [dev]
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: dev-beta-release-${{ github.ref }}
|
||||
cancel-in-progress: false
|
||||
|
||||
env:
|
||||
GHCR_IMAGE: ghcr.io/${{ github.repository }}
|
||||
DOCKERHUB_IMAGE: digitop/goclaw
|
||||
INITIAL_VERSION: 3.11.3
|
||||
PRERELEASE_ID: beta
|
||||
|
||||
jobs:
|
||||
go:
|
||||
runs-on: ubuntu-latest
|
||||
services:
|
||||
pg:
|
||||
image: pgvector/pgvector:pg18
|
||||
env:
|
||||
POSTGRES_PASSWORD: test
|
||||
POSTGRES_DB: goclaw_test
|
||||
ports:
|
||||
- 5432:5432
|
||||
options: >-
|
||||
--health-cmd "pg_isready -U postgres"
|
||||
--health-interval 5s
|
||||
--health-timeout 3s
|
||||
--health-retries 10
|
||||
env:
|
||||
TEST_DATABASE_URL: postgres://postgres:test@localhost:5432/goclaw_test?sslmode=disable
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
cache-dependency-path: go.sum
|
||||
- run: go build ./...
|
||||
- run: go build -tags sqliteonly ./...
|
||||
- run: go vet ./...
|
||||
- name: Unit tests
|
||||
run: go test -race -timeout=5m -coverpkg=./... -coverprofile=coverage.out ./...
|
||||
- name: Invariant tests (P0)
|
||||
run: go test -race -timeout=90s -tags integration ./tests/invariants/...
|
||||
- name: Contract tests (P1)
|
||||
run: go test -race -timeout=90s -tags integration ./tests/contracts/... || echo "::warning::Contract tests skipped (no server configured)"
|
||||
continue-on-error: true
|
||||
- name: Integration tests
|
||||
run: go test -race -timeout=180s -tags integration ./tests/integration/
|
||||
- name: Coverage summary
|
||||
run: go tool cover -func=coverage.out | tail -1
|
||||
|
||||
web:
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ui/web
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 10
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22
|
||||
cache: pnpm
|
||||
cache-dependency-path: ui/web/pnpm-lock.yaml
|
||||
- run: pnpm install --frozen-lockfile
|
||||
- run: pnpm lint
|
||||
- run: pnpm build
|
||||
|
||||
release_preflight:
|
||||
needs: [go, web]
|
||||
if: github.ref == 'refs/heads/dev'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Validate release secrets
|
||||
env:
|
||||
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
run: |
|
||||
test -n "$DOCKERHUB_USERNAME" || { echo "::error::Missing DOCKERHUB_USERNAME secret"; exit 1; }
|
||||
test -n "$DOCKERHUB_TOKEN" || { echo "::error::Missing DOCKERHUB_TOKEN secret"; exit 1; }
|
||||
|
||||
beta_version:
|
||||
needs: [go, web, release_preflight]
|
||||
if: github.ref == 'refs/heads/dev'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
outputs:
|
||||
released: ${{ steps.version.outputs.released }}
|
||||
version: ${{ steps.version.outputs.version }}
|
||||
tag: ${{ steps.version.outputs.tag }}
|
||||
notes_path: ${{ steps.version.outputs.notes_path }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Fetch upstream release tags
|
||||
run: git fetch --force --tags https://github.com/nextlevelbuilder/goclaw.git "refs/tags/v*:refs/tags/v*"
|
||||
- name: Compute semantic beta version
|
||||
id: version
|
||||
run: node scripts/ci/semantic-beta-version.mjs
|
||||
- name: Create or verify beta tag
|
||||
if: steps.version.outputs.released == 'true'
|
||||
env:
|
||||
TAG: ${{ steps.version.outputs.tag }}
|
||||
run: |
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||
if ! git rev-parse "$TAG" >/dev/null 2>&1; then
|
||||
git tag -a "$TAG" -m "Release $TAG"
|
||||
git push origin "$TAG"
|
||||
fi
|
||||
- name: Upload release notes
|
||||
if: steps.version.outputs.released == 'true'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: release-notes
|
||||
path: ${{ steps.version.outputs.notes_path }}
|
||||
|
||||
build_binaries:
|
||||
needs: beta_version
|
||||
if: needs.beta_version.outputs.released == 'true'
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- goos: linux
|
||||
goarch: amd64
|
||||
- goos: linux
|
||||
goarch: arm64
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ needs.beta_version.outputs.tag }}
|
||||
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
cache-dependency-path: go.sum
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22
|
||||
|
||||
- name: Build web UI
|
||||
run: |
|
||||
corepack enable && corepack prepare pnpm@10.28.2 --activate
|
||||
cd ui/web && pnpm install --frozen-lockfile && pnpm build && cd ../..
|
||||
mkdir -p internal/webui/dist
|
||||
cp -r ui/web/dist/* internal/webui/dist/
|
||||
|
||||
- name: Build binary
|
||||
env:
|
||||
GOOS: ${{ matrix.goos }}
|
||||
GOARCH: ${{ matrix.goarch }}
|
||||
VERSION: ${{ needs.beta_version.outputs.tag }}
|
||||
run: |
|
||||
CGO_ENABLED=0 go build -tags embedui \
|
||||
-ldflags="-s -w -X github.com/nextlevelbuilder/goclaw/cmd.Version=${VERSION}" \
|
||||
-o goclaw .
|
||||
tar -czf "goclaw-${VERSION}-${{ matrix.goos }}-${{ matrix.goarch }}.tar.gz" goclaw migrations/
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: binary-${{ matrix.goos }}-${{ matrix.goarch }}
|
||||
path: goclaw-*.tar.gz
|
||||
|
||||
publish_release:
|
||||
needs: [beta_version, build_binaries, promote_beta_aliases]
|
||||
if: needs.beta_version.outputs.released == 'true'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Download all artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
pattern: binary-*
|
||||
path: artifacts
|
||||
merge-multiple: true
|
||||
|
||||
- name: Download release notes
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: release-notes
|
||||
path: release-notes
|
||||
|
||||
- name: Publish prerelease
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
TAG: ${{ needs.beta_version.outputs.tag }}
|
||||
run: |
|
||||
if gh release view "$TAG" >/dev/null 2>&1; then
|
||||
gh release edit "$TAG" \
|
||||
--title "GoClaw $TAG" \
|
||||
--notes-file release-notes/release-notes.md \
|
||||
--prerelease
|
||||
else
|
||||
gh release create "$TAG" \
|
||||
--title "GoClaw $TAG" \
|
||||
--notes-file release-notes/release-notes.md \
|
||||
--prerelease
|
||||
fi
|
||||
gh release upload "$TAG" artifacts/* --clobber
|
||||
|
||||
docker_images:
|
||||
needs: beta_version
|
||||
if: needs.beta_version.outputs.released == 'true'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- variant: latest
|
||||
suffix: ""
|
||||
enable_otel: "false"
|
||||
enable_embedui: "true"
|
||||
enable_python: "true"
|
||||
enable_full_skills: "false"
|
||||
- variant: full
|
||||
suffix: "-full"
|
||||
enable_otel: "false"
|
||||
enable_embedui: "true"
|
||||
enable_python: "true"
|
||||
enable_full_skills: "true"
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ needs.beta_version.outputs.tag }}
|
||||
|
||||
- uses: docker/setup-qemu-action@v3
|
||||
|
||||
- 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: Log in to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Extract metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: |
|
||||
${{ env.GHCR_IMAGE }}
|
||||
${{ env.DOCKERHUB_IMAGE }}
|
||||
tags: |
|
||||
type=raw,value=${{ needs.beta_version.outputs.tag }},suffix=${{ matrix.suffix }}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
build-args: |
|
||||
ENABLE_OTEL=${{ matrix.enable_otel }}
|
||||
ENABLE_EMBEDUI=${{ matrix.enable_embedui }}
|
||||
ENABLE_PYTHON=${{ matrix.enable_python }}
|
||||
ENABLE_FULL_SKILLS=${{ matrix.enable_full_skills }}
|
||||
VERSION=${{ needs.beta_version.outputs.tag }}
|
||||
cache-from: type=gha,scope=dev-beta-${{ matrix.variant }}
|
||||
cache-to: type=gha,mode=max,scope=dev-beta-${{ matrix.variant }}
|
||||
|
||||
promote_beta_aliases:
|
||||
needs: [beta_version, docker_images]
|
||||
if: needs.beta_version.outputs.released == 'true'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
steps:
|
||||
- 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: Log in to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Promote beta aliases
|
||||
env:
|
||||
TAG: ${{ needs.beta_version.outputs.tag }}
|
||||
run: |
|
||||
docker buildx imagetools create -t "${GHCR_IMAGE}:beta" "${GHCR_IMAGE}:${TAG}"
|
||||
docker buildx imagetools create -t "${GHCR_IMAGE}:beta-full" "${GHCR_IMAGE}:${TAG}-full"
|
||||
docker buildx imagetools create -t "${DOCKERHUB_IMAGE}:beta" "${DOCKERHUB_IMAGE}:${TAG}"
|
||||
docker buildx imagetools create -t "${DOCKERHUB_IMAGE}:beta-full" "${DOCKERHUB_IMAGE}:${TAG}-full"
|
||||
Reference in new issue
Block a user