diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml new file mode 100644 index 00000000..d6c386cd --- /dev/null +++ b/.gitea/workflows/release.yml @@ -0,0 +1,121 @@ +name: Release + +on: + workflow_dispatch: + push: + tags: ["v*"] + +jobs: + release: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: https://github.com/actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Resolve version metadata + id: version + shell: bash + run: | + SHOULD_RUN=true + POINTED_TAG="$(git tag --points-at HEAD --list 'v*' | sort -V | tail -n1)" + + if [[ "${GITHUB_REF}" == refs/heads/main ]] && [[ -n "$POINTED_TAG" ]]; then + SHOULD_RUN=false + VERSION="$POINTED_TAG" + elif [[ "${GITHUB_REF}" == refs/tags/* ]]; then + VERSION="${GITHUB_REF_NAME}" + else + VERSION="$(git describe --tags)" + fi + + echo "should_run=$SHOULD_RUN" >> "$GITHUB_OUTPUT" + echo "version=$VERSION" >> "$GITHUB_OUTPUT" + if [[ "$VERSION" =~ ^v[0-9]+(\.[0-9]+)*$ ]]; then + echo "is_prerelease=false" >> "$GITHUB_OUTPUT" + else + echo "is_prerelease=true" >> "$GITHUB_OUTPUT" + fi + + - name: Set up Node.js + if: steps.version.outputs.should_run == 'true' + uses: https://github.com/actions/setup-node@v4 + with: + node-version: 18 + + - name: Build Frontend + if: steps.version.outputs.should_run == 'true' + env: + CI: "" + VERSION: ${{ steps.version.outputs.version }} + run: | + cd atsf_server/web + npm install + REACT_APP_VERSION="$VERSION" npm run build + + - name: Set up Go + if: steps.version.outputs.should_run == 'true' + uses: https://github.com/actions/setup-go@v5 + with: + go-version-file: atsf_server/go.mod + + - name: Build Server Binaries + if: steps.version.outputs.should_run == 'true' + shell: bash + env: + CGO_ENABLED: 0 + VERSION: ${{ steps.version.outputs.version }} + run: | + set -euo pipefail + + mkdir -p dist + + cd atsf_server + go mod download + + while read -r GOOS GOARCH ASSET_NAME; do + GOOS="$GOOS" GOARCH="$GOARCH" \ + go build -trimpath -ldflags "-s -w -X 'atsflare/common.Version=$VERSION'" -o "../dist/$ASSET_NAME" . + done <<'EOF' + linux amd64 atsflare-server-linux-amd64 + linux arm64 atsflare-server-linux-arm64 + darwin amd64 atsflare-server-darwin-amd64 + darwin arm64 atsflare-server-darwin-arm64 + windows amd64 atsflare-server-windows-amd64.exe + EOF + + - name: Build Agent Binaries + if: steps.version.outputs.should_run == 'true' + shell: bash + env: + CGO_ENABLED: 0 + VERSION: ${{ steps.version.outputs.version }} + run: | + set -euo pipefail + + cd atsf_agent + go mod download + + while read -r GOOS GOARCH ASSET_NAME; do + GOOS="$GOOS" GOARCH="$GOARCH" \ + go build -trimpath -ldflags "-s -w -X 'atsflare-agent/internal/config.AgentVersion=$VERSION'" -o "../dist/$ASSET_NAME" ./cmd/agent + done <<'EOF' + linux amd64 atsflare-agent-linux-amd64 + linux arm64 atsflare-agent-linux-arm64 + darwin amd64 atsflare-agent-darwin-amd64 + darwin arm64 atsflare-agent-darwin-arm64 + windows amd64 atsflare-agent-windows-amd64.exe + EOF + + - name: Publish Release + if: steps.version.outputs.should_run == 'true' + uses: https://gitea.com/actions/gitea-release-action@v1 + with: + tag_name: ${{ steps.version.outputs.version }} + name: ${{ steps.version.outputs.version }} + target_commitish: ${{ github.sha }} + files: | + dist/* + draft: false + prerelease: ${{ steps.version.outputs.is_prerelease == 'true' }} diff --git a/.github/workflows/docker-image-amd64.yml b/.github/workflows/docker-image-amd64.yml deleted file mode 100644 index 43705321..00000000 --- a/.github/workflows/docker-image-amd64.yml +++ /dev/null @@ -1,54 +0,0 @@ -name: Publish Docker image (amd64) - -on: - push: - tags: - - '*' - workflow_dispatch: - inputs: - name: - description: 'reason' - required: false -jobs: - push_to_registries: - name: Push Docker image to multiple registries - runs-on: ubuntu-latest - permissions: - packages: write - contents: read - steps: - - name: Check out the repo - uses: actions/checkout@v3 - - - name: Save version info - run: | - git describe --tags > VERSION - - - name: Log in to Docker Hub - uses: docker/login-action@v2 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Log in to the Container registry - uses: docker/login-action@v2 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Extract metadata (tags, labels) for Docker - id: meta - uses: docker/metadata-action@v4 - with: - images: | - ghcr.io/rain-kl/atsflare - ghcr.io/${{ github.repository }} - - - name: Build and push Docker images - uses: docker/build-push-action@v3 - with: - context: . - push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} \ No newline at end of file diff --git a/.github/workflows/docker-image-arm64.yml b/.github/workflows/docker-image-arm64.yml deleted file mode 100644 index 91e84156..00000000 --- a/.github/workflows/docker-image-arm64.yml +++ /dev/null @@ -1,62 +0,0 @@ -name: Publish Docker image (arm64) - -on: - push: - tags: - - '*' - - '!*-alpha*' - workflow_dispatch: - inputs: - name: - description: 'reason' - required: false -jobs: - push_to_registries: - name: Push Docker image to multiple registries - runs-on: ubuntu-latest - permissions: - packages: write - contents: read - steps: - - name: Check out the repo - uses: actions/checkout@v3 - - - name: Save version info - run: | - git describe --tags > VERSION - - - name: Set up QEMU - uses: docker/setup-qemu-action@v2 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 - - - name: Log in to Docker Hub - uses: docker/login-action@v2 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Log in to the Container registry - uses: docker/login-action@v2 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Extract metadata (tags, labels) for Docker - id: meta - uses: docker/metadata-action@v4 - with: - images: | - ghcr.io/rain-kl/atsflare - ghcr.io/${{ github.repository }} - - - name: Build and push Docker images - uses: docker/build-push-action@v3 - with: - context: . - platforms: linux/amd64,linux/arm64 - push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} \ No newline at end of file diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml new file mode 100644 index 00000000..b0d7c773 --- /dev/null +++ b/.github/workflows/docker-image.yml @@ -0,0 +1,63 @@ +name: Docker image builds + +on: + workflow_dispatch: + push: + tags: ["v*"] + +permissions: + contents: read + packages: write + attestations: write + id-token: write + +jobs: + build: + runs-on: ubuntu-24.04 + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-tags: true + fetch-depth: 0 + persist-credentials: false + + - name: Set lowercase image name + id: meta + shell: bash + run: | + echo "image=ghcr.io/${GITHUB_REPOSITORY,,}" >> "$GITHUB_OUTPUT" + echo "version=$(git describe --tags)" >> "$GITHUB_OUTPUT" + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - 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@v6 + with: + context: ./atsf_server + file: ./atsf_server/Dockerfile + push: true + tags: | + ${{ steps.meta.outputs.image }}:${{ steps.meta.outputs.version }} + ${{ steps.meta.outputs.image }}:latest + build-args: | + VERSION=${{ steps.meta.outputs.version }} + cache-from: type=gha + cache-to: type=gha,mode=max + platforms: linux/amd64,linux/arm64 + + - name: Generate artifact attestation + uses: actions/attest-build-provenance@v3 + with: + subject-name: ${{ steps.meta.outputs.image }} + subject-digest: ${{ steps.build.outputs.digest }} + push-to-registry: true diff --git a/.github/workflows/github-pages.yml b/.github/workflows/github-pages.yml index 51453080..cbc31445 100644 --- a/.github/workflows/github-pages.yml +++ b/.github/workflows/github-pages.yml @@ -1,29 +1,29 @@ -name: Build GitHub Pages -on: - workflow_dispatch: - inputs: - name: - description: 'Reason' - required: false -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - - name: Checkout 🛎️ - uses: actions/checkout@v2 # If you're using actions/checkout@v2 you must set persist-credentials to false in most cases for the deployment to work correctly. - with: - persist-credentials: false - - name: Install and Build 🔧 # This example project is built using npm and outputs the result to the 'build' folder. Replace with the commands required to build your project, or remove this step entirely if your site is pre-built. - env: - CI: "" - run: | - cd web - npm install - npm run build - - - name: Deploy 🚀 - uses: JamesIves/github-pages-deploy-action@releases/v3 - with: - ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }} - BRANCH: gh-pages # The branch the action should deploy to. +name: Build GitHub Pages +on: + workflow_dispatch: + inputs: + name: + description: 'Reason' + required: false +jobs: + build-and-deploy: + runs-on: ubuntu-latest + steps: + - name: Checkout 🛎️ + uses: actions/checkout@v2 # If you're using actions/checkout@v2 you must set persist-credentials to false in most cases for the deployment to work correctly. + with: + persist-credentials: false + - name: Install and Build 🔧 # This example project is built using npm and outputs the result to the 'build' folder. Replace with the commands required to build your project, or remove this step entirely if your site is pre-built. + env: + CI: "" + run: | + cd atsf_server/web + npm install + npm run build + + - name: Deploy 🚀 + uses: JamesIves/github-pages-deploy-action@releases/v3 + with: + ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }} + BRANCH: gh-pages # The branch the action should deploy to. FOLDER: web/build # The folder the action should deploy. \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d3ff70ca..8a00c19e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -5,7 +5,6 @@ permissions: on: workflow_dispatch: push: - branches: ["main"] tags: ["v*"] jobs: diff --git a/atsf_server/Dockerfile b/atsf_server/Dockerfile index 71efbcf4..9b26093f 100644 --- a/atsf_server/Dockerfile +++ b/atsf_server/Dockerfile @@ -1,22 +1,28 @@ -FROM node:16 as builder +ARG VERSION=dev + +FROM node:18 AS builder + +ARG VERSION WORKDIR /build -COPY ./web . -COPY ./VERSION . +COPY ./web/package*.json ./ RUN npm install -RUN REACT_APP_VERSION=$(cat VERSION) npm run build +COPY ./web ./ +RUN REACT_APP_VERSION="$VERSION" npm run build -FROM golang AS builder2 +FROM golang:1.22 AS builder2 + +ARG VERSION ENV GO111MODULE=on \ - CGO_ENABLED=1 \ + CGO_ENABLED=0 \ GOOS=linux WORKDIR /build COPY . . COPY --from=builder /build/build ./web/build RUN go mod download -RUN go build -ldflags "-s -w -X 'atsflare/common.Version=$(cat VERSION)' -extldflags '-static'" -o atsflare +RUN go build -trimpath -ldflags "-s -w -X 'atsflare/common.Version=$VERSION'" -o atsflare FROM alpine diff --git a/docs/deployment.md b/docs/deployment.md index d782466c..fb4b79d9 100644 --- a/docs/deployment.md +++ b/docs/deployment.md @@ -191,6 +191,19 @@ cd atsf_server/web npm run build ``` +### 6.4 发布工作流 + +当前仓库维护两套独立的 Release 工作流: + +* GitHub 使用 [.github/workflows/release.yml](.github/workflows/release.yml),保留制品上传/下载分阶段流程 +* Gitea 使用 [.gitea/workflows/release.yml](.gitea/workflows/release.yml),在单个 Job 内完成前端构建、服务端/Agent 多平台编译与 Release 发布,避免依赖 Gitea 目前不兼容的 `upload-artifact@v4`、`download-artifact@v4` + +Docker 镜像发布使用 [.github/workflows/docker-image.yml](.github/workflows/docker-image.yml): + +* 仅构建 `atsf_server` 服务端镜像 +* 发布到 GitHub Container Registry(`ghcr.io//:`) +* 单个工作流同时产出 `linux/amd64` 与 `linux/arm64` 多架构镜像 + --- ## 7. Agent 一键部署(V3)