The sed pattern on the store path basename gave 'tar.gz' because buildLayeredImage outputs 'openclaw.tar.gz'. Use imageTag attribute which returns the actual tag (e.g., '2026.4.14').
191 lines
6.9 KiB
YAML
191 lines
6.9 KiB
YAML
name: CI
|
|
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
pull_request:
|
|
branches: [main]
|
|
|
|
jobs:
|
|
check:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
|
|
- uses: https://git.johnogle.info/johno/gitea-actions/nix-setup@v1
|
|
|
|
- name: Check flake
|
|
run: nix flake check
|
|
env:
|
|
NIX_CONFIG: "access-tokens = git.johnogle.info=${{ secrets.GITEA_ACCESS_TOKEN }}"
|
|
|
|
build-and-cache:
|
|
runs-on: ubuntu-latest
|
|
needs: check
|
|
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
|
|
- uses: https://git.johnogle.info/johno/gitea-actions/nix-setup@v1
|
|
|
|
- name: Setup SSH for cache
|
|
run: |
|
|
mkdir -p ~/.ssh
|
|
echo "${{ secrets.CACHE_SSH_KEY }}" > ~/.ssh/cache_key
|
|
chmod 600 ~/.ssh/cache_key
|
|
ssh-keyscan -H ${{ secrets.CACHE_HOST }} >> ~/.ssh/known_hosts 2>/dev/null || true
|
|
|
|
- name: Setup signing key
|
|
run: |
|
|
echo "${{ secrets.NIX_SIGNING_KEY }}" > /tmp/signing-key
|
|
chmod 600 /tmp/signing-key
|
|
|
|
- name: Build, sign, and cache all packages
|
|
run: |
|
|
PACKAGES=(
|
|
custom-claude-code
|
|
custom-app-launcher-server
|
|
custom-mcrcon-rbw
|
|
custom-tea-rbw
|
|
custom-rclone-torbox-setup
|
|
custom-opencode
|
|
custom-qmd
|
|
custom-nextcloud-talk-desktop
|
|
qt-pinned-jellyfin-media-player
|
|
qt-pinned-stremio
|
|
nix-deck-kernel
|
|
)
|
|
|
|
FAILED=()
|
|
SKIPPED=()
|
|
for pkg in "${PACKAGES[@]}"; do
|
|
echo "::group::Building $pkg"
|
|
|
|
# Check if package is already cached by evaluating its store path and checking the remote
|
|
OUT_PATH=$(nix eval ".#$pkg.outPath" --raw 2>/dev/null)
|
|
if [ -n "$OUT_PATH" ] && ssh -i ~/.ssh/cache_key ${{ secrets.CACHE_USER }}@${{ secrets.CACHE_HOST }} \
|
|
"nix path-info '$OUT_PATH' >/dev/null 2>&1"; then
|
|
echo "⏭ $pkg already cached ($OUT_PATH), skipping"
|
|
SKIPPED+=("$pkg")
|
|
echo "::endgroup::"
|
|
continue
|
|
fi
|
|
|
|
# --cores 2 limits parallel jobs to reduce RAM pressure on john-endesktop
|
|
if BUILD_OUTPUT=$(nix build ".#$pkg" --no-link --print-out-paths --cores 2 2>&1); then
|
|
OUT_PATH=$(echo "$BUILD_OUTPUT" | grep '^/nix/store/' | tail -1)
|
|
echo "$BUILD_OUTPUT"
|
|
echo "Store path: $OUT_PATH"
|
|
|
|
# Sign the closure
|
|
nix store sign --key-file /tmp/signing-key -r "$OUT_PATH"
|
|
|
|
# Push to cache
|
|
nix copy --to "ssh-ng://${{ secrets.CACHE_USER }}@${{ secrets.CACHE_HOST }}?ssh-key=$HOME/.ssh/cache_key" "$OUT_PATH"
|
|
|
|
# Create GC root to prevent garbage collection
|
|
OUT_HASH=$(basename "$OUT_PATH" | cut -d'-' -f1)
|
|
ssh -i ~/.ssh/cache_key ${{ secrets.CACHE_USER }}@${{ secrets.CACHE_HOST }} \
|
|
"mkdir -p /nix/var/nix/gcroots/ci-cache && ln -sfn $OUT_PATH /nix/var/nix/gcroots/ci-cache/${OUT_HASH}"
|
|
|
|
echo "✓ $pkg cached successfully"
|
|
else
|
|
echo "✗ $pkg failed to build"
|
|
FAILED+=("$pkg")
|
|
fi
|
|
echo "::endgroup::"
|
|
done
|
|
|
|
if [ ${#SKIPPED[@]} -gt 0 ]; then
|
|
echo "Skipped (already cached): ${SKIPPED[*]}"
|
|
fi
|
|
|
|
if [ ${#FAILED[@]} -gt 0 ]; then
|
|
echo "::error::Failed packages: ${FAILED[*]}"
|
|
exit 1
|
|
fi
|
|
env:
|
|
NIX_CONFIG: "access-tokens = git.johnogle.info=${{ secrets.GITEA_ACCESS_TOKEN }}"
|
|
|
|
build-and-push-openclaw:
|
|
name: Build & Push OpenClaw Image
|
|
runs-on: ubuntu-latest
|
|
needs: check
|
|
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
|
outputs:
|
|
image_tag: ${{ steps.meta.outputs.tag }}
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
|
|
- uses: https://git.johnogle.info/johno/gitea-actions/nix-setup@v1
|
|
|
|
- name: Setup SSH for cache
|
|
run: |
|
|
mkdir -p ~/.ssh
|
|
echo "${{ secrets.CACHE_SSH_KEY }}" > ~/.ssh/cache_key
|
|
chmod 600 ~/.ssh/cache_key
|
|
ssh-keyscan -H ${{ secrets.CACHE_HOST }} >> ~/.ssh/known_hosts 2>/dev/null || true
|
|
|
|
- name: Generate image tag
|
|
id: meta
|
|
run: |
|
|
# Read the image tag from the nix definition's tag attribute
|
|
# buildLayeredImage sets tag from openclawImageTag in default.nix
|
|
IMAGE_TAG=$(nix eval .#packages.x86_64-linux.openclaw-image.imageTag --raw 2>/dev/null || \
|
|
nix eval .#openclaw-image.imageTag --raw 2>/dev/null || \
|
|
nix eval .#openclaw-image.outPath --raw 2>/dev/null | xargs basename | sed 's/.*-//')
|
|
# Fallback to short SHA if tag extraction fails
|
|
if [ -z "$IMAGE_TAG" ] || [ "$IMAGE_TAG" = "tar.gz" ]; then
|
|
IMAGE_TAG=$(echo "${{ github.sha }}" | cut -c1-7)
|
|
fi
|
|
echo "tag=${IMAGE_TAG}" >> $GITHUB_OUTPUT
|
|
echo "Image will be tagged: ${IMAGE_TAG}"
|
|
|
|
- name: Build Docker image with Nix
|
|
run: nix build .#openclaw-image --cores 2
|
|
env:
|
|
NIX_CONFIG: "access-tokens = git.johnogle.info=${{ secrets.GITEA_ACCESS_TOKEN }}"
|
|
|
|
- name: Load and tag image
|
|
run: |
|
|
docker load < result
|
|
docker tag openclaw:${{ steps.meta.outputs.tag }} registry.johnogle.info/openclaw:${{ steps.meta.outputs.tag }}
|
|
docker tag openclaw:${{ steps.meta.outputs.tag }} registry.johnogle.info/openclaw:latest
|
|
|
|
- name: Login to registry
|
|
run: |
|
|
echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login registry.johnogle.info -u ${{ secrets.REGISTRY_USERNAME }} --password-stdin
|
|
|
|
- name: Push image
|
|
run: |
|
|
docker push registry.johnogle.info/openclaw:${{ steps.meta.outputs.tag }}
|
|
docker push registry.johnogle.info/openclaw:latest
|
|
|
|
deploy-openclaw:
|
|
name: Deploy OpenClaw to Cluster
|
|
runs-on: ubuntu-latest
|
|
needs: build-and-push-openclaw
|
|
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
|
|
steps:
|
|
- name: Checkout k3s-cluster-config
|
|
uses: actions/checkout@v4
|
|
with:
|
|
repository: johno/k3s-cluster-config
|
|
token: ${{ secrets.CONFIG_REPO_TOKEN }}
|
|
path: k3s-cluster-config
|
|
|
|
- name: Update HelmRelease image tag
|
|
run: |
|
|
cd k3s-cluster-config
|
|
sed -i 's|tag: ".*"|tag: "${{ needs.build-and-push-openclaw.outputs.image_tag }}"|' \
|
|
clusters/oglenet/apps/communication/openclaw.yaml
|
|
|
|
- name: Commit and push
|
|
run: |
|
|
cd k3s-cluster-config
|
|
git config user.name "Gitea CI"
|
|
git config user.email "ci@johnogle.info"
|
|
git add clusters/oglenet/apps/communication/openclaw.yaml
|
|
git diff --cached --quiet || git commit -m "Deploy openclaw:${{ needs.build-and-push-openclaw.outputs.image_tag }}"
|
|
git push
|