From a998f02f2bd032b3d554e83f677b08b383cccece Mon Sep 17 00:00:00 2001 From: ryan Date: Mon, 8 Jun 2026 20:47:48 +0800 Subject: [PATCH] ci --- .github/workflows/build-image.yml | 187 +++++++++++++++++++++++++++ .github/workflows/build-release.yml | 71 ++++++++++ .github/workflows/build_backend.yml | 40 ------ .github/workflows/build_frontend.yml | 36 ------ .github/workflows/build_image.yml | 146 --------------------- 5 files changed, 258 insertions(+), 222 deletions(-) create mode 100644 .github/workflows/build-image.yml create mode 100644 .github/workflows/build-release.yml delete mode 100644 .github/workflows/build_backend.yml delete mode 100644 .github/workflows/build_frontend.yml delete mode 100644 .github/workflows/build_image.yml diff --git a/.github/workflows/build-image.yml b/.github/workflows/build-image.yml new file mode 100644 index 00000000..ab242f60 --- /dev/null +++ b/.github/workflows/build-image.yml @@ -0,0 +1,187 @@ +name: Docker image build (Server) + +on: + workflow_dispatch: + inputs: + version: + description: "Image version/tag to publish, for example v1.0.0-beta" + required: false + type: string + push: + tags: ["v*"] + +permissions: + contents: read + packages: write + attestations: write + id-token: write + +jobs: + build: + name: Build (${{ matrix.arch }}) + strategy: + fail-fast: false + matrix: + include: + - arch: amd64 + platform: linux/amd64 + runner: ubuntu-24.04 + - arch: arm64 + platform: linux/arm64 + runner: ubuntu-24.04-arm + runs-on: ${{ matrix.runner }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-tags: true + fetch-depth: 0 + persist-credentials: false + + - name: Set image metadata + shell: bash + env: + INPUT_VERSION: ${{ github.event.inputs.version }} + run: | + POINTED_TAG="$(git tag --points-at HEAD --list 'v*' | sort -V | tail -n1)" + INPUT_VERSION="${INPUT_VERSION//[[:space:]]/}" + + echo "IMAGE=ghcr.io/${GITHUB_REPOSITORY,,}" >> "$GITHUB_ENV" + if [[ "${GITHUB_REF}" == refs/tags/* ]]; then + VERSION="${GITHUB_REF_NAME}" + elif [[ -n "$INPUT_VERSION" ]]; then + VERSION="$INPUT_VERSION" + elif [[ -n "$POINTED_TAG" ]]; then + VERSION="$POINTED_TAG" + else + echo "workflow_dispatch requires an explicit version input when HEAD is not tagged" >&2 + exit 1 + fi + + echo "VERSION=$VERSION" >> "$GITHUB_ENV" + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v4 + + - name: Log into registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and push + id: build + uses: docker/build-push-action@v7 + with: + context: . + file: ./openflare-server/Dockerfile + platforms: ${{ matrix.platform }} + outputs: type=image,name=${{ env.IMAGE }},push-by-digest=true,name-canonical=true,push=true + build-args: | + VERSION=${{ env.VERSION }} + cache-from: type=gha,scope=docker-server-${{ matrix.arch }} + cache-to: type=gha,mode=max,ignore-error=true,timeout=20m,scope=docker-server-${{ matrix.arch }} + + - name: Export digest + shell: bash + run: | + mkdir -p /tmp/server-digests + touch "/tmp/server-digests/${DIGEST#sha256:}" + env: + DIGEST: ${{ steps.build.outputs.digest }} + + - name: Upload digest + uses: actions/upload-artifact@v4 + with: + name: server-digests-${{ matrix.arch }} + path: /tmp/server-digests/* + if-no-files-found: error + retention-days: 1 + + - name: Generate artifact attestation + uses: actions/attest-build-provenance@v3 + with: + subject-name: ${{ env.IMAGE }} + subject-digest: ${{ steps.build.outputs.digest }} + push-to-registry: true + + merge: + name: Merge multi-arch manifest + runs-on: ubuntu-24.04 + needs: build + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-tags: true + fetch-depth: 0 + persist-credentials: false + + - name: Set image metadata + shell: bash + env: + INPUT_VERSION: ${{ github.event.inputs.version }} + run: | + POINTED_TAG="$(git tag --points-at HEAD --list 'v*' | sort -V | tail -n1)" + INPUT_VERSION="${INPUT_VERSION//[[:space:]]/}" + + echo "IMAGE=ghcr.io/${GITHUB_REPOSITORY,,}" >> "$GITHUB_ENV" + if [[ "${GITHUB_REF}" == refs/tags/* ]]; then + VERSION="${GITHUB_REF_NAME}" + elif [[ -n "$INPUT_VERSION" ]]; then + VERSION="$INPUT_VERSION" + elif [[ -n "$POINTED_TAG" ]]; then + VERSION="$POINTED_TAG" + else + echo "workflow_dispatch requires an explicit version input when HEAD is not tagged" >&2 + exit 1 + fi + + echo "VERSION=$VERSION" >> "$GITHUB_ENV" + + - name: Download digests + uses: actions/download-artifact@v4 + with: + path: /tmp/server-digests + pattern: server-digests-* + merge-multiple: true + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v4 + + - name: Log into registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create and push manifest list + working-directory: /tmp/server-digests + shell: bash + run: | + shopt -s nullglob + references=() + for digest in *; do + references+=("${IMAGE}@sha256:${digest}") + done + + if [ ${#references[@]} -eq 0 ]; then + echo "No digests found in /tmp/server-digests" >&2 + exit 1 + fi + + if [[ "${VERSION}" =~ (alpha|beta|rc) ]]; then + FLOATING_TAG="beta" + else + FLOATING_TAG="latest" + fi + + docker buildx imagetools create \ + -t "${IMAGE}:${VERSION}" \ + -t "${IMAGE}:${FLOATING_TAG}" \ + "${references[@]}" + + - name: Inspect image + run: docker buildx imagetools inspect "${IMAGE}:${VERSION}" diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml new file mode 100644 index 00000000..3d977913 --- /dev/null +++ b/.github/workflows/build-release.yml @@ -0,0 +1,71 @@ +name: Build Release + +on: + push: + tags: + - "v*" + +permissions: + contents: write + packages: write + +jobs: + create-release: + name: Create Release + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v6 + with: + fetch-depth: 0 + + - name: Create Release + uses: softprops/action-gh-release@v2 + + - name: Setup node + uses: actions/setup-node@v6 + with: + node-version: 22 + + - run: npx changelogithub + env: + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} + + build-matrix: + name: Release Go Binary + runs-on: ubuntu-latest + strategy: + matrix: + goos: [linux, darwin, windows] + goarch: [amd64, arm64] + exclude: + - goos: windows + goarch: arm64 + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Extract version from Git Ref + id: extract_version + run: | + VERSION=$(echo "${{ github.ref }}" | sed 's/refs\/tags\/v//') + echo "VERSION=${VERSION}" >> $GITHUB_ENV + + - name: Release Go Binary + uses: wangyoucao577/go-release-action@v1 + with: + pre_command: export CGO_ENABLED=0 + goos: ${{ matrix.goos }} + goarch: ${{ matrix.goarch }} + github_token: ${{ secrets.GITHUB_TOKEN }} + extra_files: | + LICENSE + README.md + ldflags: >- + -s -w + -X "github.com/krau/SaveAny-Bot/config.Version=${{ env.VERSION }}" + -X "github.com/krau/SaveAny-Bot/config.BuildTime=${{ format(github.event.repository.updated_at, 'yyyy-MM-dd HH:mm:ss') }}" + -X "github.com/krau/SaveAny-Bot/config.GitCommit=${{ github.sha }}" + binary_name: saveany-bot + env: + VERSION: ${{ env.VERSION }} diff --git a/.github/workflows/build_backend.yml b/.github/workflows/build_backend.yml deleted file mode 100644 index 44885366..00000000 --- a/.github/workflows/build_backend.yml +++ /dev/null @@ -1,40 +0,0 @@ -name: Go Build - -on: - pull_request: - branches: [ "*" ] - push: - branches: - - "dev" - - "main" - -jobs: - go_build: - runs-on: ubuntu-24.04 - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up Go - uses: actions/setup-go@v5 - with: - go-version: "1.25" - check-latest: true - - - name: Install dependencies - run: | - go mod download - go install github.com/swaggo/swag/cmd/swag@v1.16.6 - - - name: Make Swagger - run: make swagger - - - name: Diff Files - run: | - if ! git diff --exit-code; then - echo 'Detected unstaged changes after command. Please make swagger locally.' - exit 1 - fi - - - name: Build - run: go build main.go diff --git a/.github/workflows/build_frontend.yml b/.github/workflows/build_frontend.yml deleted file mode 100644 index 5fd1ae43..00000000 --- a/.github/workflows/build_frontend.yml +++ /dev/null @@ -1,36 +0,0 @@ -name: NextJS Build - -on: - pull_request: - branches: [ "*" ] - push: - branches: - - "dev" - - "main" - -jobs: - nextjs_build: - runs-on: ubuntu-24.04 - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Install pnpm - uses: pnpm/action-setup@v4 - with: - version: 10.10.0 - - - name: Set up Node.js - uses: actions/setup-node@v4 - with: - node-version: "22" - cache: 'pnpm' - cache-dependency-path: frontend/pnpm-lock.yaml - - - name: Install dependencies - working-directory: frontend - run: pnpm install --frozen-lockfile - - - name: Build - working-directory: frontend - run: pnpm build diff --git a/.github/workflows/build_image.yml b/.github/workflows/build_image.yml deleted file mode 100644 index be89f726..00000000 --- a/.github/workflows/build_image.yml +++ /dev/null @@ -1,146 +0,0 @@ -name: Build Docker Images - -on: - push: - branches: - - "main" - tags: - - "*" - pull_request: - branches: - - "main" - -env: - REGISTRY: ghcr.io - IMAGE_NAME: ${{ github.repository }} - FRONTEND_IMAGE_NAME: ${{ github.repository }}-frontend - BACKEND_IMAGE_NAME: ${{ github.repository }}-backend - -permissions: - contents: read - packages: write - -jobs: - build_integrated_image: - name: Build integrated image - runs-on: ubuntu-24.04 - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Log into registry - uses: docker/login-action@v3 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Extract Docker metadata - id: meta - uses: docker/metadata-action@v5 - with: - images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} - tags: | - type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }} - type=semver,pattern={{version}} - type=semver,pattern={{major}}.{{minor}} - type=ref,event=tag - type=sha,format=short,prefix= - - - name: Build Docker image - uses: docker/build-push-action@v5 - with: - context: . - file: docker/Dockerfile - push: ${{ github.ref_type == 'tag' || (github.ref == 'refs/heads/main' && github.event_name == 'push') }} - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - platforms: linux/amd64,linux/arm64 - - build_frontend_image: - name: Build frontend image - runs-on: ubuntu-24.04 - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Log into registry - uses: docker/login-action@v3 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Extract Docker metadata - id: meta - uses: docker/metadata-action@v5 - with: - images: ${{ env.REGISTRY }}/${{ env.FRONTEND_IMAGE_NAME }} - tags: | - type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }} - type=semver,pattern={{version}} - type=semver,pattern={{major}}.{{minor}} - type=ref,event=tag - type=sha,format=short,prefix= - - - name: Generate frontend build date - id: frontend_build_meta - run: echo "build_date=$(date -u +'%Y/%m/%d UTC')" >> "$GITHUB_OUTPUT" - - - name: Build Frontend Docker image - uses: docker/build-push-action@v5 - with: - context: . - file: docker/Dockerfile.frontend - push: ${{ github.ref_type == 'tag' || (github.ref == 'refs/heads/main' && github.event_name == 'push') }} - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - platforms: linux/amd64,linux/arm64 - build-args: | - VERSION=${{ github.ref_type == 'tag' && github.ref_name || '' }} - BUILD_DATE=${{ steps.frontend_build_meta.outputs.build_date }} - - build_backend_image: - name: Build backend image - runs-on: ubuntu-24.04 - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Log into registry - uses: docker/login-action@v3 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Extract Docker metadata - id: meta - uses: docker/metadata-action@v5 - with: - images: ${{ env.REGISTRY }}/${{ env.BACKEND_IMAGE_NAME }} - tags: | - type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }} - type=semver,pattern={{version}} - type=semver,pattern={{major}}.{{minor}} - type=ref,event=tag - type=sha,format=short,prefix= - - - name: Build Backend Docker image - uses: docker/build-push-action@v5 - with: - context: . - file: docker/Dockerfile.backend - push: ${{ github.ref_type == 'tag' || (github.ref == 'refs/heads/main' && github.event_name == 'push') }} - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - platforms: linux/amd64,linux/arm64