From 93cba2f3918fb16d1de51bfe27bae602933392fc Mon Sep 17 00:00:00 2001 From: Huarch Date: Mon, 11 May 2026 17:15:25 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=20gitea=20=E5=B7=A5=E4=BD=9C?= =?UTF-8?q?=E6=B5=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitea/workflows/package.yml | 217 +++++++++++++++++++++++++++++++++++ 1 file changed, 217 insertions(+) create mode 100644 .gitea/workflows/package.yml diff --git a/.gitea/workflows/package.yml b/.gitea/workflows/package.yml new file mode 100644 index 0000000..3643f52 --- /dev/null +++ b/.gitea/workflows/package.yml @@ -0,0 +1,217 @@ +name: Agent CI/CD + +on: + pull_request: + push: + branches: + - main + - master + tags: + - "v*" + - "latest" + +jobs: + validate: + runs-on: ubuntu-22.04 + permissions: + contents: read + defaults: + run: + shell: bash + + steps: + - name: Checkout code + env: + SERVER_URL: ${{ github.server_url }} + REPOSITORY: ${{ github.repository }} + COMMIT_SHA: ${{ github.sha }} + GIT_USERNAME: ${{ github.actor }} + GIT_TOKEN: ${{ github.token }} + run: | + case "$SERVER_URL" in + http://*) + AUTH_SERVER_URL="http://${GIT_USERNAME}:${GIT_TOKEN}@${SERVER_URL#http://}" + ;; + https://*) + AUTH_SERVER_URL="https://${GIT_USERNAME}:${GIT_TOKEN}@${SERVER_URL#https://}" + ;; + *) + AUTH_SERVER_URL="$SERVER_URL" + ;; + esac + + if [ ! -d .git ]; then + git init . + fi + + if git remote get-url origin >/dev/null 2>&1; then + git remote set-url origin "${AUTH_SERVER_URL}/${REPOSITORY}.git" + else + git remote add origin "${AUTH_SERVER_URL}/${REPOSITORY}.git" + fi + + git fetch --depth=1 origin "$COMMIT_SHA" + git checkout --force --detach FETCH_HEAD + git clean -ffdx + + - name: Install Bun + run: | + curl -fsSL https://bun.sh/install | bash + echo "$HOME/.bun/bin" >> "$GITHUB_PATH" + + - name: Install dependencies + run: bun install --frozen-lockfile + + - name: Run checks + run: bun run check + + docker-image: + runs-on: ubuntu-22.04 + needs: validate + if: startsWith(github.ref, 'refs/tags/') + permissions: + contents: read + defaults: + run: + shell: bash + + steps: + - name: Checkout code + env: + SERVER_URL: ${{ github.server_url }} + REPOSITORY: ${{ github.repository }} + COMMIT_SHA: ${{ github.sha }} + GIT_USERNAME: ${{ github.actor }} + GIT_TOKEN: ${{ github.token }} + run: | + case "$SERVER_URL" in + http://*) + AUTH_SERVER_URL="http://${GIT_USERNAME}:${GIT_TOKEN}@${SERVER_URL#http://}" + ;; + https://*) + AUTH_SERVER_URL="https://${GIT_USERNAME}:${GIT_TOKEN}@${SERVER_URL#https://}" + ;; + *) + AUTH_SERVER_URL="$SERVER_URL" + ;; + esac + + if [ ! -d .git ]; then + git init . + fi + + if git remote get-url origin >/dev/null 2>&1; then + git remote set-url origin "${AUTH_SERVER_URL}/${REPOSITORY}.git" + else + git remote add origin "${AUTH_SERVER_URL}/${REPOSITORY}.git" + fi + + git fetch --depth=1 origin "$COMMIT_SHA" + git checkout --force --detach FETCH_HEAD + git clean -ffdx + + - name: Normalize image metadata + env: + RAW_REGISTRY_HOST: ${{ vars.REGISTRY_HOST }} + RAW_REPOSITORY: ${{ github.repository }} + IMAGE_TAG: ${{ github.ref_name }} + run: | + REGISTRY_HOST="${RAW_REGISTRY_HOST#http://}" + REGISTRY_HOST="${REGISTRY_HOST#https://}" + REGISTRY_HOST="${REGISTRY_HOST%/}" + REPOSITORY_PATH="${RAW_REPOSITORY#/}" + IMAGE_REPOSITORY_PATH="$(printf '%s' "$REPOSITORY_PATH" | tr '[:upper:]' '[:lower:]')" + IMAGE_NAME="${REGISTRY_HOST}/${IMAGE_REPOSITORY_PATH}" + { + echo "REGISTRY_HOST=${REGISTRY_HOST}" + echo "REPOSITORY_PATH=${REPOSITORY_PATH}" + echo "IMAGE_REPOSITORY_PATH=${IMAGE_REPOSITORY_PATH}" + echo "IMAGE_NAME=${IMAGE_NAME}" + echo "IMAGE_TAG=${IMAGE_TAG}" + echo "IMAGE_REF=${IMAGE_NAME}:${IMAGE_TAG}" + } >> "$GITHUB_ENV" + + - name: Login to Gitea Container Registry + run: | + echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login "$REGISTRY_HOST" \ + --username "${{ secrets.REGISTRY_USERNAME }}" \ + --password-stdin + + - name: Build and Push Image + run: | + push_with_retry() { + image_ref="$1" + attempt=1 + max_attempts=3 + + while [ "$attempt" -le "$max_attempts" ]; do + if docker push "$image_ref"; then + return 0 + fi + + if [ "$attempt" -eq "$max_attempts" ]; then + return 1 + fi + + echo "Push failed for $image_ref (attempt $attempt/$max_attempts); retrying in 10s..." + attempt=$((attempt + 1)) + sleep 10 + done + } + + docker build \ + -f ./Dockerfile \ + -t "${IMAGE_NAME}:${IMAGE_TAG}" \ + -t "${IMAGE_NAME}:latest" \ + . + push_with_retry "${IMAGE_NAME}:${IMAGE_TAG}" + push_with_retry "${IMAGE_NAME}:latest" + + - name: Notify Deploy Server + run: | + post_deploy_webhook() { + label="$1" + payload="$2" + + http_code=$(curl -sS -D /tmp/deploy_headers.txt -o /tmp/deploy_response.txt -w "%{http_code}" -X POST "${{ vars.DEPLOY_WEBHOOK_URL }}" \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer ${{ secrets.DEPLOY_WEBHOOK_TOKEN }}" \ + -d "$payload") + + echo "[$label] webhook HTTP status: ${http_code}" + if [ "$http_code" -ge 200 ] && [ "$http_code" -lt 300 ]; then + return 0 + fi + + echo "[$label] response headers:" + cat /tmp/deploy_headers.txt + echo "[$label] response body:" + cat /tmp/deploy_response.txt + return 1 + } + + PRIMARY_PAYLOAD="{\"image\":\"${IMAGE_REF}\",\"tag\":\"${IMAGE_TAG}\",\"repo\":\"${REPOSITORY_PATH}\"}" + FALLBACK_PAYLOAD="{\"image\":\"${IMAGE_REF}\",\"tag\":\"${IMAGE_TAG}\",\"repo\":\"${IMAGE_REPOSITORY_PATH}\"}" + + echo "Deploy webhook target: ${{ vars.DEPLOY_WEBHOOK_URL }}" + echo "Deploy payload(primary): image=${IMAGE_REF}, tag=${IMAGE_TAG}, repo=${REPOSITORY_PATH}" + if post_deploy_webhook "primary" "$PRIMARY_PAYLOAD"; then + exit 0 + fi + + echo "Primary webhook request failed, retrying with lowercase repo path..." + echo "Deploy payload(fallback): image=${IMAGE_REF}, tag=${IMAGE_TAG}, repo=${IMAGE_REPOSITORY_PATH}" + if post_deploy_webhook "fallback" "$FALLBACK_PAYLOAD"; then + exit 0 + fi + + echo "Deploy webhook failed after primary and fallback attempts." + exit 1 + + deploy-fallback-log: + runs-on: ubuntu-22.04 + needs: docker-image + if: failure() + steps: + - name: Deployment not triggered + run: echo "Image build/push failed, deployment webhook was not called."