From 126b47b56acb9056799d308853e0c6395f6087cc Mon Sep 17 00:00:00 2001 From: sangnn Date: Tue, 23 Jun 2026 01:54:29 +0000 Subject: [PATCH 1/3] ci: add deployment --- .gitea/workflows/pr-security-check.yml | 58 +++++++++++++++++++ .gitea/workflows/push-develop.yml | 79 ++++++++++++++++++++++++++ .gitea/workflows/push-main.yml | 78 +++++++++++++++++++++++++ docker-compose.yml | 7 +-- 4 files changed, 216 insertions(+), 6 deletions(-) create mode 100644 .gitea/workflows/pr-security-check.yml create mode 100644 .gitea/workflows/push-develop.yml create mode 100644 .gitea/workflows/push-main.yml diff --git a/.gitea/workflows/pr-security-check.yml b/.gitea/workflows/pr-security-check.yml new file mode 100644 index 0000000..1f5353e --- /dev/null +++ b/.gitea/workflows/pr-security-check.yml @@ -0,0 +1,58 @@ +name: PR -> develop + +on: + pull_request: + branches: + - main + - develop + +env: + GITLEAKS_VERSION: "8.30.1" + +jobs: + + # ── 1. Secret scan ──────────────────────────────────────────────────────────── + gitleaks: + name: Scan for secrets (Gitleaks) + runs-on: stage-gatehouse-ui + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Install Gitleaks + run: | + if command -v gitleaks >/dev/null 2>&1; then + echo "gitleaks already installed: $(gitleaks version)" + exit 0 + fi + curl -sSfL \ + "https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}/gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz" \ + | tar xz gitleaks + mv gitleaks /usr/local/bin/gitleaks + + - name: Run secret scan + run: gitleaks detect --source . --exit-code 1 --redact --verbose --log-level debug + + # ── 2. CVE scan ─────────────────────────────────────────────────────────────── + trivy: + name: Scan for CVEs (Trivy) + runs-on: stage-gatehouse-ui + + steps: + - uses: actions/checkout@v4 + + - name: Install Trivy + run: | + command -v trivy >/dev/null 2>&1 || \ + curl -sSfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh \ + | sh -s -- -b /usr/local/bin + + - name: Run filesystem scan + run: | + trivy fs \ + --exit-code 1 \ + --severity HIGH,CRITICAL \ + --no-progress \ + . diff --git a/.gitea/workflows/push-develop.yml b/.gitea/workflows/push-develop.yml new file mode 100644 index 0000000..c7c8f10 --- /dev/null +++ b/.gitea/workflows/push-develop.yml @@ -0,0 +1,79 @@ +name: Push -> develop + +on: + push: + branches: + - develop + - ci/deploy + +jobs: + + # ── 1. Build ────────────────────────────────────────────────────────────────── + build: + name: Build Docker image + runs-on: stage-gatehouse-ui + outputs: + tag: ${{ steps.sha.outputs.tag }} + + steps: + - uses: actions/checkout@v4 + + - name: Set image tag + id: sha + run: echo "tag=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT" + + - name: Build ui image + run: | + # VITE_API_BASE_URL is baked into the static bundle at build time. + # Source it from the deployed env on this (stage) runner. + set -a; . /opt/gatehouse-ui/.env; set +a + docker build \ + --build-arg VITE_API_BASE_URL="${VITE_API_BASE_URL}" \ + -t "gatehouse-ui:${{ steps.sha.outputs.tag }}" \ + -t "gatehouse-ui:latest" \ + . + + - name: Scan ui image for vulnerabilities (Trivy) + run: | + command -v trivy >/dev/null 2>&1 || \ + curl -sSfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh \ + | sh -s -- -b /usr/local/bin + + trivy image \ + --exit-code 0 \ + --severity HIGH,CRITICAL \ + --no-progress \ + "gatehouse-ui:${{ steps.sha.outputs.tag }}" + + # ── 2. Deploy ───────────────────────────────────────────────────────────────── + deploy: + name: Deploy + runs-on: stage-gatehouse-ui + needs: build + env: + COMPOSE_DIR: /opt/gatehouse-ui + + steps: + - uses: actions/checkout@v4 + + - name: Deploy (docker compose up) + run: | + cp docker-compose.yml "${COMPOSE_DIR}/docker-compose.yml" + cd "${COMPOSE_DIR}" + IMAGE_TAG="${{ needs.build.outputs.tag }}" docker compose up -d --remove-orphans + + # ── 3. Alert ────────────────────────────────────────────────────────────────── + alert: + name: Notify on result + runs-on: stage-gatehouse-ui + needs: deploy + if: always() + + steps: + - name: Send notification + run: | + STATUS="${{ needs.deploy.result }}" + echo "TODO: send alert — deploy status: ${STATUS}" + # curl -X POST "${{ secrets.ALERT_WEBHOOK }}" \ + # -H 'Content-Type: application/json' \ + # -d "{\"text\": \"[gatehouse-ui] Deploy ${STATUS} — tag: ${{ needs.build.outputs.tag }}\"}" diff --git a/.gitea/workflows/push-main.yml b/.gitea/workflows/push-main.yml new file mode 100644 index 0000000..1b5dded --- /dev/null +++ b/.gitea/workflows/push-main.yml @@ -0,0 +1,78 @@ +name: Push -> main + +on: + push: + branches: + - main + +jobs: + + # ── 1. Build ────────────────────────────────────────────────────────────────── + build: + name: Build Docker image + runs-on: prod-gatehouse-ui + outputs: + tag: ${{ steps.sha.outputs.tag }} + + steps: + - uses: actions/checkout@v4 + + - name: Set image tag + id: sha + run: echo "tag=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT" + + - name: Build ui image + run: | + # VITE_API_BASE_URL is baked into the static bundle at build time. + # Source it from the deployed env on this (prod) runner. + set -a; . /opt/gatehouse-ui/.env; set +a + docker build \ + --build-arg VITE_API_BASE_URL="${VITE_API_BASE_URL}" \ + -t "gatehouse-ui:${{ steps.sha.outputs.tag }}" \ + -t "gatehouse-ui:latest" \ + . + + - name: Scan ui image for vulnerabilities (Trivy) + run: | + command -v trivy >/dev/null 2>&1 || \ + curl -sSfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh \ + | sh -s -- -b /usr/local/bin + + trivy image \ + --exit-code 0 \ + --severity HIGH,CRITICAL \ + --no-progress \ + "gatehouse-ui:${{ steps.sha.outputs.tag }}" + + # ── 2. Deploy ───────────────────────────────────────────────────────────────── + deploy: + name: Deploy + runs-on: prod-gatehouse-ui + needs: build + env: + COMPOSE_DIR: /opt/gatehouse-ui + + steps: + - uses: actions/checkout@v4 + + - name: Deploy (docker compose up) + run: | + cp docker-compose.yml "${COMPOSE_DIR}/docker-compose.yml" + cd "${COMPOSE_DIR}" + IMAGE_TAG="${{ needs.build.outputs.tag }}" docker compose up -d --remove-orphans + + # ── 3. Alert ────────────────────────────────────────────────────────────────── + alert: + name: Notify on result + runs-on: prod-gatehouse-ui + needs: deploy + if: always() + + steps: + - name: Send notification + run: | + STATUS="${{ needs.deploy.result }}" + echo "TODO: send alert — deploy status: ${STATUS}" + # curl -X POST "${{ secrets.ALERT_WEBHOOK }}" \ + # -H 'Content-Type: application/json' \ + # -d "{\"text\": \"[gatehouse-ui] Deploy ${STATUS} — tag: ${{ needs.build.outputs.tag }}\"}" diff --git a/docker-compose.yml b/docker-compose.yml index 02048f0..25a6c23 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,12 +1,7 @@ services: ui: - build: - context: . - args: - - VITE_API_BASE_URL=${VITE_API_BASE_URL} + image: gatehouse-ui:${IMAGE_TAG:-latest} container_name: gatehouse-ui - env_file: - - .env ports: - "8080:8080" restart: unless-stopped -- 2.52.0 From 89dc3a28932b96402c562dea1a8b285fd265c85d Mon Sep 17 00:00:00 2001 From: sangnn Date: Tue, 23 Jun 2026 02:02:06 +0000 Subject: [PATCH 2/3] ci: upgrade image packages --- Dockerfile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Dockerfile b/Dockerfile index bf123fa..d7094d1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,6 +14,9 @@ RUN bun run build # Production stage FROM nginx:alpine AS production +# Patch inherited Alpine OS packages to clear known CVEs not yet in the base image +RUN apk upgrade --no-cache + COPY --from=builder /app/dist /usr/share/nginx/html COPY nginx.conf /etc/nginx/conf.d/default.conf -- 2.52.0 From 985ea273b965bf6d7659164965556d210b46b6a2 Mon Sep 17 00:00:00 2001 From: sangnn Date: Tue, 23 Jun 2026 02:04:11 +0000 Subject: [PATCH 3/3] ci: remove ci/deploy --- .gitea/workflows/push-develop.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitea/workflows/push-develop.yml b/.gitea/workflows/push-develop.yml index c7c8f10..e25a3c3 100644 --- a/.gitea/workflows/push-develop.yml +++ b/.gitea/workflows/push-develop.yml @@ -4,7 +4,6 @@ on: push: branches: - develop - - ci/deploy jobs: -- 2.52.0