name: Build and Push Docker Image on: workflow_dispatch: # 允许手动触发 push: branches: - main - develop tags: - 'v*' pull_request: branches: - main env: REGISTRY: docker.io IMAGE_NAME: feather2dev/paper-burner-x jobs: build-and-push: # PR 上仅需跑 test 必要检查;跳过镜像构建以避免 lock 不一致导致失败 if: github.event_name != 'pull_request' runs-on: ubuntu-latest permissions: contents: read packages: write steps: - name: Checkout repository uses: actions/checkout@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Log in to Docker Hub if: github.event_name != 'pull_request' uses: docker/login-action@v3 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - name: Extract metadata id: meta uses: docker/metadata-action@v5 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} tags: | type=ref,event=branch type=ref,event=pr type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} type=semver,pattern={{major}} # 避免在 PR 场景下出现 "-" 这种以连字符开头的非法标签 # 统一使用稳定前缀,确保 Docker tag 合法(如 "sha-ac262a7") type=sha,prefix=sha- type=raw,value=latest,enable={{is_default_branch}} - name: Build and push Docker image id: build uses: docker/build-push-action@v5 with: context: . file: ./Dockerfile push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} cache-from: type=gha cache-to: type=gha,mode=max platforms: linux/amd64,linux/arm64 - name: Image digest run: echo ${{ steps.build.outputs.digest }} test: runs-on: ubuntu-latest services: postgres: image: postgres:16-alpine env: POSTGRES_USER: test POSTGRES_PASSWORD: test POSTGRES_DB: test options: >- --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 ports: - 5432:5432 steps: - name: Checkout repository uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '20' cache: 'npm' cache-dependency-path: server/package-lock.json - name: Install dependencies working-directory: ./server run: npm install --no-audit --no-fund - name: Generate Prisma Client working-directory: ./server run: npx prisma generate - name: Run database migrations working-directory: ./server env: DATABASE_URL: postgresql://test:test@localhost:5432/test run: npx prisma migrate deploy - name: Lint check (placeholder) working-directory: ./server run: npm run lint continue-on-error: true - name: Test server startup working-directory: ./server env: DATABASE_URL: postgresql://test:test@localhost:5432/test JWT_SECRET: test-secret-key-for-ci run: | timeout 10s node src/index.js || code=$? if [ $code -eq 124 ]; then echo "Server started successfully" exit 0 else echo "Server failed to start" exit 1 fi - name: Run unit tests working-directory: ./server env: NODE_ENV: test DATABASE_URL: postgresql://test:test@localhost:5432/test JWT_SECRET: test-secret-key-for-ci run: npm test