refactor: 统一剪贴板复制功能到 useClipboard 组合式函数 #46
Workflow file for this run
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: Build and Publish Docker Image | |
| on: | |
| push: | |
| tags: ['v*'] | |
| workflow_dispatch: | |
| inputs: | |
| build_base: | |
| description: 'Rebuild base image' | |
| required: false | |
| default: false | |
| type: boolean | |
| env: | |
| REGISTRY: ghcr.io | |
| BASE_IMAGE_NAME: fawney19/aether-base | |
| APP_IMAGE_NAME: fawney19/aether | |
| # Files that affect base image - used for hash calculation | |
| BASE_FILES: "Dockerfile.base pyproject.toml frontend/package.json frontend/package-lock.json" | |
| jobs: | |
| check-base-changes: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| base_changed: ${{ steps.check.outputs.base_changed }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Log in to Container Registry | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Check if base image needs rebuild | |
| id: check | |
| run: | | |
| if [ "${{ github.event.inputs.build_base }}" == "true" ]; then | |
| echo "base_changed=true" >> $GITHUB_OUTPUT | |
| exit 0 | |
| fi | |
| # Calculate current hash of base-related files | |
| CURRENT_HASH=$(cat ${{ env.BASE_FILES }} 2>/dev/null | sha256sum | cut -d' ' -f1) | |
| echo "Current base files hash: $CURRENT_HASH" | |
| # Try to get hash label from remote image config | |
| # Pull the image config and extract labels | |
| REMOTE_HASH="" | |
| if docker pull ${{ env.REGISTRY }}/${{ env.BASE_IMAGE_NAME }}:latest 2>/dev/null; then | |
| REMOTE_HASH=$(docker inspect ${{ env.REGISTRY }}/${{ env.BASE_IMAGE_NAME }}:latest --format '{{ index .Config.Labels "org.opencontainers.image.base.hash" }}' 2>/dev/null) || true | |
| fi | |
| if [ -z "$REMOTE_HASH" ] || [ "$REMOTE_HASH" == "<no value>" ]; then | |
| # No remote image or no hash label, need to rebuild | |
| echo "No remote base image or hash label found, need rebuild" | |
| echo "base_changed=true" >> $GITHUB_OUTPUT | |
| elif [ "$CURRENT_HASH" != "$REMOTE_HASH" ]; then | |
| echo "Hash mismatch: remote=$REMOTE_HASH, current=$CURRENT_HASH" | |
| echo "base_changed=true" >> $GITHUB_OUTPUT | |
| else | |
| echo "Hash matches, no rebuild needed" | |
| echo "base_changed=false" >> $GITHUB_OUTPUT | |
| fi | |
| build-base: | |
| needs: check-base-changes | |
| if: needs.check-base-changes.outputs.base_changed == 'true' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| packages: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Log in to Container Registry | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Calculate base files hash | |
| id: hash | |
| run: | | |
| HASH=$(cat ${{ env.BASE_FILES }} 2>/dev/null | sha256sum | cut -d' ' -f1) | |
| echo "hash=$HASH" >> $GITHUB_OUTPUT | |
| - name: Extract metadata for base image | |
| id: meta | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: ${{ env.REGISTRY }}/${{ env.BASE_IMAGE_NAME }} | |
| tags: | | |
| type=raw,value=latest | |
| type=sha,prefix= | |
| labels: | | |
| org.opencontainers.image.base.hash=${{ steps.hash.outputs.hash }} | |
| - name: Build and push base image | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: . | |
| file: ./Dockerfile.base | |
| push: true | |
| 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 | |
| build-app: | |
| needs: [check-base-changes, build-base] | |
| if: always() && (needs.build-base.result == 'success' || needs.build-base.result == 'skipped') | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| packages: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Log in to Container Registry | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Extract metadata for app image | |
| id: meta | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: ${{ env.REGISTRY }}/${{ env.APP_IMAGE_NAME }} | |
| tags: | | |
| type=raw,value=latest,enable={{is_default_branch}} | |
| type=ref,event=branch | |
| type=ref,event=pr | |
| type=semver,pattern={{version}} | |
| type=semver,pattern={{major}}.{{minor}} | |
| type=sha,prefix= | |
| - name: Update Dockerfile.app to use registry base image | |
| run: | | |
| sed -i "s|FROM aether-base:latest AS builder|FROM ${{ env.REGISTRY }}/${{ env.BASE_IMAGE_NAME }}:latest AS builder|g" Dockerfile.app | |
| - name: Build and push app image | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: . | |
| file: ./Dockerfile.app | |
| push: true | |
| 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 |