name: Build & Publish All-in-One on: push: branches: [main] tags: [v*] workflow_dispatch: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BIN_NAME: spage BIN_OUT: build # for Go build GO_PKG_ROOT: github.com/LiteyukiStudio/spage # for container build CONTAINER_PLATFORMS: linux/amd64,linux/arm64,linux/386,linux/arm,linux/ppc64le,linux/s390x REG_GHCR: ghcr.io REG_DOCKERHUB: docker.io REG_LCR: reg.liteyuki.org NAMESPACE_GHCR: liteyukistudio NAMESPACE_DOCKERHUB: liteyukistudio NAMESPACE_LCR: spage concurrency: group: "build-aio" cancel-in-progress: true permissions: contents: write packages: write jobs: build: name: Build runs-on: ubuntu-latest outputs: version: ${{ steps.version.outputs.version }} tag: ${{ steps.version.outputs.tag }} nightly: ${{ steps.version.outputs.nightly }} strategy: matrix: include: - goos: darwin goarch: amd64 - goos: darwin goarch: arm64 - goos: freebsd goarch: amd64 - goos: freebsd goarch: arm64 - goos: freebsd goarch: 386 - goos: freebsd goarch: arm - goos: linux goarch: amd64 - goos: linux goarch: arm64 - goos: linux goarch: 386 - goos: linux goarch: arm - goos: linux goarch: ppc64le - goos: linux goarch: s390x - goos: windows goarch: amd64 - goos: windows goarch: arm64 steps: - name: Checkout code uses: actions/checkout@v4 - name: Setup Go uses: actions/setup-go@v5 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: 22 - name: Set version/tag id: version run: | if [[ "${GITHUB_REF}" == refs/tags/v* ]]; then VERSION="${GITHUB_REF#refs/tags/}" TAG="${VERSION}" NIGHTLY="false" else VERSION="${GITHUB_SHA}" TAG="nightly" NIGHTLY="true" fi echo "version=${VERSION}" >> $GITHUB_OUTPUT echo "tag=${TAG}" >> $GITHUB_OUTPUT echo "nightly=${NIGHTLY}" >> $GITHUB_OUTPUT - name: Build frontend run: | cd web-src npm install pnpm -g pnpm install pnpm build cp -r out/* ../static/dist/ - name: Build Go binary continue-on-error: true env: GOOS: ${{ matrix.goos }} GOARCH: ${{ matrix.goarch }} run: | mkdir -p ${{ env.BIN_OUT }} if [ "${{ matrix.goos }}" = "windows" ]; then BIN_OUT="${{ env.BIN_OUT }}/${{ env.BIN_NAME }}-${{ matrix.goos }}-${{ matrix.goarch }}.exe" else BIN_OUT="${{ env.BIN_OUT }}/${{ env.BIN_NAME }}-${{ matrix.goos }}-${{ matrix.goarch }}" fi go build \ -ldflags \ "-X '${{ env.GO_PKG_ROOT }}/config.CommitHash=${{ github.sha }}' \ -X '${{ env.GO_PKG_ROOT }}/config.BuildTime=$(date -u +%Y-%m-%dT%H:%M:%SZ)' \ -X '${{ env.GO_PKG_ROOT }}/config.Version=${{ steps.version.outputs.version }}'" \ -o $BIN_OUT ./cmd/server - name: Upload artifact uses: actions/upload-artifact@v4 with: name: ${{ env.BIN_NAME }}-${{ matrix.goos }}-${{ matrix.goarch }} path: | ${{ env.BIN_OUT }}/${{ env.BIN_NAME }}-${{ matrix.goos }}-${{ matrix.goarch }}* publish: name: Publish Artifacts & Images runs-on: ubuntu-latest needs: build steps: - name: Checkout code uses: actions/checkout@v4 - name: Download all artifacts for release uses: actions/download-artifact@v4 with: pattern: ${{ env.BIN_NAME }}-* path: ${{ env.BIN_OUT }} # Linux Container - name: Prepare binaries for Docker build run: | set -e ls -l build/ for arch in amd64 arm64 386 arm ppc64le s390x; do if [ -f build/${{ env.BIN_NAME }}-linux-$arch/${{ env.BIN_NAME }}-linux-$arch ]; then mkdir -p build/linux-$arch cp build/${{ env.BIN_NAME }}-linux-$arch/${{ env.BIN_NAME }}-linux-$arch build/linux-$arch/${{ env.BIN_NAME }} fi done ls -l build/linux-amd64/ - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 - name: Login to GHCR uses: docker/login-action@v3 with: registry: ${{ env.REG_GHCR }} username: ${{ secrets.GHCR_USER }} password: ${{ secrets.GHCR_TOKEN }} - name: Login to DockerHub uses: docker/login-action@v3 with: registry: ${{ env.REG_DOCKERHUB }} username: ${{ secrets.DOCKERHUB_USER }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Login to LCR uses: docker/login-action@v3 with: registry: ${{ env.REG_LCR }} username: ${{ secrets.LITEYUKIREG_USER }} password: ${{ secrets.LITEYUKIREG_TOKEN }} # 有 tag 时推送 版本号、latest、nightly 三个标签 - name: Build & Push Docker Images (tag & latest) if: ${{ needs.build.outputs.nightly == 'false' }} uses: docker/build-push-action@v6 with: context: . push: true tags: | ${{ env.NAMESPACE_DOCKERHUB }}/${{ env.BIN_NAME }}:${{ needs.build.outputs.tag }} ${{ env.NAMESPACE_DOCKERHUB }}/${{ env.BIN_NAME }}:latest ${{ env.NAMESPACE_DOCKERHUB }}/${{ env.BIN_NAME }}:nightly ${{ env.REG_GHCR }}/${{ env.NAMESPACE_GHCR }}/${{ env.BIN_NAME }}:${{ needs.build.outputs.tag }} ${{ env.REG_GHCR }}/${{ env.NAMESPACE_GHCR }}/${{ env.BIN_NAME }}:latest ${{ env.REG_GHCR }}/${{ env.NAMESPACE_GHCR }}/${{ env.BIN_NAME }}:nightly ${{ env.REG_LCR }}/${{ env.NAMESPACE_LCR }}/${{ env.BIN_NAME }}:${{ needs.build.outputs.tag }} ${{ env.REG_LCR }}/${{ env.NAMESPACE_LCR }}/${{ env.BIN_NAME }}:latest ${{ env.REG_LCR }}/${{ env.NAMESPACE_LCR }}/${{ env.BIN_NAME }}:nightly platforms: ${{ env.CONTAINER_PLATFORMS }} # nightly 时只推送 nightly - name: Build & Push Docker Images (nightly only) if: ${{ needs.build.outputs.nightly == 'true' }} uses: docker/build-push-action@v6 with: context: . push: true tags: | ${{ env.NAMESPACE_DOCKERHUB }}/${{ env.BIN_NAME }}:nightly ${{ env.REG_GHCR }}/${{ env.NAMESPACE_GHCR }}/${{ env.BIN_NAME }}:nightly ${{ env.REG_LCR }}/${{ env.NAMESPACE_LCR }}/${{ env.BIN_NAME }}:nightly platforms: ${{ env.CONTAINER_PLATFORMS }} - name: Prepare release assets run: | mkdir -p release-assets find build -type f -name "${{ env.BIN_NAME }}-*" -exec cp {} release-assets/ \; - name: Publish GitHub Release if: ${{ needs.build.outputs.nightly == 'false' }} uses: softprops/action-gh-release@v2.3.0 with: tag_name: ${{ needs.build.outputs.tag }} name: Release ${{ needs.build.outputs.tag }} body: | Release ${{ needs.build.outputs.tag }} Built from tag ${{ needs.build.outputs.tag }} files: release-assets/*