demo_docs/Templates/Pipeline Template(Main).md
2025-05-14 09:42:59 +07:00

8.3 KiB

Build - Test - Security (SCA/SAST) - Staging - Deploy Example

# File: .gitea/workflows/ci.yml (Phiên bản cải thiện)
name: Go CI Pipeline

# Step 1: Thêm trigger pull_request
on:

  push:

    tags:

      - 'v*'

jobs:

  # ---- Job: Lint Code ----

  lint:

    name: Lint Code

    runs-on: ubuntu-latest

    steps:

      # Step 2: Cập nhật action versions

      - name: Checkout code

        uses: actions/checkout@v4

  

      # Step 2: Cập nhật action versions

      - name: Set up Go

        uses: actions/setup-go@v5

        with:

          go-version: '1.23' # Đặt phiên bản Go của bạn

          cache-dependency-path: go.sum # Bật cache cho Go modules

  

      - name: Run golangci-lint

        uses: golangci/golangci-lint-action@v6

        with:

          version: latest # Hoặc phiên bản cụ thể

          args: --timeout=5m # Giữ timeout

          # Gợi ý: Tạo file .golangci.yml trong repo để cấu hình chi tiết,

          # bao gồm bật các linter bảo mật như 'gosec' để có SAST cơ bản.

          # cache: true # Cân nhắc bật cache của golangci-lint nếu cần

  

  # ---- Job: Run Tests ----

  test:

    name: Run Tests

    runs-on: ubuntu-latest

    steps:

      # Step 2: Cập nhật action versions

      - name: Checkout code

        uses: actions/checkout@v4

  

      # Step 2: Cập nhật action versions

      - name: Set up Go

        uses: actions/setup-go@v5

        with:

          go-version: '1.23'

          cache-dependency-path: go.sum

  

      # Step 7: Cài đặt tool tạo report JUnit

      - name: Install go-junit-report

        run: go install github.com/jstemmer/go-junit-report@latest

  

      # Step 7: Chạy test, tạo coverage

      - name: Run Go Test, Coverage

        run: |

          # Chạy test với -v để go-junit-report có input, lưu output vào file log

          go test -v -race -coverprofile=coverage.out ./... | tee test-output.log

          # Tạo report coverage dạng text (tùy chọn)

          go tool cover -func=coverage.out

  # ---- Job: Security Scan (SCA - govulncheck) ----

  sca_scan:

    name: Security Scan (SCA - govulncheck)

    runs-on: ubuntu-latest

    steps:

      # Step 2: Cập nhật action versions

      - name: Checkout code

        uses: actions/checkout@v4

  

      # Step 2: Cập nhật action versions

      - name: Set up Go

        uses: actions/setup-go@v5

        with:

          go-version: '1.23'

          cache-dependency-path: go.sum

  

      # Step 5: Thay Trivy bằng govulncheck action

      - name: Run Go Vulnerability Check (govulncheck)

        uses: golang/govulncheck-action@v1

        # govulncheck sẽ tự động fail job nếu tìm thấy lỗ hổng có thể bị ảnh hưởng

  

  # ---- Job: Build ----

  build:

    name: Build Application

    runs-on: ubuntu-latest

    # Quan trọng: needs phải bao gồm tất cả các job kiểm tra trước đó

    steps:

      # Step 2: Cập nhật action versions

      - name: Checkout code

        uses: actions/checkout@v4

  

      # Step 2: Cập nhật action versions

      - name: Set up Go

        uses: actions/setup-go@v5

        with:

          go-version: '1.23'

          cache-dependency-path: go.sum

  

      # Step 6: Build với các cờ tối ưu và version info

      - name: Build Go Application

        run: |

          # Lấy thông tin version (ví dụ: tên tag hoặc tên nhánh + SHA ngắn)

          # Lưu ý: Biến context của Gitea có thể là gitea.* thay vì github.*

          APP_VERSION="${{ gitea.ref_name }}-${{ format('{0}', gitea.sha) }}"

          # Thay main.version bằng đường dẫn thực tế đến biến version trong code của bạn

          go build -v -ldflags="-s -w -X main.version=${APP_VERSION}" -o ./bin/server ./cmd/server

      # Step 6: Upload artifact binary

      # Step 2: Cập nhật action versions

      - name: Upload build artifact

        uses: actions/upload-artifact@v3

        with:

          name: server-binary # Tên artifact rõ ràng hơn

          path: ./bin/server # Đường dẫn tới file binary

  

  docker-build-push:

    name: Build and Push Docker Image

    runs-on: ubuntu-latest

    needs: [build]

    if: gitea.ref_name == 'master' || startsWith(gitea.ref_name, 'v')

    steps:

      - name: Checkout code # Cần checkout để lấy Dockerfile.prod

        uses: actions/checkout@v4

  

      - name: Download build artifact # Tải artifact binary từ job 'build'

        uses: actions/download-artifact@v3 # Dùng v3 cho Gitea

        with:

          name: server-binary # Tên artifact đã upload ở job build

          path: ./bin # Giải nén vào thư mục ./bin

  

      - name: Cài Docker CLI

        run: |

          apt-get update

          apt-get install -y docker.io

          docker version

  

      - name: Set up Docker Buildx # Công cụ build image nâng cao

        uses: docker/setup-buildx-action@v3

  

      - name: Login to Gitea Container Registry # Đăng nhập vào registry

        uses: docker/login-action@v3

        with:

          registry: ${{ gitea.server_url }} # Biến context chứa URL Gitea (vd: gitea.tuvanwebsite.com) - Kiểm tra lại biến đúng

          username: ${{ secrets.REGISTRY_USER }}

          password: ${{ secrets.REGISTRY_PASSWORD }}

  

      - name: Build and push Docker image

        uses: docker/build-push-action@v5

        with:

          context: . # Build context là thư mục gốc

          file: ./Dockerfile # Chỉ định Dockerfile cho production

          push: true # Đẩy image lên registry

          tags: | # Đặt tên và tag cho image

            ${{ secrets.REGISTRY_URL }}/${{ gitea.repository }}:${{ gitea.ref_name }}

            ${{ secrets.REGISTRY_URL }}/${{ gitea.repository }}:latest

          # cache-from: type=gha # Bật cache build layer (tùy chọn)

          # cache-to: type=gha,mode=max

  # ---- Job: Deploy to VPS ----

  deploy:

    name: Deploy to VPS

    runs-on: ubuntu-latest

    if: gitea.ref_name == 'master' || startsWith(gitea.ref_name, 'v')

    steps:

      - name: Set image name

        run: echo "IMAGE_NAME=${{ secrets.REGISTRY_URL }}/${{ gitea.repository }}:${{ gitea.ref_name }}" >> $GITEA_ENV

      - name: Cài Docker CLI

        run: |

          apt-get update

          apt-get install -y docker.io

          apt-get install -y curl

          docker version

      - name: Deploy using Docker commands

        run: |

          curl -v https://${{ secrets.REGISTRY_URL }} || echo "Curl failed"

          echo "Deploying image: ${{ env.IMAGE_NAME }}"

          # Kéo image mới nhất về VPS host (thông qua runner)

          docker pull ${{ env.IMAGE_NAME }}

  

          # Dừng container cũ nếu đang chạy (bỏ qua lỗi nếu chưa có)

          docker stop my-go-app-container || true

  

          # Xóa container cũ nếu tồn tại (bỏ qua lỗi nếu chưa có)

          docker rm my-go-app-container || true

  

          # Chạy container mới từ image vừa kéo

          # Quan trọng: Thêm các biến môi trường cần thiết cho ứng dụng (-e)

          # và đảm bảo nó kết nối đúng network để thấy DB (-network)

          docker run -d \

            --name my-go-app-container \

            --network gitea_gitea_network \

            --restart always \

            -p 8080:8080 \

            -e DB_HOST=db \

            -e DB_USER=gitea \

            -e DB_PASSWORD=gitea \

            -e DB_NAME=gitea \

            ${{ env.IMAGE_NAME }} # Sử dụng image vừa build/push