Files
workflow/ci/web-spa-deploy.yml

159 lines
6.0 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 公共可复用工作流workflow_call。调用方传入node_version、yarn_version、project_dir。
# 部署主机/用户/父路径、SSH 私钥从「调用方」仓库的 vars / secrets 读取(同仓 uses: ./... 时即本仓库配置)。
#
# 调用方 ci.yml 示例:
# jobs:
# build:
# uses: ./.gitea/workflows/node-spa-tar-deploy.reusable.yml@main
# with:
# node_version: "22.14.0"
# yarn_version: "1.22.22"
# project_dir: "chat-one-web"
# secrets: inherit
#
# 调用方「工作流 → 变量」DEPLOY_PATH、DEPLOY_HOST、DEPLOY_USER
# 调用方「工作流 → 密钥」SSH_PRIVATE_KEY
# 远端发布目录 = ${DEPLOY_PATH}/${project_dir}
name: Reusable Node SPA + tar deploy
on:
workflow_call:
inputs:
node_version:
description: "Node 完整版本号(如 22.14.0npmmirror linux-x64"
required: true
type: string
yarn_version:
description: "Yarn 1 版本号(如 1.22.22"
required: true
type: string
project_dir:
description: "站点子目录(相对 DEPLOY_PATH如 chat-one-web"
required: true
type: string
jobs:
build:
runs-on: ubuntu-latest
env:
DEPLOY_PATH: ${{ vars.DEPLOY_PATH }}
DEPLOY_HOST: ${{ vars.DEPLOY_HOST }}
DEPLOY_USER: ${{ vars.DEPLOY_USER }}
steps:
- name: Checkout
env:
TOKEN: ${{ github.token }}
run: |
set -e
export GIT_TERMINAL_PROMPT=0
if ! command -v git >/dev/null 2>&1; then
export DEBIAN_FRONTEND=noninteractive
shopt -s nullglob
for f in /etc/apt/sources.list /etc/apt/sources.list.d/debian.sources /etc/apt/sources.list.d/*.sources /etc/apt/sources.list.d/*.list; do
[ -f "$f" ] || continue
sed -i \
-e 's/deb.debian.org/mirrors.aliyun.com/g' \
-e 's/security.debian.org/mirrors.aliyun.com/g' \
"$f"
done
apt-get -o Acquire::http::Timeout=30 -o Acquire::https::Timeout=30 -o Acquire::Retries=2 update
apt-get install -y --no-install-recommends git
fi
SERVER="${{ github.server_url }}"
SERVER="${SERVER%/}"
REPO="${{ github.repository }}"
ORIGIN="${SERVER/https:\/\//https:\/\/oauth2:${TOKEN}@}"
ORIGIN="${ORIGIN/http:\/\//http:\/\/oauth2:${TOKEN}@}/${REPO}.git"
git init
git remote add origin "$ORIGIN"
git fetch --depth 1 origin "${{ github.sha }}"
git checkout -f "${{ github.sha }}"
- name: Install Node ${{ inputs.node_version }}
run: |
set -euo pipefail
NODE_VER="${{ inputs.node_version }}"
WANT="${NODE_VER#v}"
HAVE=""
if command -v node >/dev/null 2>&1; then
HAVE="$(node -v | sed 's/^v//')"
fi
if [ -n "$HAVE" ] && [ "$HAVE" = "$WANT" ]; then
echo "Node 已是 ${WANT}node -v: v${HAVE}),跳过下载安装"
node -v
exit 0
fi
ARCH="linux-x64"
NAME="node-v${WANT}-${ARCH}"
URL="https://npmmirror.com/mirrors/node/v${WANT}/${NAME}.tar.xz"
curl -fsSL "$URL" -o /tmp/node.tar.xz
mkdir -p /opt/node-ci
tar -xJf /tmp/node.tar.xz -C /opt/node-ci
BINDIR="/opt/node-ci/${NAME}/bin"
if [ -x "$BINDIR/node" ]; then
[ -n "${GITHUB_PATH:-}" ] && echo "$BINDIR" >> "$GITHUB_PATH"
[ -n "${GITHUB_ENV:-}" ] && echo "PATH=$BINDIR:$PATH" >> "$GITHUB_ENV"
export PATH="$BINDIR:$PATH"
node -v
else
echo "Install Node failed: $BINDIR/node missing" >&2
exit 1
fi
- name: Setup Yarn
run: |
corepack enable
corepack prepare yarn@${{ inputs.yarn_version }} --activate
echo "node -v: $(node -v); yarn -v: $(yarn -v)"
- name: Install
run: yarn install --frozen-lockfile
- name: Prettier check
run: yarn format:check
- name: ESLint
run: yarn lint
- name: Build
run: yarn build
- name: Install OpenSSH client
if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master')
run: |
set -e
export DEBIAN_FRONTEND=noninteractive
shopt -s nullglob
for f in /etc/apt/sources.list /etc/apt/sources.list.d/debian.sources /etc/apt/sources.list.d/*.sources /etc/apt/sources.list.d/*.list; do
[ -f "$f" ] || continue
sed -i \
-e 's/deb.debian.org/mirrors.aliyun.com/g' \
-e 's/security.debian.org/mirrors.aliyun.com/g' \
"$f"
done
apt-get -o Acquire::http::Timeout=30 -o Acquire::https::Timeout=30 -o Acquire::Retries=2 update
apt-get install -y --no-install-recommends openssh-client
- name: Deploy to Nginx (tar over SSH)
if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master')
env:
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
PROJECT_DIR: ${{ inputs.project_dir }}
run: |
set -e
: "${DEPLOY_PATH:?DEPLOY_PATH (vars) is not set}"
: "${DEPLOY_HOST:?DEPLOY_HOST (vars) is not set}"
: "${DEPLOY_USER:?DEPLOY_USER (vars) is not set}"
: "${PROJECT_DIR:?project_dir is not set}"
REMOTE_ROOT="${DEPLOY_PATH}/${PROJECT_DIR}"
mkdir -p ~/.ssh
chmod 700 ~/.ssh
echo "$SSH_PRIVATE_KEY" | tr -d '\r' > ~/.ssh/id_deploy
chmod 600 ~/.ssh/id_deploy
ssh-keyscan -H "$DEPLOY_HOST" >> ~/.ssh/known_hosts
SSH=(ssh -i ~/.ssh/id_deploy -o IdentitiesOnly=yes -o StrictHostKeyChecking=yes)
"${SSH[@]}" "${DEPLOY_USER}@${DEPLOY_HOST}" "mkdir -p '${REMOTE_ROOT}' && find '${REMOTE_ROOT}' -mindepth 1 -delete"
tar czf - -C dist . | "${SSH[@]}" "${DEPLOY_USER}@${DEPLOY_HOST}" "tar xzf - -C '${REMOTE_ROOT}'"