feat(devops): add Gitea CI (act_runner) to Azure VM setup
- Phase 2: install act_runner binary, register with Gitea, create systemd service - Phase 3: push all 11 repos to VM Gitea after cloning from GitHub - Expanded Gitea API token scopes (write:repository, write:user) - Runner config: host mode, capacity 2, GITEA_NPM_TOKEN injected - Enables CI on the VM for NETWORK!=corp usage
This commit is contained in:
parent
aa139d5021
commit
70fdc6b279
@ -8,7 +8,8 @@
|
||||
# What gets installed:
|
||||
# - Docker CE + Docker Compose + BuildKit
|
||||
# - Node.js 22 LTS + pnpm 10.6.5
|
||||
# - Gitea (Docker container — npm package registry on :3300)
|
||||
# - Gitea (Docker container — npm package registry + CI on :3300)
|
||||
# - act_runner (Gitea CI runner — systemd service, host mode)
|
||||
# - Ollama (local LLM inference for LocalMemGPT on :11434)
|
||||
# - All 11 ByteLyst repos (cloned from GitHub)
|
||||
# - All @bytelyst/* packages (built + published to Gitea)
|
||||
@ -26,8 +27,8 @@
|
||||
#
|
||||
# Phases:
|
||||
# 1 System dependencies (Docker, Node, pnpm, Ollama)
|
||||
# 2 Gitea npm registry (container on :3300)
|
||||
# 3 Clone 11 repositories from GitHub
|
||||
# 2 Gitea npm registry + CI runner (container on :3300 + act_runner systemd)
|
||||
# 3 Clone 11 repositories from GitHub + push to Gitea
|
||||
# 4 Build all @bytelyst/* packages
|
||||
# 5 Publish packages to Gitea npm registry
|
||||
# 6 Generate .env.ecosystem config
|
||||
@ -332,7 +333,7 @@ phase2_gitea() {
|
||||
token_response=$(curl -sf -X POST "${GITEA_URL}/api/v1/users/${GITEA_ADMIN}/tokens" \
|
||||
-H "$AUTH_HEADER" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name":"vm-deploy","scopes":["write:package","read:package","write:organization","read:organization"]}')
|
||||
-d '{"name":"vm-deploy","scopes":["write:package","read:package","write:organization","read:organization","write:repository","read:repository","write:user","read:user"]}')
|
||||
|
||||
GITEA_NPM_TOKEN=$(echo "$token_response" | jq -r '.sha1 // .token' 2>/dev/null || echo "")
|
||||
if [ -z "$GITEA_NPM_TOKEN" ] || [ "$GITEA_NPM_TOKEN" = "null" ]; then
|
||||
@ -344,7 +345,121 @@ phase2_gitea() {
|
||||
echo "$GITEA_NPM_TOKEN" > "${INSTALL_DIR}/.gitea_token"
|
||||
chmod 600 "${INSTALL_DIR}/.gitea_token"
|
||||
|
||||
ok "Phase 2 complete. Gitea running at http://localhost:${GITEA_PORT}"
|
||||
# ── Install act_runner (Gitea CI) ─────────────────────────────────
|
||||
log "Installing act_runner for Gitea CI..."
|
||||
|
||||
local RUNNER_VERSION="0.3.0"
|
||||
local RUNNER_ARCH
|
||||
RUNNER_ARCH=$(dpkg --print-architecture) # amd64 or arm64
|
||||
local RUNNER_BIN="/usr/local/bin/act_runner"
|
||||
|
||||
if [ ! -f "$RUNNER_BIN" ]; then
|
||||
local runner_url="https://gitea.com/gitea/act_runner/releases/download/v${RUNNER_VERSION}/act_runner-${RUNNER_VERSION}-linux-${RUNNER_ARCH}"
|
||||
curl -sfL "$runner_url" -o "$RUNNER_BIN" || fail "Failed to download act_runner v${RUNNER_VERSION}"
|
||||
chmod +x "$RUNNER_BIN"
|
||||
ok "act_runner v${RUNNER_VERSION} installed."
|
||||
else
|
||||
ok "act_runner already installed."
|
||||
fi
|
||||
|
||||
# Create runner data directory
|
||||
local RUNNER_DIR="${INSTALL_DIR}/.act_runner"
|
||||
mkdir -p "$RUNNER_DIR"
|
||||
|
||||
# Register runner (idempotent — skip if already registered)
|
||||
if [ ! -f "${RUNNER_DIR}/.runner" ]; then
|
||||
# Get a runner registration token from Gitea API
|
||||
local reg_token_resp
|
||||
reg_token_resp=$(curl -sf -X POST "${GITEA_URL}/api/v1/admin/runners/registration-token" \
|
||||
-H "$AUTH_HEADER" \
|
||||
-H "Content-Type: application/json" 2>/dev/null || echo "")
|
||||
|
||||
local reg_token
|
||||
reg_token=$(echo "$reg_token_resp" | jq -r '.token' 2>/dev/null || echo "")
|
||||
|
||||
if [ -z "$reg_token" ] || [ "$reg_token" = "null" ]; then
|
||||
warn "Could not get runner registration token (Gitea may not support this API). Trying alternate method..."
|
||||
# Fallback: use the Gitea admin API (older versions)
|
||||
reg_token_resp=$(curl -sf "${GITEA_URL}/api/v1/admin/runners/registration-token" \
|
||||
-H "Authorization: token ${GITEA_NPM_TOKEN}" 2>/dev/null || echo "")
|
||||
reg_token=$(echo "$reg_token_resp" | jq -r '.token' 2>/dev/null || echo "")
|
||||
fi
|
||||
|
||||
if [ -z "$reg_token" ] || [ "$reg_token" = "null" ]; then
|
||||
warn "Could not obtain runner registration token. act_runner will need manual registration."
|
||||
warn "Run: act_runner register --instance http://localhost:${GITEA_PORT} --token <TOKEN>"
|
||||
else
|
||||
cd "$RUNNER_DIR"
|
||||
"$RUNNER_BIN" register \
|
||||
--instance "http://localhost:${GITEA_PORT}" \
|
||||
--token "$reg_token" \
|
||||
--name "bytelyst-vm" \
|
||||
--labels "ubuntu-latest:host,self-hosted:host" \
|
||||
--no-interactive 2>/dev/null || true
|
||||
ok "act_runner registered with Gitea."
|
||||
fi
|
||||
else
|
||||
ok "act_runner already registered."
|
||||
fi
|
||||
|
||||
# Generate runner config
|
||||
cat > "${RUNNER_DIR}/config.yaml" <<RUNNER_CFG
|
||||
log:
|
||||
level: info
|
||||
runner:
|
||||
file: ${RUNNER_DIR}/.runner
|
||||
capacity: 2
|
||||
envs:
|
||||
PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||
HOME: /root
|
||||
NODE_ENV: test
|
||||
GITEA_NPM_TOKEN: ${GITEA_NPM_TOKEN}
|
||||
GITEA_NPM_HOST: localhost
|
||||
timeout: 30m
|
||||
shutdown_timeout: 10s
|
||||
insecure: false
|
||||
fetch_timeout: 5s
|
||||
fetch_interval: 2s
|
||||
labels:
|
||||
- "ubuntu-latest:host"
|
||||
- "self-hosted:host"
|
||||
cache:
|
||||
enabled: true
|
||||
container:
|
||||
docker_host: "-"
|
||||
force_pull: false
|
||||
require_docker: false
|
||||
host:
|
||||
workdir_parent: ${INSTALL_DIR}/.cache/act
|
||||
RUNNER_CFG
|
||||
|
||||
mkdir -p "${INSTALL_DIR}/.cache/act"
|
||||
|
||||
# Create systemd service (idempotent)
|
||||
cat > /etc/systemd/system/act-runner.service <<SYSTEMD_SVC
|
||||
[Unit]
|
||||
Description=Gitea Act Runner
|
||||
After=network.target docker.service
|
||||
Wants=docker.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
WorkingDirectory=${RUNNER_DIR}
|
||||
ExecStart=${RUNNER_BIN} daemon --config ${RUNNER_DIR}/config.yaml
|
||||
Restart=on-failure
|
||||
RestartSec=10
|
||||
Environment="HOME=/root"
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
SYSTEMD_SVC
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable act-runner.service 2>/dev/null || true
|
||||
systemctl restart act-runner.service 2>/dev/null || true
|
||||
ok "act_runner systemd service started."
|
||||
|
||||
ok "Phase 2 complete. Gitea running at http://localhost:${GITEA_PORT}, CI runner active."
|
||||
}
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════
|
||||
@ -378,7 +493,42 @@ phase3_clone() {
|
||||
# (commit fix(docker) across all 10 product repos + dashboards).
|
||||
# No runtime sed stripping needed.
|
||||
|
||||
ok "Phase 3 complete. All repos in ${INSTALL_DIR}/"
|
||||
# ── Push repos to VM Gitea (enables CI triggers on push) ──────────
|
||||
log "Pushing repos to VM Gitea (CI will trigger on push)..."
|
||||
require_gitea_token
|
||||
|
||||
local GITEA_URL="http://localhost:${GITEA_PORT}"
|
||||
local GITEA_PUSH_URL="http://${GITEA_ADMIN}:${GITEA_PASS}@localhost:${GITEA_PORT}/bytelyst"
|
||||
|
||||
for repo in "${REPOS[@]}"; do
|
||||
local target="${INSTALL_DIR}/${repo}"
|
||||
[ -d "$target/.git" ] || continue
|
||||
|
||||
# Create repo in Gitea org if it doesn't exist (idempotent)
|
||||
local repo_status
|
||||
repo_status=$(curl -sf -o /dev/null -w "%{http_code}" \
|
||||
-H "Authorization: token ${GITEA_NPM_TOKEN}" \
|
||||
"${GITEA_URL}/api/v1/repos/bytelyst/${repo}" 2>/dev/null || echo "000")
|
||||
|
||||
if [ "$repo_status" != "200" ]; then
|
||||
curl -sf -X POST "${GITEA_URL}/api/v1/orgs/bytelyst/repos" \
|
||||
-H "Authorization: token ${GITEA_NPM_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"name\":\"${repo}\",\"default_branch\":\"main\",\"auto_init\":false}" > /dev/null 2>&1 || true
|
||||
fi
|
||||
|
||||
# Add gitea remote and push (idempotent)
|
||||
cd "$target"
|
||||
git remote remove gitea 2>/dev/null || true
|
||||
git remote add gitea "${GITEA_PUSH_URL}/${repo}.git"
|
||||
if git push gitea main 2>/dev/null; then
|
||||
log " Pushed: $repo"
|
||||
else
|
||||
warn " Push failed (non-fatal): $repo"
|
||||
fi
|
||||
done
|
||||
|
||||
ok "Phase 3 complete. All repos in ${INSTALL_DIR}/ and pushed to Gitea."
|
||||
}
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════
|
||||
@ -845,8 +995,8 @@ usage() {
|
||||
echo ""
|
||||
echo "Phases:"
|
||||
echo " 1 System dependencies (Docker, Node, pnpm, Ollama)"
|
||||
echo " 2 Gitea npm registry"
|
||||
echo " 3 Clone repositories"
|
||||
echo " 2 Gitea npm registry + CI runner"
|
||||
echo " 3 Clone repositories + push to Gitea"
|
||||
echo " 4 Build @bytelyst/* packages"
|
||||
echo " 5 Publish packages to Gitea"
|
||||
echo " 6 Generate .env.ecosystem"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user