This commit is contained in:
ryan
2026-06-20 13:27:18 +08:00
parent cdac1f8a45
commit 6975a6c290
25 changed files with 1081 additions and 587 deletions
@@ -1,4 +1,4 @@
name: Docker image build (OpenFlared)
name: Build Image (openflare-agent)
on:
workflow_dispatch:
@@ -16,6 +16,10 @@ permissions:
attestations: write
id-token: write
env:
IMAGE_NAME: openflare-agent
DOCKERFILE: docker/Dockerfile.agent
jobs:
build:
name: Build (${{ matrix.arch }})
@@ -46,7 +50,8 @@ jobs:
POINTED_TAG="$(git tag --points-at HEAD --list 'v*' | sort -V | tail -n1)"
INPUT_VERSION="${INPUT_VERSION//[[:space:]]/}"
echo "IMAGE=ghcr.io/${GITHUB_REPOSITORY_OWNER,,}/openflared" >> "$GITHUB_ENV"
OWNER="${GITHUB_REPOSITORY_OWNER,,}"
if [[ "${GITHUB_REF}" == refs/tags/* ]]; then
VERSION="${GITHUB_REF_NAME}"
elif [[ -n "$INPUT_VERSION" ]]; then
@@ -58,6 +63,7 @@ jobs:
exit 1
fi
echo "IMAGE=ghcr.io/${OWNER}/openflare-agent" >> "$GITHUB_ENV"
echo "VERSION=$VERSION" >> "$GITHUB_ENV"
- name: Set up Docker Buildx
@@ -75,27 +81,27 @@ jobs:
uses: docker/build-push-action@v7
with:
context: .
file: ./openflared/Dockerfile
file: ${{ env.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-flared-${{ matrix.arch }}
cache-to: type=gha,mode=max,ignore-error=true,timeout=20m,scope=docker-flared-${{ matrix.arch }}
cache-from: type=gha,scope=docker-${{ env.IMAGE_NAME }}-${{ matrix.arch }}
cache-to: type=gha,mode=max,ignore-error=true,timeout=20m,scope=docker-${{ env.IMAGE_NAME }}-${{ matrix.arch }}
- name: Export digest
shell: bash
run: |
mkdir -p /tmp/flared-digests
touch "/tmp/flared-digests/${DIGEST#sha256:}"
mkdir -p "/tmp/${{ env.IMAGE_NAME }}-digests"
touch "/tmp/${{ env.IMAGE_NAME }}-digests/${DIGEST#sha256:}"
env:
DIGEST: ${{ steps.build.outputs.digest }}
- name: Upload digest
uses: actions/upload-artifact@v4
with:
name: flared-digests-${{ matrix.arch }}
path: /tmp/flared-digests/*
name: ${{ env.IMAGE_NAME }}-digests-${{ matrix.arch }}
path: /tmp/${{ env.IMAGE_NAME }}-digests/*
if-no-files-found: error
retention-days: 1
@@ -126,7 +132,8 @@ jobs:
POINTED_TAG="$(git tag --points-at HEAD --list 'v*' | sort -V | tail -n1)"
INPUT_VERSION="${INPUT_VERSION//[[:space:]]/}"
echo "IMAGE=ghcr.io/${GITHUB_REPOSITORY_OWNER,,}/openflared" >> "$GITHUB_ENV"
OWNER="${GITHUB_REPOSITORY_OWNER,,}"
if [[ "${GITHUB_REF}" == refs/tags/* ]]; then
VERSION="${GITHUB_REF_NAME}"
elif [[ -n "$INPUT_VERSION" ]]; then
@@ -138,13 +145,14 @@ jobs:
exit 1
fi
echo "IMAGE=ghcr.io/${OWNER}/openflare-agent" >> "$GITHUB_ENV"
echo "VERSION=$VERSION" >> "$GITHUB_ENV"
- name: Download digests
uses: actions/download-artifact@v4
with:
path: /tmp/flared-digests
pattern: flared-digests-*
path: /tmp/${{ env.IMAGE_NAME }}-digests
pattern: ${{ env.IMAGE_NAME }}-digests-*
merge-multiple: true
- name: Set up Docker Buildx
@@ -158,7 +166,7 @@ jobs:
password: ${{ secrets.GITHUB_TOKEN }}
- name: Create and push manifest list
working-directory: /tmp/flared-digests
working-directory: /tmp/${{ env.IMAGE_NAME }}-digests
shell: bash
run: |
shopt -s nullglob
@@ -168,7 +176,7 @@ jobs:
done
if [ ${#references[@]} -eq 0 ]; then
echo "No digests found in /tmp/flared-digests" >&2
echo "No digests found in /tmp/${{ env.IMAGE_NAME }}-digests" >&2
exit 1
fi
@@ -182,6 +190,8 @@ jobs:
-t "${IMAGE}:${VERSION}" \
-t "${IMAGE}:${FLOATING_TAG}" \
"${references[@]}"
env:
IMAGE: ${{ env.IMAGE }}
- name: Inspect image
run: docker buildx imagetools inspect "${IMAGE}:${VERSION}"
run: docker buildx imagetools inspect "${{ env.IMAGE }}:${{ env.VERSION }}"
@@ -1,4 +1,4 @@
name: Docker image build (Relay)
name: Build Image (openflare-relay)
on:
workflow_dispatch:
@@ -16,6 +16,10 @@ permissions:
attestations: write
id-token: write
env:
IMAGE_NAME: openflare-relay
DOCKERFILE: docker/Dockerfile.relay
jobs:
build:
name: Build (${{ matrix.arch }})
@@ -46,7 +50,8 @@ jobs:
POINTED_TAG="$(git tag --points-at HEAD --list 'v*' | sort -V | tail -n1)"
INPUT_VERSION="${INPUT_VERSION//[[:space:]]/}"
echo "IMAGE=ghcr.io/${GITHUB_REPOSITORY,,}-relay" >> "$GITHUB_ENV"
OWNER="${GITHUB_REPOSITORY_OWNER,,}"
if [[ "${GITHUB_REF}" == refs/tags/* ]]; then
VERSION="${GITHUB_REF_NAME}"
elif [[ -n "$INPUT_VERSION" ]]; then
@@ -58,6 +63,7 @@ jobs:
exit 1
fi
echo "IMAGE=ghcr.io/${OWNER}/openflare-relay" >> "$GITHUB_ENV"
echo "VERSION=$VERSION" >> "$GITHUB_ENV"
- name: Set up Docker Buildx
@@ -75,27 +81,27 @@ jobs:
uses: docker/build-push-action@v7
with:
context: .
file: ./openflare-relay/Dockerfile
file: ${{ env.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-relay-${{ matrix.arch }}
cache-to: type=gha,mode=max,ignore-error=true,timeout=20m,scope=docker-relay-${{ matrix.arch }}
cache-from: type=gha,scope=docker-${{ env.IMAGE_NAME }}-${{ matrix.arch }}
cache-to: type=gha,mode=max,ignore-error=true,timeout=20m,scope=docker-${{ env.IMAGE_NAME }}-${{ matrix.arch }}
- name: Export digest
shell: bash
run: |
mkdir -p /tmp/relay-digests
touch "/tmp/relay-digests/${DIGEST#sha256:}"
mkdir -p "/tmp/${{ env.IMAGE_NAME }}-digests"
touch "/tmp/${{ env.IMAGE_NAME }}-digests/${DIGEST#sha256:}"
env:
DIGEST: ${{ steps.build.outputs.digest }}
- name: Upload digest
uses: actions/upload-artifact@v4
with:
name: relay-digests-${{ matrix.arch }}
path: /tmp/relay-digests/*
name: ${{ env.IMAGE_NAME }}-digests-${{ matrix.arch }}
path: /tmp/${{ env.IMAGE_NAME }}-digests/*
if-no-files-found: error
retention-days: 1
@@ -126,7 +132,8 @@ jobs:
POINTED_TAG="$(git tag --points-at HEAD --list 'v*' | sort -V | tail -n1)"
INPUT_VERSION="${INPUT_VERSION//[[:space:]]/}"
echo "IMAGE=ghcr.io/${GITHUB_REPOSITORY,,}-relay" >> "$GITHUB_ENV"
OWNER="${GITHUB_REPOSITORY_OWNER,,}"
if [[ "${GITHUB_REF}" == refs/tags/* ]]; then
VERSION="${GITHUB_REF_NAME}"
elif [[ -n "$INPUT_VERSION" ]]; then
@@ -138,13 +145,14 @@ jobs:
exit 1
fi
echo "IMAGE=ghcr.io/${OWNER}/openflare-relay" >> "$GITHUB_ENV"
echo "VERSION=$VERSION" >> "$GITHUB_ENV"
- name: Download digests
uses: actions/download-artifact@v4
with:
path: /tmp/relay-digests
pattern: relay-digests-*
path: /tmp/${{ env.IMAGE_NAME }}-digests
pattern: ${{ env.IMAGE_NAME }}-digests-*
merge-multiple: true
- name: Set up Docker Buildx
@@ -158,7 +166,7 @@ jobs:
password: ${{ secrets.GITHUB_TOKEN }}
- name: Create and push manifest list
working-directory: /tmp/relay-digests
working-directory: /tmp/${{ env.IMAGE_NAME }}-digests
shell: bash
run: |
shopt -s nullglob
@@ -168,7 +176,7 @@ jobs:
done
if [ ${#references[@]} -eq 0 ]; then
echo "No digests found in /tmp/relay-digests" >&2
echo "No digests found in /tmp/${{ env.IMAGE_NAME }}-digests" >&2
exit 1
fi
@@ -182,6 +190,8 @@ jobs:
-t "${IMAGE}:${VERSION}" \
-t "${IMAGE}:${FLOATING_TAG}" \
"${references[@]}"
env:
IMAGE: ${{ env.IMAGE }}
- name: Inspect image
run: docker buildx imagetools inspect "${IMAGE}:${VERSION}"
run: docker buildx imagetools inspect "${{ env.IMAGE }}:${{ env.VERSION }}"
@@ -1,4 +1,4 @@
name: Docker image build (Server)
name: Build Image (openflare)
on:
workflow_dispatch:
@@ -16,6 +16,10 @@ permissions:
attestations: write
id-token: write
env:
IMAGE_NAME: openflare
DOCKERFILE: docker/Dockerfile
jobs:
build:
name: Build (${{ matrix.arch }})
@@ -46,7 +50,8 @@ jobs:
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"
OWNER="${GITHUB_REPOSITORY_OWNER,,}"
if [[ "${GITHUB_REF}" == refs/tags/* ]]; then
VERSION="${GITHUB_REF_NAME}"
elif [[ -n "$INPUT_VERSION" ]]; then
@@ -58,7 +63,9 @@ jobs:
exit 1
fi
echo "IMAGE=ghcr.io/${OWNER}/openflare" >> "$GITHUB_ENV"
echo "VERSION=$VERSION" >> "$GITHUB_ENV"
echo "BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> "$GITHUB_ENV"
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
@@ -75,27 +82,28 @@ jobs:
uses: docker/build-push-action@v7
with:
context: .
file: ./docker/Dockerfile
file: ${{ env.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 }}
BUILD_DATE=${{ env.BUILD_DATE }}
cache-from: type=gha,scope=docker-${{ env.IMAGE_NAME }}-${{ matrix.arch }}
cache-to: type=gha,mode=max,ignore-error=true,timeout=20m,scope=docker-${{ env.IMAGE_NAME }}-${{ matrix.arch }}
- name: Export digest
shell: bash
run: |
mkdir -p /tmp/server-digests
touch "/tmp/server-digests/${DIGEST#sha256:}"
mkdir -p "/tmp/${{ env.IMAGE_NAME }}-digests"
touch "/tmp/${{ env.IMAGE_NAME }}-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/*
name: ${{ env.IMAGE_NAME }}-digests-${{ matrix.arch }}
path: /tmp/${{ env.IMAGE_NAME }}-digests/*
if-no-files-found: error
retention-days: 1
@@ -126,7 +134,8 @@ jobs:
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"
OWNER="${GITHUB_REPOSITORY_OWNER,,}"
if [[ "${GITHUB_REF}" == refs/tags/* ]]; then
VERSION="${GITHUB_REF_NAME}"
elif [[ -n "$INPUT_VERSION" ]]; then
@@ -138,13 +147,14 @@ jobs:
exit 1
fi
echo "IMAGE=ghcr.io/${OWNER}/openflare" >> "$GITHUB_ENV"
echo "VERSION=$VERSION" >> "$GITHUB_ENV"
- name: Download digests
uses: actions/download-artifact@v4
with:
path: /tmp/server-digests
pattern: server-digests-*
path: /tmp/${{ env.IMAGE_NAME }}-digests
pattern: ${{ env.IMAGE_NAME }}-digests-*
merge-multiple: true
- name: Set up Docker Buildx
@@ -158,7 +168,7 @@ jobs:
password: ${{ secrets.GITHUB_TOKEN }}
- name: Create and push manifest list
working-directory: /tmp/server-digests
working-directory: /tmp/${{ env.IMAGE_NAME }}-digests
shell: bash
run: |
shopt -s nullglob
@@ -168,7 +178,7 @@ jobs:
done
if [ ${#references[@]} -eq 0 ]; then
echo "No digests found in /tmp/server-digests" >&2
echo "No digests found in /tmp/${{ env.IMAGE_NAME }}-digests" >&2
exit 1
fi
@@ -182,6 +192,18 @@ jobs:
-t "${IMAGE}:${VERSION}" \
-t "${IMAGE}:${FLOATING_TAG}" \
"${references[@]}"
env:
IMAGE: ${{ env.IMAGE }}
- name: Inspect image
run: docker buildx imagetools inspect "${IMAGE}:${VERSION}"
run: docker buildx imagetools inspect "${{ env.IMAGE }}:${{ env.VERSION }}"
- name: Trigger webhook
env:
WEBHOOK_URL: ${{ secrets.WEBHOOK_URL }}
run: |
if [ -n "$WEBHOOK_URL" ]; then
curl -fsSL "$WEBHOOK_URL"
else
echo "Webhook URL is not set, skipping."
fi
@@ -1,4 +1,4 @@
name: Docker image build (Agent)
name: Build Image (openflared)
on:
workflow_dispatch:
@@ -16,6 +16,10 @@ permissions:
attestations: write
id-token: write
env:
IMAGE_NAME: openflared
DOCKERFILE: docker/Dockerfile.flared
jobs:
build:
name: Build (${{ matrix.arch }})
@@ -46,7 +50,8 @@ jobs:
POINTED_TAG="$(git tag --points-at HEAD --list 'v*' | sort -V | tail -n1)"
INPUT_VERSION="${INPUT_VERSION//[[:space:]]/}"
echo "IMAGE=ghcr.io/${GITHUB_REPOSITORY,,}-agent" >> "$GITHUB_ENV"
OWNER="${GITHUB_REPOSITORY_OWNER,,}"
if [[ "${GITHUB_REF}" == refs/tags/* ]]; then
VERSION="${GITHUB_REF_NAME}"
elif [[ -n "$INPUT_VERSION" ]]; then
@@ -58,6 +63,7 @@ jobs:
exit 1
fi
echo "IMAGE=ghcr.io/${OWNER}/openflared" >> "$GITHUB_ENV"
echo "VERSION=$VERSION" >> "$GITHUB_ENV"
- name: Set up Docker Buildx
@@ -75,27 +81,27 @@ jobs:
uses: docker/build-push-action@v7
with:
context: .
file: ./openflare-agent/Dockerfile
file: ${{ env.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-agent-${{ matrix.arch }}
cache-to: type=gha,mode=max,ignore-error=true,timeout=20m,scope=docker-agent-${{ matrix.arch }}
cache-from: type=gha,scope=docker-${{ env.IMAGE_NAME }}-${{ matrix.arch }}
cache-to: type=gha,mode=max,ignore-error=true,timeout=20m,scope=docker-${{ env.IMAGE_NAME }}-${{ matrix.arch }}
- name: Export digest
shell: bash
run: |
mkdir -p /tmp/agent-digests
touch "/tmp/agent-digests/${DIGEST#sha256:}"
mkdir -p "/tmp/${{ env.IMAGE_NAME }}-digests"
touch "/tmp/${{ env.IMAGE_NAME }}-digests/${DIGEST#sha256:}"
env:
DIGEST: ${{ steps.build.outputs.digest }}
- name: Upload digest
uses: actions/upload-artifact@v4
with:
name: agent-digests-${{ matrix.arch }}
path: /tmp/agent-digests/*
name: ${{ env.IMAGE_NAME }}-digests-${{ matrix.arch }}
path: /tmp/${{ env.IMAGE_NAME }}-digests/*
if-no-files-found: error
retention-days: 1
@@ -126,7 +132,8 @@ jobs:
POINTED_TAG="$(git tag --points-at HEAD --list 'v*' | sort -V | tail -n1)"
INPUT_VERSION="${INPUT_VERSION//[[:space:]]/}"
echo "IMAGE=ghcr.io/${GITHUB_REPOSITORY,,}-agent" >> "$GITHUB_ENV"
OWNER="${GITHUB_REPOSITORY_OWNER,,}"
if [[ "${GITHUB_REF}" == refs/tags/* ]]; then
VERSION="${GITHUB_REF_NAME}"
elif [[ -n "$INPUT_VERSION" ]]; then
@@ -138,13 +145,14 @@ jobs:
exit 1
fi
echo "IMAGE=ghcr.io/${OWNER}/openflared" >> "$GITHUB_ENV"
echo "VERSION=$VERSION" >> "$GITHUB_ENV"
- name: Download digests
uses: actions/download-artifact@v4
with:
path: /tmp/agent-digests
pattern: agent-digests-*
path: /tmp/${{ env.IMAGE_NAME }}-digests
pattern: ${{ env.IMAGE_NAME }}-digests-*
merge-multiple: true
- name: Set up Docker Buildx
@@ -158,7 +166,7 @@ jobs:
password: ${{ secrets.GITHUB_TOKEN }}
- name: Create and push manifest list
working-directory: /tmp/agent-digests
working-directory: /tmp/${{ env.IMAGE_NAME }}-digests
shell: bash
run: |
shopt -s nullglob
@@ -168,7 +176,7 @@ jobs:
done
if [ ${#references[@]} -eq 0 ]; then
echo "No digests found in /tmp/agent-digests" >&2
echo "No digests found in /tmp/${{ env.IMAGE_NAME }}-digests" >&2
exit 1
fi
@@ -182,6 +190,8 @@ jobs:
-t "${IMAGE}:${VERSION}" \
-t "${IMAGE}:${FLOATING_TAG}" \
"${references[@]}"
env:
IMAGE: ${{ env.IMAGE }}
- name: Inspect image
run: docker buildx imagetools inspect "${IMAGE}:${VERSION}"
run: docker buildx imagetools inspect "${{ env.IMAGE }}:${{ env.VERSION }}"
+411
View File
@@ -0,0 +1,411 @@
name: Build Release
on:
push:
tags: ["v*"]
workflow_dispatch:
inputs:
version:
description: "Release version/tag to build, for example v1.0.0-beta"
required: true
type: string
env:
APP_NAME: openflare-server
GO_MAIN: ./main.go
GO_BUILD_TAGS: embed_frontend
GO_LDFLAGS: -s -w
NODE_VERSION: "22"
PNPM_VERSION: "10.10.0"
FRONTEND_DIR: frontend
FRONTEND_BUILD_COMMAND: pnpm build:embed
FRONTEND_OUT_DIR: frontend/out
EMBED_DIST_DIR: internal/router/root/dist
EXTRA_FILES: |
LICENSE
README.md
README_zh.md
config.example.yaml
DEPLOYMENT_zh.md
permissions:
contents: write
jobs:
prepare-message:
runs-on: ubuntu-latest
outputs:
commit_msg: ${{ steps.trans.outputs.commit_msg }}
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.ref }}
fetch-depth: 0
- name: Prepare Commit Message
id: trans
shell: bash
run: |
msg=$(git log -1 --pretty=%B)
pip install deep-translator > /dev/null 2>&1 || true
export COMMIT_MSG="$msg"
echo "commit_msg<<EOF" >> "$GITHUB_OUTPUT"
if [ -f "scripts/translate_commit.py" ]; then
python3 scripts/translate_commit.py >> "$GITHUB_OUTPUT"
else
echo "Translation script not found, using raw message"
echo "$msg" >> "$GITHUB_OUTPUT"
fi
echo "EOF" >> "$GITHUB_OUTPUT"
create-release:
name: Create Release
needs: prepare-message
runs-on: ubuntu-latest
outputs:
version: ${{ steps.metadata.outputs.version }}
version_without_v: ${{ steps.metadata.outputs.version_without_v }}
build_date: ${{ steps.metadata.outputs.build_date }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: true
- name: Set release metadata
id: metadata
shell: bash
env:
INPUT_VERSION: ${{ github.event.inputs.version }}
run: |
set -euo pipefail
input_version="${INPUT_VERSION//[[:space:]]/}"
if [[ "$GITHUB_REF" == refs/tags/* ]]; then
version="$GITHUB_REF_NAME"
elif [[ -n "$input_version" ]]; then
version="$input_version"
else
echo "workflow_dispatch requires a version input" >&2
exit 1
fi
{
echo "version=$version"
echo "version_without_v=${version#v}"
echo "build_date=$(date -u +'%Y-%m-%dT%H:%M:%SZ')"
} >> "$GITHUB_OUTPUT"
- name: Create release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ steps.metadata.outputs.version }}
name: ${{ steps.metadata.outputs.version }}
body: ${{ needs.prepare-message.outputs.commit_msg }}
prerelease: ${{ contains(steps.metadata.outputs.version, 'alpha') || contains(steps.metadata.outputs.version, 'beta') || contains(steps.metadata.outputs.version, 'rc') }}
build-frontend:
name: Build Embedded Frontend
runs-on: ubuntu-latest
needs: create-release
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
run_install: false
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: pnpm
cache-dependency-path: ${{ env.FRONTEND_DIR }}/pnpm-lock.yaml
- name: Install frontend dependencies
working-directory: ${{ env.FRONTEND_DIR }}
run: pnpm install --frozen-lockfile
- name: Build frontend
env:
NEXT_PUBLIC_APP_VERSION: ${{ needs.create-release.outputs.version }}
NEXT_PUBLIC_APP_BUILD_DATE: ${{ needs.create-release.outputs.build_date }}
run: ${{ env.FRONTEND_BUILD_COMMAND }}
working-directory: ${{ env.FRONTEND_DIR }}
- name: Prepare embed directory
shell: bash
run: |
set -euo pipefail
rm -rf "$EMBED_DIST_DIR"
mkdir -p "$(dirname "$EMBED_DIST_DIR")"
cp -R "$FRONTEND_OUT_DIR" "$EMBED_DIST_DIR"
- name: Upload embedded frontend
uses: actions/upload-artifact@v4
with:
name: embedded-frontend
path: ${{ env.EMBED_DIST_DIR }}
if-no-files-found: error
retention-days: 1
build-binaries:
name: Build ${{ matrix.goos }}/${{ matrix.goarch }}
runs-on: ubuntu-latest
needs:
- create-release
- build-frontend
strategy:
fail-fast: false
matrix:
include:
- goos: linux
goarch: amd64
archive: tar.gz
- goos: linux
goarch: arm64
archive: tar.gz
- goos: darwin
goarch: amd64
archive: tar.gz
- goos: darwin
goarch: arm64
archive: tar.gz
- goos: windows
goarch: amd64
archive: zip
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Download embedded frontend
uses: actions/download-artifact@v4
with:
name: embedded-frontend
path: ${{ env.EMBED_DIST_DIR }}
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version-file: go.mod
cache: true
- name: Build binary
shell: bash
env:
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
CGO_ENABLED: "0"
VERSION: ${{ needs.create-release.outputs.version }}
BUILD_DATE: ${{ needs.create-release.outputs.build_date }}
run: |
set -euo pipefail
mkdir -p dist
binary_name="$APP_NAME"
if [[ "$GOOS" == "windows" ]]; then
binary_name="${binary_name}.exe"
fi
ldflags="$GO_LDFLAGS -X github.com/Rain-kl/Wavelet/internal/buildinfo.Version=$VERSION -X github.com/Rain-kl/Wavelet/internal/buildinfo.BuildTime=$BUILD_DATE"
build_args=(
-trimpath
-ldflags "$ldflags"
-o "dist/$binary_name"
)
if [[ -n "$GO_BUILD_TAGS" ]]; then
build_args=(-tags "$GO_BUILD_TAGS" "${build_args[@]}")
fi
go build "${build_args[@]}" "$GO_MAIN"
- name: Package artifact
id: package
shell: bash
env:
VERSION: ${{ needs.create-release.outputs.version }}
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
ARCHIVE_FORMAT: ${{ matrix.archive }}
run: |
set -euo pipefail
package_name="${APP_NAME}_${VERSION}_${GOOS}_${GOARCH}"
staging_dir="dist/$package_name"
mkdir -p "$staging_dir"
if [[ "$GOOS" == "windows" ]]; then
cp "dist/${APP_NAME}.exe" "$staging_dir/"
else
cp "dist/${APP_NAME}" "$staging_dir/"
fi
while IFS= read -r extra_file; do
[[ -z "$extra_file" ]] && continue
if [[ -e "$extra_file" ]]; then
cp -R "$extra_file" "$staging_dir/"
fi
done <<< "$EXTRA_FILES"
if [[ "$ARCHIVE_FORMAT" == "zip" ]]; then
(cd dist && zip -r "${package_name}.zip" "$package_name")
artifact="dist/${package_name}.zip"
else
tar -C dist -czf "dist/${package_name}.tar.gz" "$package_name"
artifact="dist/${package_name}.tar.gz"
fi
echo "artifact=$artifact" >> "$GITHUB_OUTPUT"
- name: Upload release artifact
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ needs.create-release.outputs.version }}
files: ${{ steps.package.outputs.artifact }}
build-agent-binaries:
name: Build agent ${{ matrix.goos }}/${{ matrix.goarch }}
runs-on: ubuntu-latest
needs: create-release
strategy:
fail-fast: false
matrix:
include:
- goos: linux
goarch: amd64
asset_name: openflare-agent-linux-amd64
- goos: linux
goarch: arm64
asset_name: openflare-agent-linux-arm64
- goos: darwin
goarch: amd64
asset_name: openflare-agent-darwin-amd64
- goos: darwin
goarch: arm64
asset_name: openflare-agent-darwin-arm64
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version-file: go.mod
- name: Build Agent
env:
CGO_ENABLED: 0
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
ASSET_NAME: ${{ matrix.asset_name }}
VERSION: ${{ needs.create-release.outputs.version }}
run: |
go mod download
mkdir -p dist
go build -trimpath -ldflags "-s -w -X 'github.com/Rain-kl/Wavelet/internal/apps/agent/config.Version=$VERSION'" -o "dist/$ASSET_NAME" ./cmd/agent/main.go
- name: Upload release artifact
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ needs.create-release.outputs.version }}
files: dist/${{ matrix.asset_name }}
build-relay-binaries:
name: Build relay ${{ matrix.goos }}/${{ matrix.goarch }}
runs-on: ubuntu-latest
needs: create-release
strategy:
fail-fast: false
matrix:
include:
- goos: linux
goarch: amd64
asset_name: openflare-relay-linux-amd64
- goos: linux
goarch: arm64
asset_name: openflare-relay-linux-arm64
- goos: darwin
goarch: amd64
asset_name: openflare-relay-darwin-amd64
- goos: darwin
goarch: arm64
asset_name: openflare-relay-darwin-arm64
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version-file: go.mod
- name: Build Relay
env:
CGO_ENABLED: 0
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
ASSET_NAME: ${{ matrix.asset_name }}
VERSION: ${{ needs.create-release.outputs.version }}
run: |
go mod download
mkdir -p dist
go build -trimpath -ldflags "-s -w -X 'github.com/Rain-kl/Wavelet/internal/apps/relay/config.Version=$VERSION'" -o "dist/$ASSET_NAME" ./cmd/relay/main.go
- name: Upload release artifact
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ needs.create-release.outputs.version }}
files: dist/${{ matrix.asset_name }}
build-flared-binaries:
name: Build flared ${{ matrix.goos }}/${{ matrix.goarch }}
runs-on: ubuntu-latest
needs: create-release
strategy:
fail-fast: false
matrix:
include:
- goos: linux
goarch: amd64
asset_name: openflared-linux-amd64
- goos: linux
goarch: arm64
asset_name: openflared-linux-arm64
- goos: darwin
goarch: amd64
asset_name: openflared-darwin-amd64
- goos: darwin
goarch: arm64
asset_name: openflared-darwin-arm64
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version-file: go.mod
- name: Build Flared
env:
CGO_ENABLED: 0
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
ASSET_NAME: ${{ matrix.asset_name }}
VERSION: ${{ needs.create-release.outputs.version }}
run: |
go mod download
mkdir -p dist
go build -trimpath -ldflags "-s -w -X 'github.com/Rain-kl/Wavelet/internal/apps/flared/config.Version=$VERSION'" -o "dist/$ASSET_NAME" ./cmd/flared/main.go
- name: Upload release artifact
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ needs.create-release.outputs.version }}
files: dist/${{ matrix.asset_name }}
@@ -1,4 +1,4 @@
name: Cleanup prerelease tags
name: Cleanup Prerelease
on:
workflow_dispatch:
+24
View File
@@ -0,0 +1,24 @@
name: Close Ticket
on:
schedule:
- cron: "0 0 * * *"
jobs:
close_ticket:
runs-on: ubuntu-24.04
permissions:
issues: write
pull-requests: write
steps:
- uses: actions/stale@v9
with:
days-before-issue-stale: 14
days-before-issue-close: 14
stale-issue-message: "此 issue 长期无活动,将在 14 天后自动关闭。如需继续讨论请回复"
close-issue-message: "此 issue 因长期无活动已自动关闭,如有需要请重新开启"
days-before-pr-stale: 14
days-before-pr-close: 14
stale-pr-message: "此 PR 长期无活动,将在 14 天后自动关闭。如需继续讨论请回复"
close-pr-message: "此 PR 因长期无活动已自动关闭,如有需要请重新开启"
+40
View File
@@ -0,0 +1,40 @@
name: "CodeQL"
on:
pull_request:
branches: [ "*" ]
push:
branches:
- "dev"
- "main"
jobs:
analyze:
name: Analyze (${{ matrix.language }})
runs-on: ubuntu-24.04
permissions:
security-events: write
packages: read
actions: read
contents: read
strategy:
fail-fast: false
matrix:
include:
- language: go
build-mode: autobuild
- language: javascript-typescript
build-mode: none
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
category: "/language:${{matrix.language}}"
+48
View File
@@ -0,0 +1,48 @@
name: "Copilot Setup Steps"
on:
workflow_dispatch:
push:
paths:
- .github/workflows/copilot-setup-steps.yml
pull_request:
paths:
- .github/workflows/copilot-setup-steps.yml
jobs:
copilot-setup-steps:
runs-on: ubuntu-24.04
permissions:
contents: read
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 JavaScript dependencies
working-directory: frontend
run: pnpm install
- 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
+35
View File
@@ -0,0 +1,35 @@
name: ESLint
on:
pull_request:
branches: [ "*" ]
push:
branches:
- "dev"
- "main"
jobs:
lint:
runs-on: ubuntu-24.04
steps:
- 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
- name: Run ESLint
working-directory: frontend
run: npx eslint . --max-warnings 0
-30
View File
@@ -1,30 +0,0 @@
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 frontend
corepack enable
pnpm install --frozen-lockfile
pnpm build:embed
- 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: frontend/out # The folder the action should deploy.
+32
View File
@@ -0,0 +1,32 @@
name: Check PR Template Checklist
on:
pull_request:
types: [opened, edited, synchronize]
jobs:
check-pr-template:
runs-on: ubuntu-24.04
steps:
- name: check all checklist items are checked
uses: actions/github-script@v7
with:
script: |
// get the pull request body
const prBody = context.payload.pull_request.body || '';
// regex to match all checklist items in the template
// matches lines like: - [ ] ... or - [x] ...
const checklistRegex = /^- \[( |x|X)\] .+$/gm;
const matches = prBody.match(checklistRegex) || [];
// check if any checklist item is not checked
const unchecked = matches.filter(line => line.startsWith('- [ ]'));
// if any unchecked, fail the workflow
if (unchecked.length > 0) {
core.setFailed(`PR checklist 未全部勾选,请确保所有 checklist 项都已勾选。未勾选项如下:\n${unchecked.join('\n')}`);
} else {
console.log('all checklist items are checked.');
}
-384
View File
@@ -1,384 +0,0 @@
name: Release
permissions:
contents: write
on:
workflow_dispatch:
inputs:
version:
description: "Release version/tag to publish, for example v1.0.0-beta"
required: false
type: string
push:
tags: ["v*"]
jobs:
prepare:
runs-on: ubuntu-latest
outputs:
should_run: ${{ steps.version.outputs.should_run }}
version: ${{ steps.version.outputs.version }}
is_prerelease: ${{ steps.version.outputs.is_prerelease }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Resolve version metadata
id: version
env:
INPUT_VERSION: ${{ github.event.inputs.version }}
run: |
SHOULD_RUN=true
POINTED_TAG="$(git tag --points-at HEAD --list 'v*' | sort -V | tail -n1)"
INPUT_VERSION="${INPUT_VERSION//[[:space:]]/}"
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"
elif [[ "${GITHUB_EVENT_NAME}" == "workflow_dispatch" ]]; then
echo "workflow_dispatch requires an explicit version input when HEAD is not tagged" >&2
exit 1
elif [[ "${GITHUB_REF}" == refs/heads/main ]]; then
echo "main branch release requires the current commit to be tagged" >&2
exit 1
else
echo "unable to resolve release version from the current ref" >&2
exit 1
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
build-frontend:
needs: prepare
if: needs.prepare.outputs.should_run == 'true'
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 10.10.0
run_install: false
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm
cache-dependency-path: frontend/pnpm-lock.yaml
- name: Build Frontend
working-directory: frontend
env:
CI: ""
NEXT_PUBLIC_APP_VERSION: ${{ needs.prepare.outputs.version }}
run: |
pnpm install --frozen-lockfile
pnpm build:embed
- name: Prepare embed directory
run: |
rm -rf internal/router/root/dist
cp -R frontend/out internal/router/root/dist
- name: Upload Frontend Artifact
uses: actions/upload-artifact@v4
with:
name: frontend-build
path: internal/router/root/dist
retention-days: 1
build-binaries:
needs:
- prepare
- build-frontend
if: needs.prepare.outputs.should_run == 'true'
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- goos: linux
goarch: amd64
asset_name: openflare-server-linux-amd64
- goos: linux
goarch: arm64
asset_name: openflare-server-linux-arm64
- goos: darwin
goarch: amd64
asset_name: openflare-server-darwin-amd64
- goos: darwin
goarch: arm64
asset_name: openflare-server-darwin-arm64
- goos: windows
goarch: amd64
asset_name: openflare-server-windows-amd64.exe
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Download Frontend Artifact
uses: actions/download-artifact@v4
with:
name: frontend-build
path: internal/router/root/dist
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: go.mod
cache-dependency-path: go.sum
- name: Build Server
env:
CGO_ENABLED: 0
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
ASSET_NAME: ${{ matrix.asset_name }}
VERSION: ${{ needs.prepare.outputs.version }}
run: |
go mod download
mkdir -p dist
go build -trimpath -tags embed_frontend \
-ldflags "-s -w -X 'github.com/Rain-kl/Wavelet/internal/buildinfo.Version=$VERSION'" \
-o "dist/$ASSET_NAME" ./main.go
- name: Upload Binary Artifact
uses: actions/upload-artifact@v4
with:
name: server-${{ matrix.goos }}-${{ matrix.goarch }}
path: dist/${{ matrix.asset_name }}
retention-days: 1
build-agent-binaries:
needs: prepare
if: needs.prepare.outputs.should_run == 'true'
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- goos: linux
goarch: amd64
asset_name: openflare-agent-linux-amd64
- goos: linux
goarch: arm64
asset_name: openflare-agent-linux-arm64
- goos: darwin
goarch: amd64
asset_name: openflare-agent-darwin-amd64
- goos: darwin
goarch: arm64
asset_name: openflare-agent-darwin-arm64
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: go.mod
- name: Build Agent
env:
CGO_ENABLED: 0
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
ASSET_NAME: ${{ matrix.asset_name }}
VERSION: ${{ needs.prepare.outputs.version }}
run: |
go mod download
mkdir -p dist
go build -trimpath -ldflags "-s -w -X 'github.com/Rain-kl/Wavelet/internal/apps/agent/config.Version=$VERSION'" -o "dist/$ASSET_NAME" ./cmd/agent/main.go
(cd dist && sha256sum "$ASSET_NAME" > "$ASSET_NAME.sha256")
- name: Upload Agent Artifact
uses: actions/upload-artifact@v4
with:
name: agent-${{ matrix.goos }}-${{ matrix.goarch }}
path: |
dist/${{ matrix.asset_name }}
dist/${{ matrix.asset_name }}.sha256
retention-days: 1
build-relay-binaries:
needs: prepare
if: needs.prepare.outputs.should_run == 'true'
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- goos: linux
goarch: amd64
asset_name: openflare-relay-linux-amd64
- goos: linux
goarch: arm64
asset_name: openflare-relay-linux-arm64
- goos: darwin
goarch: amd64
asset_name: openflare-relay-darwin-amd64
- goos: darwin
goarch: arm64
asset_name: openflare-relay-darwin-arm64
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: go.mod
- name: Build Relay
env:
CGO_ENABLED: 0
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
ASSET_NAME: ${{ matrix.asset_name }}
VERSION: ${{ needs.prepare.outputs.version }}
run: |
go mod download
mkdir -p dist
go build -trimpath -ldflags "-s -w -X 'github.com/Rain-kl/Wavelet/internal/apps/relay/config.Version=$VERSION'" -o "dist/$ASSET_NAME" ./cmd/relay/main.go
(cd dist && sha256sum "$ASSET_NAME" > "$ASSET_NAME.sha256")
- name: Upload Relay Artifact
uses: actions/upload-artifact@v4
with:
name: relay-${{ matrix.goos }}-${{ matrix.goarch }}
path: |
dist/${{ matrix.asset_name }}
dist/${{ matrix.asset_name }}.sha256
retention-days: 1
build-flared-binaries:
needs: prepare
if: needs.prepare.outputs.should_run == 'true'
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- goos: linux
goarch: amd64
asset_name: openflared-linux-amd64
- goos: linux
goarch: arm64
asset_name: openflared-linux-arm64
- goos: darwin
goarch: amd64
asset_name: openflared-darwin-amd64
- goos: darwin
goarch: arm64
asset_name: openflared-darwin-arm64
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: go.mod
- name: Build Flared
env:
CGO_ENABLED: 0
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
ASSET_NAME: ${{ matrix.asset_name }}
VERSION: ${{ needs.prepare.outputs.version }}
run: |
go mod download
mkdir -p dist
go build -trimpath -ldflags "-s -w -X 'github.com/Rain-kl/Wavelet/internal/apps/flared/config.Version=$VERSION'" -o "dist/$ASSET_NAME" ./cmd/flared/main.go
(cd dist && sha256sum "$ASSET_NAME" > "$ASSET_NAME.sha256")
- name: Upload Flared Artifact
uses: actions/upload-artifact@v4
with:
name: flared-${{ matrix.goos }}-${{ matrix.goarch }}
path: |
dist/${{ matrix.asset_name }}
dist/${{ matrix.asset_name }}.sha256
retention-days: 1
release:
needs:
- prepare
- build-binaries
- build-agent-binaries
- build-relay-binaries
- build-flared-binaries
if: needs.prepare.outputs.should_run == 'true'
runs-on: ubuntu-latest
steps:
- name: Download Server Artifacts
uses: actions/download-artifact@v4
with:
pattern: "server-*"
path: dist
merge-multiple: true
- name: Download Agent Artifacts
uses: actions/download-artifact@v4
with:
pattern: "agent-*"
path: dist
merge-multiple: true
- name: Download Relay Artifacts
uses: actions/download-artifact@v4
with:
pattern: "relay-*"
path: dist
merge-multiple: true
- name: Download Flared Artifacts
uses: actions/download-artifact@v4
with:
pattern: "flared-*"
path: dist
merge-multiple: true
- name: Release
uses: softprops/action-gh-release@v1
with:
tag_name: ${{ needs.prepare.outputs.version }}
name: ${{ needs.prepare.outputs.version }}
target_commitish: ${{ github.sha }}
files: dist/*
draft: false
prerelease: ${{ needs.prepare.outputs.is_prerelease == 'true' }}
body: |
查看完整更新日志: https://open-flare.pages.dev/changelog/
generate_release_notes: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}