name: CI Workflow on: push: branches: - "*" # 所有分支触发 tags: - 'v*' workflow_dispatch: env: TEST_TAG: ${{ secrets.DOCKERHUB_USERNAME }}/xiaomusic:${{ github.ref_name }} LATEST_TAG: ${{ secrets.DOCKERHUB_USERNAME }}/xiaomusic:latest STABLE_TAG: ${{ secrets.DOCKERHUB_USERNAME }}/xiaomusic:stable permissions: contents: write id-token: write jobs: # Job 构建镜像 build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set up QEMU uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Login to Docker Hub uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Build Docker image (linux/amd64) id: build_amd64 uses: docker/build-push-action@v6 with: platforms: linux/amd64 context: . push: false load: true tags: ${{ env.TEST_TAG }}-linux-amd64 cache-from: type=local,src=/tmp/.buildx-cache cache-to: type=local,dest=/tmp/.buildx-cache-new - name: Build Docker image (linux/arm64) id: build_arm64 uses: docker/build-push-action@v6 with: platforms: linux/arm64 context: . push: false load: true tags: ${{ env.TEST_TAG }}-linux-arm64 cache-from: type=local,src=/tmp/.buildx-cache cache-to: type=local,dest=/tmp/.buildx-cache-new - name: Build Docker image (linux/arm/v7) id: build_armv7 uses: docker/build-push-action@v6 with: platforms: linux/arm/v7 context: . push: false load: true tags: ${{ env.TEST_TAG }}-linux-arm-v7 cache-from: type=local,src=/tmp/.buildx-cache cache-to: type=local,dest=/tmp/.buildx-cache-new - name: List Docker images run: docker images - name: Test amd64 image run: | docker run --rm --entrypoint /bin/sh ${{ env.TEST_TAG }}-linux-amd64 -c "/app/.venv/bin/python3 /app/xiaomusic.py -h" - name: Test arm64 image run: | docker run --rm --entrypoint /bin/sh ${{ env.TEST_TAG }}-linux-arm64 -c "/app/.venv/bin/python3 /app/xiaomusic.py -h" - name: Test armv7 image run: | docker run --rm --entrypoint /bin/sh ${{ env.TEST_TAG }}-linux-arm-v7 -c "/app/.venv/bin/python3 /app/xiaomusic.py -h" - name: Docker Hub Description if: github.ref == 'refs/heads/main' uses: peter-evans/dockerhub-description@v4 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} repository: hanxi/xiaomusic # 发布 PyPI 版本 # 仅在 ref 为以 v 开头的标签时执行 - uses: actions/setup-node@v4 if: startsWith(github.ref, 'refs/tags/v') with: registry-url: https://registry.npmjs.org/ node-version: lts/* - run: npx changelogithub if: startsWith(github.ref, 'refs/tags/v') continue-on-error: true env: GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} - uses: pdm-project/setup-pdm@v3 if: startsWith(github.ref, 'refs/tags/v') - name: Publish package distributions to PyPI if: startsWith(github.ref, 'refs/tags/v') run: pdm publish continue-on-error: true # Job 打包应用, 发布镜像和 Release # 仅在 main 分支或以 v 开头的标签运行 - name: Package /app for amd64 if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v') run: | docker run --rm --entrypoint /bin/sh -v $PWD:/workspace ${{ env.TEST_TAG }}-linux-amd64 -c \ "tar czf /workspace/app-amd64.tar.gz -C / app" - name: Package /app (lite) for amd64 if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v') run: | docker run --rm --entrypoint /bin/sh -v $PWD:/workspace ${{ env.TEST_TAG }}-linux-amd64 -c \ "cd /app && tar --exclude='ffmpeg' -czf /workspace/app-amd64-lite.tar.gz .[!.]* *" - name: Package /app for arm64 if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v') run: | docker run --rm --entrypoint /bin/sh -v $PWD:/workspace ${{ env.TEST_TAG }}-linux-arm64 -c \ "tar czf /workspace/app-arm64.tar.gz -C / app" - name: Package /app (lite) for arm64 if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v') run: | docker run --rm --entrypoint /bin/sh -v $PWD:/workspace ${{ env.TEST_TAG }}-linux-arm64 -c \ "cd /app && tar --exclude='ffmpeg' -czf /workspace/app-arm64-lite.tar.gz .[!.]* *" - name: Package /app for arm/v7 if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v') run: | docker run --rm --entrypoint /bin/sh -v $PWD:/workspace ${{ env.TEST_TAG }}-linux-arm-v7 -c \ "tar czf /workspace/app-arm-v7.tar.gz -C / app" - name: Package /app (lite) for arm/v7 if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v') run: | docker run --rm --entrypoint /bin/sh -v $PWD:/workspace ${{ env.TEST_TAG }}-linux-arm-v7 -c \ "cd /app && tar --exclude='ffmpeg' -czf /workspace/app-arm-v7-lite.tar.gz .[!.]* *" - name: Publish to Docker Hub main if: github.ref == 'refs/heads/main' uses: docker/build-push-action@v6 with: platforms: linux/amd64,linux/arm64,linux/arm/v7 context: . push: true tags: ${{ env.TEST_TAG }} cache-from: type=local,src=/tmp/.buildx-cache-new cache-to: type=local,dest=/tmp/.buildx-cache-new # 仅在 ref 为以 v 开头的标签时执行 - name: Publish to Docker Hub latest and stable if: startsWith(github.ref, 'refs/tags/v') uses: docker/build-push-action@v6 with: platforms: linux/amd64,linux/arm64,linux/arm/v7 context: . push: true tags: ${{ env.TEST_TAG }}, ${{ env.LATEST_TAG }}, ${{ env.STABLE_TAG }} cache-from: type=local,src=/tmp/.buildx-cache-new cache-to: type=local,dest=/tmp/.buildx-cache-new - name: Move cache to limit growth run: | rm -rf /tmp/.buildx-cache mv /tmp/.buildx-cache-new /tmp/.buildx-cache # 上传文件到 release 页面 - name: Install GitHub CLI if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v') run: | sudo apt update sudo apt install -y gh # 创建或更新 Release - name: Create or update Release main if: github.ref == 'refs/heads/main' env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} # 设置 GH_TOKEN 环境变量 run: | RELEASE_NAME=test RELEASE_BODY="This release is automatically updated from the main branch." # 检查是否已有同名 Release EXISTING_RELEASE=$(gh release view "${RELEASE_NAME}" --json id --jq .id || echo "") if [[ -n "${EXISTING_RELEASE}" ]]; then echo "release exist" else # 创建新的 Release gh release create "${RELEASE_NAME}" \ --prerelease=false \ --title "${RELEASE_NAME}" \ --notes "${RELEASE_BODY}" fi - name: Create or update Release tag if: startsWith(github.ref, 'refs/tags/v') env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} # 设置 GH_TOKEN 环境变量 run: | RELEASE_NAME=${{ github.ref_name }} RELEASE_BODY="This release is automatically updated from the ${RELEASE_NAME} branch." # 检查是否已有同名 Release EXISTING_RELEASE=$(gh release view "${RELEASE_NAME}" --json id --jq .id || echo "") if [[ -n "${EXISTING_RELEASE}" ]]; then echo "release exist" else # 创建新的 Release gh release create "${RELEASE_NAME}" \ --prerelease=false \ --title "${RELEASE_NAME}" \ --notes "${RELEASE_BODY}" fi # 上传多个文件并覆盖 - name: Upload assets to Release main if: github.ref == 'refs/heads/main' env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} # 设置 GH_TOKEN 环境变量 run: | RELEASE_NAME=test FILES=$(find . -type f -name "app-*.tar.gz") for FILE in ${FILES}; do echo "type upload ${FILE}" gh release upload "${RELEASE_NAME}" "${FILE}" --clobber done - name: Upload assets to Release tag if: startsWith(github.ref, 'refs/tags/v') env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} # 设置 GH_TOKEN 环境变量 run: | RELEASE_NAME=${{ github.ref_name }} FILES=$(find . -type f -name "app-*.tar.gz") for FILE in ${FILES}; do echo "type upload ${FILE}" gh release upload "${RELEASE_NAME}" "${FILE}" --clobber done