From 2357e6d45adc50a4d1386cbde2e77e66800da373 Mon Sep 17 00:00:00 2001 From: alboped Date: Tue, 28 Apr 2026 02:04:03 +0800 Subject: [PATCH] =?UTF-8?q?ci:=20=E5=A2=9E=E5=8A=A0=E6=9E=84=E5=BB=BA?= =?UTF-8?q?=E7=8E=AF=E5=A2=83ci=E8=84=9A=E6=9C=AC=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../workflows/reusable-prepare-workspace.yml | 162 ++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 .gitea/workflows/reusable-prepare-workspace.yml diff --git a/.gitea/workflows/reusable-prepare-workspace.yml b/.gitea/workflows/reusable-prepare-workspace.yml new file mode 100644 index 0000000..7e1e827 --- /dev/null +++ b/.gitea/workflows/reusable-prepare-workspace.yml @@ -0,0 +1,162 @@ +name: Reusable Prepare Workspace + +on: + workflow_call: + inputs: + repo_url: + description: "Git 仓库地址" + required: true + type: string + git_sha: + description: "目标提交 SHA" + required: true + type: string + node_major: + description: "Node 主版本(例如 22)" + required: false + type: string + default: "22" + node_version: + description: "Node 精确版本(例如 22.12.0,优先于 node_major)" + required: false + type: string + default: "" + yarn_version: + description: "Yarn 版本(例如 stable 或 1.22.22)" + required: false + type: string + default: "stable" + nodejs_mirror: + description: "Node 二进制镜像地址" + required: false + type: string + default: "https://npmmirror.com/mirrors/node" + npm_registry: + description: "NPM 镜像地址" + required: false + type: string + default: "https://registry.npmmirror.com" + node_install_root: + description: "Node 安装缓存目录" + required: false + type: string + default: "$HOME/.local/node-ci" + run_commands: + description: "准备完成后执行的额外命令(多行 shell)" + required: false + type: string + default: "" + +jobs: + prepare: + runs-on: ubuntu-latest + env: + REPO_URL: ${{ inputs.repo_url }} + GIT_SHA: ${{ inputs.git_sha }} + NODE_MAJOR: ${{ inputs.node_major }} + NODE_VERSION: ${{ inputs.node_version }} + YARN_VERSION: ${{ inputs.yarn_version }} + NODEJS_MIRROR: ${{ inputs.nodejs_mirror }} + NPM_REGISTRY: ${{ inputs.npm_registry }} + NODE_INSTALL_ROOT: ${{ inputs.node_install_root }} + RUN_COMMANDS: ${{ inputs.run_commands }} + steps: + - name: Prepare workspace (checkout + node/yarn) + run: | + set -euo pipefail + + resolve_node_version() { + if [ -n "${NODE_VERSION}" ]; then + echo "${NODE_VERSION#v}" + return + fi + + local resolved + resolved="$(curl -fsSL "${NODEJS_MIRROR}/index.tab" | awk -F'\t' -v major="${NODE_MAJOR}" ' + NR > 1 && $1 ~ ("^v" major "\\.") { print substr($1, 2); exit } + ')" + if [ -z "${resolved}" ]; then + echo "failed to resolve latest Node ${NODE_MAJOR}.x from ${NODEJS_MIRROR}" + exit 1 + fi + echo "${resolved}" + } + + detect_arch() { + case "$(uname -m)" in + x86_64) echo "x64" ;; + aarch64 | arm64) echo "arm64" ;; + *) + echo "unsupported architecture: $(uname -m)" + exit 1 + ;; + esac + } + + install_node() { + local target_version="$1" + local arch name url tarball install_dir bindir + arch="$(detect_arch)" + name="node-v${target_version}-linux-${arch}" + url="${NODEJS_MIRROR}/v${target_version}/${name}.tar.xz" + tarball="/tmp/${name}.tar.xz" + install_dir="${NODE_INSTALL_ROOT}/${name}" + bindir="${install_dir}/bin" + + if [ ! -x "${bindir}/node" ]; then + mkdir -p "${NODE_INSTALL_ROOT}" + curl -fsSL "${url}" -o "${tarball}" + tar -xJf "${tarball}" -C "${NODE_INSTALL_ROOT}" + rm -f "${tarball}" + fi + + export PATH="${bindir}:${PATH}" + } + + ensure_node() { + local target_version node_version + target_version="$(resolve_node_version)" + + if command -v node >/dev/null 2>&1; then + node_version="$(node -v | sed 's/^v//')" + if [ "${node_version}" = "${target_version}" ]; then + return + fi + fi + + install_node "${target_version}" + + node_version="$(node -v | sed 's/^v//')" + if [ "${node_version}" != "${target_version}" ]; then + echo "failed to switch to Node ${target_version}, current=${node_version}" + exit 1 + fi + } + + if [ ! -d .git ]; then + git clone "${REPO_URL}" . + fi + + git fetch --all --tags --prune + git checkout -f "${GIT_SHA}" + + ensure_node + + npm config set registry "${NPM_REGISTRY}" >/dev/null 2>&1 || true + + if ! command -v yarn >/dev/null 2>&1; then + corepack enable + export COREPACK_NPM_REGISTRY="${NPM_REGISTRY}" + corepack prepare "yarn@${YARN_VERSION}" --activate + fi + + echo "Node: $(node -v)" + echo "Yarn: $(yarn -v)" + + - name: Run extra commands + if: ${{ inputs.run_commands != '' }} + run: | + set -euo pipefail + printf '%s\n' "${RUN_COMMANDS}" > /tmp/reusable-prepare-run.sh + chmod +x /tmp/reusable-prepare-run.sh + /tmp/reusable-prepare-run.sh