name: Build and Deploy API Server on: push: branches: - main - develop pull_request: branches: - main env: ARTIFACT_DIR: /opt/api-artifacts GO_VERSION: '1.24' jobs: build: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set up Go uses: actions/setup-go@v5 with: go-version: ${{ env.GO_VERSION }} cache: false - name: Get commit info id: commit run: | echo "sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT echo "short_sha=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT echo "branch=$(git rev-parse --abbrev-ref HEAD)" >> $GITHUB_OUTPUT echo "date=$(date -u +%Y-%m-%dT%H:%M:%SZ)" >> $GITHUB_OUTPUT echo "github output is $GITHUB_OUTPUT" - name: Download dependencies run: go mod download - name: Run tests run: go test -v ./... - name: Build binary run: | CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build \ -ldflags="-s -w -X main.Version=${{ steps.commit.outputs.short_sha }} -X main.BuildTime=${{ steps.commit.outputs.date }}" \ -o api-server \ . - name: Create build metadata run: | cat > build-info.json << EOF { "commit": "${{ steps.commit.outputs.sha }}", "short_commit": "${{ steps.commit.outputs.short_sha }}", "branch": "${{ steps.commit.outputs.branch }}", "build_date": "${{ steps.commit.outputs.date }}", "go_version": "${{ env.GO_VERSION }}" } EOF - name: Package artifact run: | mkdir -p artifact-package cp api-server artifact-package/ cp -r migrations artifact-package/ cp build-info.json artifact-package/ tar -czf api-server-${{ steps.commit.outputs.sha }}.tar.gz -C artifact-package . - name: Upload artifact uses: actions/upload-artifact@v4 with: name: api-server-${{ steps.commit.outputs.sha }} path: api-server-${{ steps.commit.outputs.sha }}.tar.gz retention-days: 30 deploy: needs: build runs-on: self-hosted if: github.ref == 'refs/heads/main' && github.event_name == 'push' steps: - name: Checkout deployment scripts uses: actions/checkout@v4 with: sparse-checkout: | deployment/scripts - name: Get commit SHA id: commit run: echo "sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT - name: Download artifact uses: actions/download-artifact@v4 with: name: api-server-${{ steps.commit.outputs.sha }} - name: Extract and deploy run: | BUILD_DIR="${{ env.ARTIFACT_DIR }}/builds/${{ steps.commit.outputs.sha }}" mkdir -p "$BUILD_DIR" tar -xzf api-server-${{ steps.commit.outputs.sha }}.tar.gz -C "$BUILD_DIR" chmod +x "$BUILD_DIR/api-server" if [ -f "${{ env.ARTIFACT_DIR }}/config/.env.production" ]; then cp "${{ env.ARTIFACT_DIR }}/config/.env.production" "$BUILD_DIR/.env.production" fi - name: Run deployment script run: | cd ${{ env.ARTIFACT_DIR }}/scripts ./deploy.sh ${{ steps.commit.outputs.sha }} env: DATABASE_URL: ${{ secrets.DATABASE_URL }} AUTO_MIGRATE: "false" PORT: "8080" - name: Health check run: | ${{ env.ARTIFACT_DIR }}/scripts/health-check.sh - name: Notify deployment status if: always() run: | if [ $? -eq 0 ]; then echo "Deployment successful: ${{ steps.commit.outputs.sha }}" else echo "Deployment failed, rollback initiated" ${{ env.ARTIFACT_DIR }}/scripts/rollback.sh fi