diff --git a/.dockerignore b/.dockerignore index 8b1f9f0..9cd5d67 100644 --- a/.dockerignore +++ b/.dockerignore @@ -4,3 +4,6 @@ data .git .env *.md +docs +.github +*.log diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e78d69e..5593d60 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,11 +33,22 @@ jobs: - name: Audit production dependencies run: npm audit --omit=dev --audit-level=high - publish-docker: - runs-on: ubuntu-latest + publish-docker-arch: + name: Publish Docker Image (${{ matrix.arch }}) + runs-on: ${{ matrix.runner }} needs: test-and-build if: github.event_name == 'push' && !startsWith(github.ref, 'refs/tags/') - timeout-minutes: 30 + timeout-minutes: 45 + strategy: + fail-fast: false + matrix: + include: + - arch: amd64 + platform: linux/amd64 + runner: ubuntu-latest + - arch: arm64 + platform: linux/arm64 + runner: ubuntu-24.04-arm steps: - name: Checkout @@ -50,9 +61,6 @@ jobs: exit 1 fi - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 @@ -73,12 +81,80 @@ jobs: type=ref,event=tag type=sha,format=short - - name: Build and push multi-arch image + - name: Add architecture suffix to tags + id: arch-tags + shell: bash + run: | + set -euo pipefail + rm -f tags.txt + while IFS= read -r tag; do + [ -n "$tag" ] || continue + echo "${tag}-${{ matrix.arch }}" >> tags.txt + done <<< "${{ steps.meta.outputs.tags }}" + { + echo 'tags<> "$GITHUB_OUTPUT" + + - name: Build and push ${{ matrix.platform }} image uses: docker/build-push-action@v6 with: context: . file: docker/Dockerfile - platforms: linux/amd64,linux/arm64 + platforms: ${{ matrix.platform }} push: true - tags: ${{ steps.meta.outputs.tags }} + tags: ${{ steps.arch-tags.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha,scope=ci-${{ matrix.arch }} + cache-to: type=gha,mode=max,scope=ci-${{ matrix.arch }} + + publish-docker: + name: Publish Docker Manifest + runs-on: ubuntu-latest + needs: publish-docker-arch + if: github.event_name == 'push' && !startsWith(github.ref, 'refs/tags/') + timeout-minutes: 15 + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Ensure Docker Hub secrets are configured + run: | + if [ -z "${{ secrets.DOCKERHUB_USERNAME }}" ] || [ -z "${{ secrets.DOCKERHUB_TOKEN }}" ]; then + echo "Missing Docker Hub secrets: DOCKERHUB_USERNAME / DOCKERHUB_TOKEN" + exit 1 + fi + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Extract Docker metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: 1467078763/metapi + tags: | + type=raw,value=latest,enable={{is_default_branch}} + type=ref,event=branch + type=ref,event=tag + type=sha,format=short + + - name: Create multi-arch manifests + shell: bash + run: | + set -euo pipefail + while IFS= read -r tag; do + [ -n "$tag" ] || continue + docker buildx imagetools create \ + --tag "$tag" \ + "${tag}-amd64" \ + "${tag}-arm64" + done <<< "${{ steps.meta.outputs.tags }}" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 47c61d5..e0e6fe2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -151,12 +151,22 @@ jobs: generate_release_notes: true files: release-assets/* - publish-docker: - name: Publish Docker Images + publish-docker-arch: + name: Publish Docker Image (${{ matrix.arch }}) needs: build-packages - runs-on: ubuntu-latest - timeout-minutes: 30 + runs-on: ${{ matrix.runner }} + timeout-minutes: 45 if: startsWith(github.ref, 'refs/tags/') + strategy: + fail-fast: false + matrix: + include: + - arch: amd64 + platform: linux/amd64 + runner: ubuntu-latest + - arch: arm64 + platform: linux/arm64 + runner: ubuntu-24.04-arm steps: - name: Checkout @@ -169,9 +179,6 @@ jobs: exit 1 fi - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 @@ -199,12 +206,87 @@ jobs: type=ref,event=tag type=raw,value=latest - - name: Build and push multi-arch images + - name: Add architecture suffix to tags + id: arch-tags + shell: bash + run: | + set -euo pipefail + rm -f tags.txt + while IFS= read -r tag; do + [ -n "$tag" ] || continue + echo "${tag}-${{ matrix.arch }}" >> tags.txt + done <<< "${{ steps.meta.outputs.tags }}" + { + echo 'tags<> "$GITHUB_OUTPUT" + + - name: Build and push ${{ matrix.platform }} image uses: docker/build-push-action@v6 with: context: . file: docker/Dockerfile - platforms: linux/amd64,linux/arm64 + platforms: ${{ matrix.platform }} push: true - tags: ${{ steps.meta.outputs.tags }} + tags: ${{ steps.arch-tags.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha,scope=release-${{ matrix.arch }} + cache-to: type=gha,mode=max,scope=release-${{ matrix.arch }} + + publish-docker: + name: Publish Docker Manifests + needs: publish-docker-arch + runs-on: ubuntu-latest + timeout-minutes: 15 + if: startsWith(github.ref, 'refs/tags/') + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Ensure Docker Hub secrets are configured + run: | + if [ -z "${{ secrets.DOCKERHUB_USERNAME }}" ] || [ -z "${{ secrets.DOCKERHUB_TOKEN }}" ]; then + echo "Missing Docker Hub secrets: DOCKERHUB_USERNAME / DOCKERHUB_TOKEN" + exit 1 + fi + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Docker metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: | + 1467078763/metapi + ghcr.io/${{ github.repository }} + tags: | + type=ref,event=tag + type=raw,value=latest + + - name: Create multi-arch manifests + shell: bash + run: | + set -euo pipefail + while IFS= read -r tag; do + [ -n "$tag" ] || continue + docker buildx imagetools create \ + --tag "$tag" \ + "${tag}-amd64" \ + "${tag}-arm64" + done <<< "${{ steps.meta.outputs.tags }}" diff --git a/docker/Dockerfile b/docker/Dockerfile index 0498498..3a852c1 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,15 +1,16 @@ -FROM node:20-alpine AS builder +# syntax=docker/dockerfile:1.7 +FROM node:20-bookworm-slim AS builder WORKDIR /app COPY package.json package-lock.json ./ -RUN npm ci +RUN --mount=type=cache,target=/root/.npm npm ci --no-audit --no-fund COPY . . RUN npm run build -RUN npm prune --omit=dev +RUN --mount=type=cache,target=/root/.npm npm prune --omit=dev --no-audit --no-fund -FROM node:20-alpine +FROM node:20-bookworm-slim WORKDIR /app diff --git a/docs/getting-started.md b/docs/getting-started.md index 2855f3b..e87bf87 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -106,20 +106,41 @@ npm run dev 完成部署后,按以下顺序配置: +> [!TIP] 从 ALL-API-Hub 迁移(可选) +> 如果你使用过 ALL-API-Hub,Metapi 兼容其导出的备份设置,可直接导入,无需手动逐项配置。 +> +> ![ALL-API-Hub备份导入](./screenshots/allapi-hub-backup.png) + ### 步骤 1:添加站点 进入 **站点管理**,添加你使用的上游中转站: -- 填写站点名称和 URL -- 选择平台类型(New API / One API / OneHub / DoneHub / Veloera / AnyRouter / Sub2API) +- 填写站点名称(自己想怎么取就怎么取)和 URL +- 选择平台类型(New API / One API / OneHub / DoneHub / Veloera / AnyRouter / Sub2API),通常可自动检测 - 填写站点的管理员 API Key(可选,部分功能需要) +![站点管理](./screenshots/site-management.png) + ### 步骤 2:添加账号 +首先前往你想添加的公益站,进入下图界面: + +![账号管理](./screenshots/account-management.png) + 进入 **账号管理**,为每个站点添加已注册的账号: + + +![账号余额](./screenshots/account-balance.png) + - 填入用户名和访问凭证 + + ![账号凭证](./screenshots/account-credentials.png) + - 系统会自动登录并获取余额信息 + +![账号余额](./screenshots/account-balance.png) + - 启用自动签到(如站点支持) ### 步骤 3:同步 Token @@ -127,7 +148,10 @@ npm run dev 进入 **Token 管理**: - 点击「同步」从上游账号拉取 API Key -- 或手动添加已有的 API Key + +- 或手动添加已有的 API Key,如下图所示。 + + ![Token管理](./screenshots/token-management.png) ### 步骤 4:检查路由 diff --git a/docs/screenshots/account-balance.png b/docs/screenshots/account-balance.png new file mode 100644 index 0000000..94718a9 Binary files /dev/null and b/docs/screenshots/account-balance.png differ diff --git a/docs/screenshots/account-credentials.png b/docs/screenshots/account-credentials.png new file mode 100644 index 0000000..3a229fb Binary files /dev/null and b/docs/screenshots/account-credentials.png differ diff --git a/docs/screenshots/account-management.png b/docs/screenshots/account-management.png new file mode 100644 index 0000000..b26f56f Binary files /dev/null and b/docs/screenshots/account-management.png differ diff --git a/docs/screenshots/allapi-hub-backup.png b/docs/screenshots/allapi-hub-backup.png new file mode 100644 index 0000000..14f80cf Binary files /dev/null and b/docs/screenshots/allapi-hub-backup.png differ diff --git a/docs/screenshots/site-management.png b/docs/screenshots/site-management.png new file mode 100644 index 0000000..32ea389 Binary files /dev/null and b/docs/screenshots/site-management.png differ diff --git a/docs/screenshots/token-management.png b/docs/screenshots/token-management.png new file mode 100644 index 0000000..e56b7c7 Binary files /dev/null and b/docs/screenshots/token-management.png differ