Test & build Docker image #82
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Test & build Docker image | |
| permissions: | |
| contents: write | |
| security-events: write | |
| actions: read | |
| on: | |
| push: | |
| branches: [main] | |
| paths: | |
| - 'version' | |
| pull_request: | |
| paths: | |
| - 'version' | |
| schedule: | |
| - cron: "0 2 * * 6" | |
| env: | |
| IMAGE_NAME: zhoujie218/php-nginx | |
| IMAGE_TAG: ${{ github.sha }} | |
| DOCKER_BUILDKIT: 1 | |
| BUILDX_NO_DEFAULT_ATTESTATIONS: 1 | |
| jobs: | |
| build: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v5 | |
| with: | |
| ref: ${{ github.event.inputs.branch || github.ref }} | |
| - name: Display build info | |
| run: | | |
| echo "Build triggered by: ${{ github.event_name }}" | |
| echo "Current branch: $(git branch --show-current)" | |
| echo "Commit SHA: ${{ github.sha }}" | |
| echo "Git ref: ${{ github.ref }}" | |
| echo "Is main branch push: ${{ github.ref == 'refs/heads/main' && github.event_name == 'push' }}" | |
| echo "Version file monitoring: ENABLED" | |
| if [ "${{ github.event_name }}" = "schedule" ]; then | |
| echo "🕐 Scheduled build - Weekly automatic build triggered" | |
| echo "This build will push to Docker Hub with latest tag" | |
| fi | |
| if [ "${{ github.event_name }}" = "pull_request" ]; then | |
| echo "⚠️ This is a Pull Request build - Docker push and Release creation will be skipped" | |
| echo "💡 To trigger Docker build and Release, update version file and push to main branch" | |
| fi | |
| - name: Parse version from file | |
| id: parse_version | |
| run: | | |
| # 读取version文件内容 | |
| VERSION_CONTENT=$(cat version) | |
| echo "Version file content: $VERSION_CONTENT" | |
| # 解析名称和版本号 (格式: name:version) | |
| if [[ $VERSION_CONTENT == *":"* ]]; then | |
| NAME=$(echo $VERSION_CONTENT | cut -d':' -f1) | |
| VERSION=$(echo $VERSION_CONTENT | cut -d':' -f2) | |
| else | |
| # 兼容旧格式,只有版本号 | |
| NAME="php-nginx" | |
| VERSION=$VERSION_CONTENT | |
| fi | |
| echo "NAME=$NAME" >> $GITHUB_OUTPUT | |
| echo "VERSION=$VERSION" >> $GITHUB_OUTPUT | |
| echo "TAG_NAME=v$VERSION" >> $GITHUB_OUTPUT | |
| echo "FULL_TAG_NAME=$NAME:$VERSION" >> $GITHUB_OUTPUT | |
| echo "Parsed name: $NAME" | |
| echo "Parsed version: $VERSION" | |
| echo "Tag name: v$VERSION" | |
| echo "Full tag: $NAME:$VERSION" | |
| - name: Set up QEMU | |
| uses: docker/setup-qemu-action@v3 | |
| - name: Set up Docker Buildx | |
| id: buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Build image | |
| run: |- | |
| docker build -t $IMAGE_NAME:$IMAGE_TAG . | |
| - name: Smoke test image | |
| run: |- | |
| docker compose -f docker-compose.test.yml up -d app | |
| sleep 2 | |
| docker compose -f docker-compose.test.yml run sut | |
| - name: Run Trivy vulnerability scanner | |
| uses: aquasecurity/trivy-action@master | |
| with: | |
| image-ref: "${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }}" | |
| format: "template" | |
| template: "@/contrib/sarif.tpl" | |
| output: "trivy-results.sarif" | |
| - name: Upload Trivy scan results to GitHub Security tab | |
| if: github.ref == 'refs/heads/main' && github.event_name == 'push' | |
| uses: github/codeql-action/upload-sarif@v3 | |
| with: | |
| sarif_file: "trivy-results.sarif" | |
| - name: Login to Docker Hub | |
| if: (github.ref == 'refs/heads/main' && github.event_name == 'push') || contains(github.ref, 'refs/tags/') || github.event_name == 'schedule' | |
| uses: docker/login-action@v3 | |
| with: | |
| username: ${{ secrets.DOCKERHUB_USERNAME }} | |
| password: ${{ secrets.DOCKERHUB_TOKEN }} | |
| - name: Build multi-arch image and push latest tag | |
| if: (github.ref == 'refs/heads/main' && github.event_name == 'push') || github.event_name == 'schedule' | |
| run: |- | |
| echo "开始构建多架构镜像 - $(date)" | |
| echo "构建镜像: ${{ steps.parse_version.outputs.NAME }}" | |
| echo "版本: ${{ steps.parse_version.outputs.VERSION }}" | |
| docker buildx build \ | |
| --cache-from=type=registry,ref=$IMAGE_NAME:buildcache \ | |
| --cache-to=type=registry,ref=$IMAGE_NAME:buildcache,mode=max \ | |
| --push \ | |
| -t $IMAGE_NAME:latest \ | |
| -t $IMAGE_NAME:${{ steps.parse_version.outputs.VERSION }} \ | |
| --platform linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6 \ | |
| --build-arg BUILDKIT_INLINE_CACHE=1 \ | |
| . | |
| echo "构建完成 - $(date)" | |
| - name: Skip Docker build (not main branch push) | |
| if: github.event_name == 'pull_request' || (github.event_name == 'push' && github.ref != 'refs/heads/main') | |
| run: | | |
| echo "⏭️ Skipping Docker build and push" | |
| echo "Reason: This is not a main branch push" | |
| echo "To trigger Docker build:" | |
| echo " 1. Update version file and push to main branch, or" | |
| echo " 2. Create a version tag (e.g., v1.0.0), or" | |
| echo " 3. Wait for weekly scheduled build (Saturday 2:00 AM UTC)" | |
| - name: Check if tag exists | |
| if: github.ref == 'refs/heads/main' && github.event_name == 'push' | |
| id: check_tag | |
| run: | | |
| TAG_NAME="${{ steps.parse_version.outputs.TAG_NAME }}" | |
| echo "Checking if tag $TAG_NAME exists..." | |
| # 检查标签是否存在 | |
| if git rev-parse "$TAG_NAME" >/dev/null 2>&1; then | |
| echo "Tag $TAG_NAME already exists" | |
| echo "TAG_EXISTS=true" >> $GITHUB_OUTPUT | |
| else | |
| echo "Tag $TAG_NAME does not exist" | |
| echo "TAG_EXISTS=false" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Create GitHub Release | |
| if: github.ref == 'refs/heads/main' && github.event_name == 'push' && steps.check_tag.outputs.TAG_EXISTS == 'false' | |
| uses: softprops/action-gh-release@v1 | |
| with: | |
| tag_name: ${{ steps.parse_version.outputs.TAG_NAME }} | |
| name: Release ${{ steps.parse_version.outputs.TAG_NAME }} | |
| body: | | |
| ## Docker Image Release ${{ steps.parse_version.outputs.TAG_NAME }} | |
| ### 镜像信息 | |
| - **名称**: ${{ steps.parse_version.outputs.NAME }} | |
| - **版本**: ${{ steps.parse_version.outputs.VERSION }} | |
| ### 镜像标签 | |
| - `${{ env.IMAGE_NAME }}:latest` | |
| - `${{ env.IMAGE_NAME }}:${{ steps.parse_version.outputs.VERSION }}` | |
| ### 支持的架构 | |
| - linux/amd64 | |
| - linux/arm64 | |
| - linux/arm/v7 | |
| - linux/arm/v6 | |
| ### 使用方法 | |
| ```bash | |
| # 拉取最新版本 | |
| docker pull ${{ env.IMAGE_NAME }}:latest | |
| # 拉取特定版本 | |
| docker pull ${{ env.IMAGE_NAME }}:${{ steps.parse_version.outputs.VERSION }} | |
| # 运行容器 | |
| docker run -p 80:8080 ${{ env.IMAGE_NAME }}:${{ steps.parse_version.outputs.VERSION }} | |
| ``` | |
| ### 变更日志 | |
| 请查看 [提交历史](https://github.com/${{ github.repository }}/compare/${{ github.event.before }}...${{ github.sha }}) 了解详细变更。 | |
| draft: false | |
| prerelease: false | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Skip Release creation (tag already exists) | |
| if: github.ref == 'refs/heads/main' && github.event_name == 'push' && steps.check_tag.outputs.TAG_EXISTS == 'true' | |
| run: | | |
| echo "⏭️ Skipping GitHub Release creation" | |
| echo "Reason: Tag ${{ steps.parse_version.outputs.TAG_NAME }} already exists" | |
| echo "If you want to create a new release, please update the version in the version file" | |
| - name: Skip Release creation (not main branch push) | |
| if: github.event_name == 'pull_request' || (github.event_name == 'push' && github.ref != 'refs/heads/main') | |
| run: | | |
| echo "⏭️ Skipping GitHub Release creation" | |
| echo "Reason: This is not a main branch push" | |
| echo "To create a Release:" | |
| echo " 1. Update the version file and push to main branch" |