From 7ae74f53c5f0de59be2cc73773c9a2fc42472972 Mon Sep 17 00:00:00 2001 From: Meo597 <197331664+Meo597@users.noreply.github.com> Date: Wed, 11 Jun 2025 22:45:45 +0800 Subject: [PATCH 1/3] Workflows: Cleaner Docker builds, support for manual exec and pre-release --- .github/workflows/docker.yml | 137 +++++++++++++++++++++++------------ 1 file changed, 90 insertions(+), 47 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index dc7759cc..ccab69c6 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -1,36 +1,78 @@ -name: Build docker image +name: Build and Push Docker Image on: release: - types: [published] + types: + - published + - released + + workflow_dispatch: + inputs: + tag: + description: "Docker image version (e.g., v1.2.3):" + required: true + add_latest_tag: + description: "Set to latest" + type: boolean + default: false jobs: - build-image: + build-and-push: runs-on: ubuntu-latest permissions: + contents: read packages: write + steps: - - uses: actions/checkout@v4 + - name: Set repository and image name to lowercase + env: + IMAGE_NAME: "${{ github.repository }}" + run: | + echo "IMAGE_NAME=${IMAGE_NAME,,}" >>${GITHUB_ENV} + echo "FULL_IMAGE_NAME=ghcr.io/${IMAGE_NAME,,}" >>${GITHUB_ENV} - - name: Docker metadata - id: meta - uses: docker/metadata-action@v5 - with: - images: ghcr.io/${{ github.repository_owner }}/xray-core - flavor: latest=auto - tags: | - type=semver,pattern={{version}} + - name: Validate and extract version tag + run: | + SOURCE_TAG="${{ github.event.inputs.tag }}" + if [[ -z "$SOURCE_TAG" ]]; then + SOURCE_TAG="${{ github.ref_name }}" + fi - - name: Docker metadata (unsupported architectures) - id: metausa - uses: docker/metadata-action@v5 - with: - images: ghcr.io/${{ github.repository_owner }}/xray-core - flavor: | - latest=auto - suffix=-usa,onlatest=true - tags: | - type=semver,pattern={{version}} + if [[ -z "$SOURCE_TAG" ]]; then + echo "Error: Could not determine a valid tag source. Input tag and context tag (github.ref_name) are both empty." + exit 1 + fi + + if [[ "$SOURCE_TAG" != v* ]]; then + echo "Error: Tag '$SOURCE_TAG' must start with 'v'. Aborting." + exit 1 + fi + + APP_VERSION=${SOURCE_TAG#v} + if [[ -z "$APP_VERSION" ]]; then + echo "Error: Tag '$SOURCE_TAG' starts with 'v' but has no version number following it." + exit 1 + fi + + echo "Application version: $APP_VERSION" + echo "APP_VERSION=$APP_VERSION" >>${GITHUB_ENV} + + LATEST=false + if [[ "${{ github.event_name }}" == "release" && "${{ github.event.release.prerelease }}" == "false" ]] || [[ "${{ github.event_name }}" == "workflow_dispatch" && "${{ github.event.inputs.add_latest_tag }}" == "true" ]]; then + LATEST=true + fi + + echo "Latest: $LATEST" + echo "LATEST=$LATEST" >>${GITHUB_ENV} + + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 - name: Login to GitHub Container Registry uses: docker/login-action@v3 @@ -39,13 +81,12 @@ jobs: username: ${{ github.repository_owner }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Build and push + - name: Build Docker image (main architectures) + id: build_main_arches uses: docker/build-push-action@v6 with: context: . + file: .github/docker/Dockerfile platforms: | linux/amd64 linux/arm/v7 @@ -53,39 +94,41 @@ jobs: linux/ppc64le linux/s390x provenance: false - file: .github/docker/Dockerfile - push: true - tags: ${{ steps.meta.outputs.tags }} + outputs: type=image,name=${{ env.FULL_IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=true - - name: Build and push (unsupported architectures) + - name: Build Docker image (additional architectures) + id: build_additional_arches uses: docker/build-push-action@v6 with: context: . + file: .github/docker/Dockerfile.usa platforms: | linux/386 linux/arm/v6 linux/riscv64 linux/loong64 provenance: false - file: .github/docker/Dockerfile.usa - push: true - tags: ${{ steps.metausa.outputs.tags }} + outputs: type=image,name=${{ env.FULL_IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=true - - name: Merge Multi-Arch Manifests + - name: Create manifest list and push run: | - echo "Starting to merge multi-architecture manifests..." + echo "Creating multi-arch manifest with version tag: ${{ env.FULL_IMAGE_NAME }}:${{ env.APP_VERSION }}" + docker buildx imagetools create \ + --tag ${{ env.FULL_IMAGE_NAME }}:${{ env.APP_VERSION }} \ + ${{ env.FULL_IMAGE_NAME }}@${{ steps.build_main_arches.outputs.digest }} \ + ${{ env.FULL_IMAGE_NAME }}@${{ steps.build_additional_arches.outputs.digest }} - # Convert newlines to spaces and split into array - TAGS=($(echo "${{ steps.meta.outputs.tags }}" | tr '\n' ' ')) + if [[ "${{ env.LATEST }}" == "true" ]]; then + echo "Adding 'latest' tag to manifest: ${{ env.FULL_IMAGE_NAME }}:latest" + docker buildx imagetools create \ + --tag ${{ env.FULL_IMAGE_NAME }}:latest \ + ${{ env.FULL_IMAGE_NAME }}:${{ env.APP_VERSION }} + fi - echo "Total tags to process: ${#TAGS[@]}" - for tag in "${TAGS[@]}"; do - echo "Merging tag: $tag with unsupported architectures ($tag-usa)" - docker buildx imagetools create --append --tag "$tag" "$tag-usa" - if [ $? -ne 0 ]; then - echo "Error: Failed to merge $tag-usa into $tag" - exit 1 - fi - done + - name: Inspect image + run: | + docker buildx imagetools inspect ${{ env.FULL_IMAGE_NAME }}:${{ env.APP_VERSION }} - echo "Multi-architecture manifest merge completed successfully." + if [[ "${{ env.LATEST }}" == "true" ]]; then + docker buildx imagetools inspect ${{ env.FULL_IMAGE_NAME }}:latest + fi From f093ce4b408f530bf93e71ebf93031f4f42e59a2 Mon Sep 17 00:00:00 2001 From: Meo597 <197331664+Meo597@users.noreply.github.com> Date: Sun, 15 Jun 2025 20:27:01 +0800 Subject: [PATCH 2/3] Applicable to more scenarios --- .github/workflows/docker.yml | 37 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index ccab69c6..98b4e0d5 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -9,9 +9,9 @@ on: workflow_dispatch: inputs: tag: - description: "Docker image version (e.g., v1.2.3):" + description: "Docker image tag:" required: true - add_latest_tag: + latest: description: "Set to latest" type: boolean default: false @@ -31,7 +31,7 @@ jobs: echo "IMAGE_NAME=${IMAGE_NAME,,}" >>${GITHUB_ENV} echo "FULL_IMAGE_NAME=ghcr.io/${IMAGE_NAME,,}" >>${GITHUB_ENV} - - name: Validate and extract version tag + - name: Validate and extract tag run: | SOURCE_TAG="${{ github.event.inputs.tag }}" if [[ -z "$SOURCE_TAG" ]]; then @@ -43,26 +43,21 @@ jobs: exit 1 fi - if [[ "$SOURCE_TAG" != v* ]]; then - echo "Error: Tag '$SOURCE_TAG' must start with 'v'. Aborting." - exit 1 + if [[ "$SOURCE_TAG" =~ ^v[0-9]+\.[0-9] ]]; then + IMAGE_TAG="${SOURCE_TAG#v}" + else + IMAGE_TAG="$SOURCE_TAG" fi - APP_VERSION=${SOURCE_TAG#v} - if [[ -z "$APP_VERSION" ]]; then - echo "Error: Tag '$SOURCE_TAG' starts with 'v' but has no version number following it." - exit 1 - fi - - echo "Application version: $APP_VERSION" - echo "APP_VERSION=$APP_VERSION" >>${GITHUB_ENV} + echo "Docker image tag: '$IMAGE_TAG'." + echo "IMAGE_TAG=$IMAGE_TAG" >>${GITHUB_ENV} LATEST=false - if [[ "${{ github.event_name }}" == "release" && "${{ github.event.release.prerelease }}" == "false" ]] || [[ "${{ github.event_name }}" == "workflow_dispatch" && "${{ github.event.inputs.add_latest_tag }}" == "true" ]]; then + if [[ "${{ github.event_name }}" == "release" && "${{ github.event.release.prerelease }}" == "false" ]] || [[ "${{ github.event_name }}" == "workflow_dispatch" && "${{ github.event.inputs.latest }}" == "true" ]]; then LATEST=true fi - echo "Latest: $LATEST" + echo "Latest: '$LATEST'." echo "LATEST=$LATEST" >>${GITHUB_ENV} - name: Checkout code @@ -112,22 +107,22 @@ jobs: - name: Create manifest list and push run: | - echo "Creating multi-arch manifest with version tag: ${{ env.FULL_IMAGE_NAME }}:${{ env.APP_VERSION }}" + echo "Creating multi-arch manifest with tag: '${{ env.FULL_IMAGE_NAME }}:${{ env.IMAGE_TAG }}'." docker buildx imagetools create \ - --tag ${{ env.FULL_IMAGE_NAME }}:${{ env.APP_VERSION }} \ + --tag ${{ env.FULL_IMAGE_NAME }}:${{ env.IMAGE_TAG }} \ ${{ env.FULL_IMAGE_NAME }}@${{ steps.build_main_arches.outputs.digest }} \ ${{ env.FULL_IMAGE_NAME }}@${{ steps.build_additional_arches.outputs.digest }} if [[ "${{ env.LATEST }}" == "true" ]]; then - echo "Adding 'latest' tag to manifest: ${{ env.FULL_IMAGE_NAME }}:latest" + echo "Adding 'latest' tag to manifest: '${{ env.FULL_IMAGE_NAME }}:latest'." docker buildx imagetools create \ --tag ${{ env.FULL_IMAGE_NAME }}:latest \ - ${{ env.FULL_IMAGE_NAME }}:${{ env.APP_VERSION }} + ${{ env.FULL_IMAGE_NAME }}:${{ env.IMAGE_TAG }} fi - name: Inspect image run: | - docker buildx imagetools inspect ${{ env.FULL_IMAGE_NAME }}:${{ env.APP_VERSION }} + docker buildx imagetools inspect ${{ env.FULL_IMAGE_NAME }}:${{ env.IMAGE_TAG }} if [[ "${{ env.LATEST }}" == "true" ]]; then docker buildx imagetools inspect ${{ env.FULL_IMAGE_NAME }}:latest From dd039378df6f8ad19c6caf6b94128e27e9e6f205 Mon Sep 17 00:00:00 2001 From: Meo597 <197331664+Meo597@users.noreply.github.com> Date: Wed, 25 Jun 2025 12:25:04 +0800 Subject: [PATCH 3/3] concurrency --- .github/workflows/docker.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 98b4e0d5..9ec5b9d9 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -18,6 +18,7 @@ on: jobs: build-and-push: + if: (github.event.action != 'published') || (github.event.action == 'published' && github.event.release.prerelease == true) runs-on: ubuntu-latest permissions: contents: read