This commit is contained in:
严浩
2024-09-30 14:13:23 +08:00
committed by mini2024
commit b821c98ddd
18 changed files with 1043 additions and 0 deletions

1
.github/_files/.npmrc vendored Normal file
View File

@ -0,0 +1 @@
use-node-version=22.14.0 # https://pnpm.io/zh/npmrc#use-node-version

6
.github/_files/package.json vendored Normal file
View File

@ -0,0 +1,6 @@
{
"packageManager": "pnpm@10.6.5",
"dependencies": {
"bun": "^1.2.5"
}
}

125
.github/_files/pnpm-lock.yaml generated vendored Normal file
View File

@ -0,0 +1,125 @@
lockfileVersion: '9.0'
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
importers:
.:
dependencies:
bun:
specifier: ^1.2.5
version: 1.2.5
packages:
'@oven/bun-darwin-aarch64@1.2.5':
resolution: {integrity: sha512-ggZfdpgUJ/OiWrfcfTgHeSTHcec5HAjkGrZHL9FJ/R60sydRKPYHgAgexdIoJAGfsCVAL+x7y8NSTRIAX8J4Ng==}
cpu: [arm64]
os: [darwin]
'@oven/bun-darwin-x64-baseline@1.2.5':
resolution: {integrity: sha512-3W1RO3/D6Z1S79J47F/DLzmK+dgkYq5hS1ShOCSBAYTTA2b1ZuymaN8avGzSb9ed5W0QfxtyeAksfEY2xUBOqA==}
cpu: [x64]
os: [darwin]
'@oven/bun-darwin-x64@1.2.5':
resolution: {integrity: sha512-4zqyQLJB33s99KcTxH6yQqH5EYBmF1qofQTtLsToIFbIZN1NqSp/aegYiGmxO5Kj/BuWsy8Wf8MS6vX2O0o2Lw==}
cpu: [x64]
os: [darwin]
'@oven/bun-linux-aarch64-musl@1.2.5':
resolution: {integrity: sha512-URlISBOE2HQi8qdru691OYywJRwChxMfXFbk26tCgdZ01LgGAKsIjAYylefuSsPuA697imDN3Pel3D7rveusmw==}
cpu: [aarch64]
os: [linux]
'@oven/bun-linux-aarch64@1.2.5':
resolution: {integrity: sha512-NQFtAVyQyJhLYrhFVxKdh6cqrDNc60pBnBGLQSO8PU+oyFyiJ3e3gGXjLzMbxd6cJxNIK5FZ0JIq96WljKAhlg==}
cpu: [arm64]
os: [linux]
'@oven/bun-linux-x64-baseline@1.2.5':
resolution: {integrity: sha512-fCm/qp7e3VYlaoRs6NIEsKubPqyxjzLv8/qZkxeLLOlPd7CS8L26UY4KPOSjA+wrhPT+Nxsyvl/EEJq2R/iauA==}
cpu: [x64]
os: [linux]
'@oven/bun-linux-x64-musl-baseline@1.2.5':
resolution: {integrity: sha512-H7tuJz7mZvOTPo4yLbIXIxkiDGWSGd2DbwGl4zNol/FURqGsKQVqpomv86yl9KCXsUUOm5FX2i5Ed+ro8N//Cg==}
cpu: [x64]
os: [linux]
'@oven/bun-linux-x64-musl@1.2.5':
resolution: {integrity: sha512-DuU2kQnY48g9tNWjFrZqyG+U2emCBwlhOPxbuY/TMVVNSTMAcQbE/bb3s2pZdhZH5ssjc5SH/ZyWU1TePcYB2A==}
cpu: [x64]
os: [linux]
'@oven/bun-linux-x64@1.2.5':
resolution: {integrity: sha512-pa3kQ4cXNV0jk5aM8+Hdmxr+b4QoPVgeAIA454SN5l3hMGfNsHjczKpsz0ksInZ8506iMMTCPEBXpyQJcSme+Q==}
cpu: [x64]
os: [linux]
'@oven/bun-windows-x64-baseline@1.2.5':
resolution: {integrity: sha512-j5FxI8FeKfWI6rEXA+1O3ASBMTp5CFcZ7MR+/aCpiBKrDse32wLaZMVGnvqQqs4y0YHUvR8b7eXHHTboezjL1w==}
cpu: [x64]
os: [win32]
'@oven/bun-windows-x64@1.2.5':
resolution: {integrity: sha512-oNDdPmzsCyvCATiYgkKWgxOeEx2F7m/i2MGUba+YJAeVXJsJg9iPJrLVBtETvKoSAgkXViwoUEw2U25jRYsp4g==}
cpu: [x64]
os: [win32]
bun@1.2.5:
resolution: {integrity: sha512-fbQLt+DPiGUrPKdmsHRRT7cQAlfjdxPVFvLZrsUPmKiTdv+pU50ypdx9yRJluknSbyaZchFVV7Lx2KXikXKX2Q==}
cpu: [arm64, x64, aarch64]
os: [darwin, linux, win32]
hasBin: true
snapshots:
'@oven/bun-darwin-aarch64@1.2.5':
optional: true
'@oven/bun-darwin-x64-baseline@1.2.5':
optional: true
'@oven/bun-darwin-x64@1.2.5':
optional: true
'@oven/bun-linux-aarch64-musl@1.2.5':
optional: true
'@oven/bun-linux-aarch64@1.2.5':
optional: true
'@oven/bun-linux-x64-baseline@1.2.5':
optional: true
'@oven/bun-linux-x64-musl-baseline@1.2.5':
optional: true
'@oven/bun-linux-x64-musl@1.2.5':
optional: true
'@oven/bun-linux-x64@1.2.5':
optional: true
'@oven/bun-windows-x64-baseline@1.2.5':
optional: true
'@oven/bun-windows-x64@1.2.5':
optional: true
bun@1.2.5:
optionalDependencies:
'@oven/bun-darwin-aarch64': 1.2.5
'@oven/bun-darwin-x64': 1.2.5
'@oven/bun-darwin-x64-baseline': 1.2.5
'@oven/bun-linux-aarch64': 1.2.5
'@oven/bun-linux-aarch64-musl': 1.2.5
'@oven/bun-linux-x64': 1.2.5
'@oven/bun-linux-x64-baseline': 1.2.5
'@oven/bun-linux-x64-musl': 1.2.5
'@oven/bun-linux-x64-musl-baseline': 1.2.5
'@oven/bun-windows-x64': 1.2.5
'@oven/bun-windows-x64-baseline': 1.2.5

View File

@ -0,0 +1,26 @@
on:
pull_request:
paths:
- "deploy-dist-to-surge/**"
- ".github/workflows/deploy-dist-to-surge-test.yaml"
push:
paths:
- "deploy-dist-to-surge/**"
- ".github/workflows/deploy-dist-to-surge-test.yaml"
env:
TZ: Asia/Shanghai
jobs:
job:
runs-on: ubuntu-latest
steps:
- name: 准备部署文件
run: |
mkdir dist
html="<!DOCTYPE html><html><body><h1>${{ github.event_name }}: ${{ github.sha }}</h1></body></html>"
echo $html > dist/index.html
- uses: yanhao98/composite-actions/deploy-dist-to-surge@main
id: surge_deploy
- name: Check Surge URL
run: |
echo "steps.surge_deploy.outputs.url: ${{ steps.surge_deploy.outputs.url }}"

View File

@ -0,0 +1,133 @@
# name: _打包推送镜像
on:
workflow_dispatch:
pull_request:
paths:
- 'docker-build-push/**'
- '.github/workflows/docker-build-push-test.yaml'
push:
paths:
- 'docker-build-push/**'
- '.github/workflows/docker-build-push-test.yaml'
env:
TZ: Asia/Shanghai
jobs:
build-and-push-ghcr:
runs-on: ubuntu-latest
env:
# https://github.com/docker/metadata-action/tree/v5/?tab=readme-ov-file#semver
# Event: push, Ref: refs/head/main, Tags: main
# Event: push tag, Ref: refs/tags/v1.2.3, Tags: 1.2.3, 1.2, 1, latest
# Event: push tag, Ref: refs/tags/v2.0.8-rc1, Tags: 2.0.8-rc1
metadata-action-tags: |
type=ref,event=branch
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
steps:
- name: 🔑 登录 GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: 🐳 构建并推送 Docker 镜像
uses: yanhao98/composite-actions/docker-build-push@main
with:
file: ./Dockerfile.test
platforms: linux/amd64,linux/arm64
push: true
load: false
meta_images: ghcr.io/${{ github.repository }}
meta_tags: ${{ env.metadata-action-tags }}
cache-from: type=gha,scope=${{ github.workflow }}
cache-to: type=gha,scope=${{ github.workflow }}
build-and-push-multi-registry:
runs-on: ubuntu-latest
steps:
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: yanhao98/composite-actions/docker-build-push@main
id: docker-build-push
with:
file: ./Dockerfile.test
platforms: linux/amd64,linux/arm64
push: true
load: false
meta_images: |
docker.io/${{ vars.DOCKERHUB_USERNAME }}/docker-example
ghcr.io/${{ github.repository }}
meta_tags: | # https://github.com/docker/metadata-action
type=raw,value=latest,enable=true
cache-gha:
runs-on: ubuntu-latest
steps:
- uses: yanhao98/composite-actions/docker-build-push@main
id: docker-build-push
with:
file: ./Dockerfile.test
platforms: linux/amd64
push: false
load: true
build-args: |
SHA=${{ github.sha }}
# #####
# scope: https://github.com/docker/build-push-action/issues/252#issuecomment-881050512
# cache-to: mode=max
# #####
cache-from: type=gha,scope=${{ github.workflow }}
cache-to: type=gha,scope=${{ github.workflow }}
- name: Check Docker image
run: |
set -x;
docker images;
docker run --rm ${{ steps.docker-build-push.outputs.imageid }} cat /root/sha.txt;
cache-local:
runs-on: ubuntu-latest
steps:
- name: 🗄️ 缓存Docker层
uses: actions/cache@v4
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-IMAGE_NAME-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-IMAGE_NAME-
- uses: yanhao98/composite-actions/docker-build-push@main
id: docker-build-push
with:
file: ./Dockerfile.test
platforms: linux/amd64
push: false
load: true
build-args: |
SHA=${{ github.sha }}
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache-new
# Temp fix: 如果要在一个 job 中多次使用 buildx 缓存才需要这个步骤。
# https://github.com/docker/build-push-action/issues/252
# https://github.com/moby/buildkit/issues/1896
- name: 🔄 更新缓存
run: |
rm -rf /tmp/.buildx-cache
mv /tmp/.buildx-cache-new /tmp/.buildx-cache
- name: Check Docker image
run: |
set -x;
docker images;
docker run --rm ${{ steps.docker-build-push.outputs.imageid }} cat /root/sha.txt;

View File

@ -0,0 +1,26 @@
on:
pull_request:
paths:
- "npm-build-fix-to-nexus/**"
- ".github/workflows/npm-build-fix-to-nexus-test.yaml"
push:
paths:
- "npm-build-fix-to-nexus/**"
- ".github/workflows/npm-build-fix-to-nexus-test.yaml"
env:
TZ: Asia/Shanghai
jobs:
upload_npm_fix_to_nexus:
runs-on: ubuntu-latest
steps:
- name: Prepare
run: |
mkdir npm-build-fix-to-nexus
- uses: yanhao98/composite-actions/npm-build-fix-to-nexus@main
with:
package_json_url: 'https://www.unpkg.com/fuck-your-code/package.json'
pack_workspace: './npm-build-fix-to-nexus'
build_command: 'whoami'
nexus_post_url: 'https://nexus.oo1.dev/service/rest/v1/components?repository=npm-hosted'
nexus_auth: ${{ secrets.NEXUS_AUTH }}

View File

@ -0,0 +1,133 @@
on:
pull_request:
paths:
- "setup-node-environment/**"
- ".github/workflows/setup-node-environment-test.yaml"
push:
paths:
- "setup-node-environment/**"
- ".github/workflows/setup-node-environment-test.yaml"
env:
TZ: Asia/Shanghai
package_json_content: |
{
"packageManager": "pnpm@10.6.5",
"dependencies": {
"bun": "^1.2.5"
}
}
concurrency:
group: ${{ github.event_name }}-${{ github.ref }}
cancel-in-progress: true
defaults:
run:
shell: bash
jobs:
generate_lock:
runs-on: ubuntu-latest
outputs:
lock_file_content: ${{ steps.generate_lock.outputs.lock_file_content }}
steps:
- uses: pnpm/action-setup@v4
with:
version: latest
standalone: true
- id: generate_lock
env:
CI: 'false'
run: |
set -x;
cat <<EOF > package.json
${{ env.package_json_content }}
EOF
pnpm config list
cat package.json
pnpm install --lockfile-only
echo "lock_file_content<<EOF" >> $GITHUB_OUTPUT
cat pnpm-lock.yaml >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
tests:
needs: generate_lock
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
checkout:
- true
- false
container:
- 'yanhao98/runner-images:pnpm'
- '' # gitea/runner-images:ubuntu-latest
npmrc_content:
- ''
-
use-node-version=22.14.0 # https://pnpm.io/zh/npmrc#use-node-version
lock_file:
- 'true'
- 'false'
cwd:
- ''
- 'test'
container: ${{ matrix.container }}
steps:
- uses: actions/checkout@main
if: matrix.checkout == 'true'
- name: 打印 matrix
run: |
echo "🤖---- 打印 matrix ----🤖"
echo "container: ${{ matrix.container }}"
echo "checkout: ${{ matrix.checkout }}"
echo "npmrc_content: ${{ matrix.npmrc_content }}"
echo "lock_file: ${{ matrix.lock_file }}"
echo "cwd: ${{ matrix.cwd }}"
echo "GITHUB_WORKSPACE: ${{ github.workspace }}"
- name: Create test directory
if: matrix.cwd != ''
run: |
mkdir -p ${{ matrix.cwd }}
pwd
- name: Create .npmrc
working-directory: ${{ matrix.cwd }}
if: matrix.npmrc_content != ''
run: |
set -x;
ls -l -R .
cat <<EOF > .npmrc
${{ matrix.npmrc_content }}
EOF
pwd
- name: Create package.json
working-directory: ${{ matrix.cwd }}
run: |
mkdir -p ${{ github.workspace }}/.git
cat <<EOF > package.json
${{ env.package_json_content }}
EOF
set -x;
ls -l -R .
cat package.json
pwd
- name: Create pnpm-lock.yaml
working-directory: ${{ matrix.cwd }}
if: matrix.lock_file == 'true'
run: |
mkdir -p ${{ github.workspace }}/.git
cat <<EOF > pnpm-lock.yaml
${{ needs.generate_lock.outputs.lock_file_content }}
EOF
set -x;
ls -l -R .
cat pnpm-lock.yaml
- uses: yanhao98/composite-actions/setup-node-environment@main
with:
package_json_cwd: ${{ matrix.cwd }}
# pnpm_standalone: true

View File

@ -0,0 +1,52 @@
name: Upload to Alist Example
on:
pull_request:
paths:
- "upload-to-alist/**"
- ".github/workflows/upload-to-alist-example-test.yaml"
push:
paths:
- "upload-to-alist/**"
- ".github/workflows/upload-to-alist-example-test.yaml"
env:
TZ: Asia/Shanghai
jobs:
upload:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: 📝 生成构建产物的文件名
id: filename
run: |
PROJECT_NAME=$(echo ${{ github.repository }} | cut -d'/' -f2)
DATE=$(date '+%Y%m%d_%H%M')
SHORT_HASH=$(git rev-parse --short HEAD)
FILENAME="${PROJECT_NAME}_${DATE}_${SHORT_HASH}.txt"
echo "📝 生成的文件名: $FILENAME"
echo "FILENAME=${FILENAME}" >> $GITHUB_OUTPUT
- name: Create test file
run: |
cat > ${{ steps.filename.outputs.FILENAME }} << EOF
# 测试文件
- 项目: ${{ github.repository }}
- 分支: ${{ github.ref_name }}
- 提交: $(git rev-parse HEAD)
- 时间: $(date '+%Y-%m-%d %H:%M:%S %Z')
- 触发事件: ${{ github.event_name }}
EOF
- uses: yanhao98/composite-actions/upload-to-alist@main
with:
alist_url: ${{ vars.ALIST_URL }}
alist_username: ${{ secrets.ALIST_USERNAME }}
alist_password: ${{ secrets.ALIST_PASSWORD }}
alist_target: ${{ vars.alist_target_base }}/github-actions/upload-to-alist/${{ steps.filename.outputs.FILENAME }}
file: ${{ steps.filename.outputs.FILENAME }}

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
node_modules

7
.releaserc.json Normal file
View File

@ -0,0 +1,7 @@
{
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/changelog"
]
}

12
Dockerfile.test Normal file
View File

@ -0,0 +1,12 @@
# syntax=docker/dockerfile:1.14-labs
FROM alpine:latest
ARG SHA=unspecified
ENV SHA=$SHA
COPY <<EOF /root/sha.txt
$SHA
EOF

1
README.md Normal file
View File

@ -0,0 +1 @@
- https://github.com/renovatebot/renovate/blob/81fc75630b0b43fb4b89a0b65c1086d487e65d2e/.github/actions/setup-node/action.yml

View File

@ -0,0 +1,22 @@
name: "Deploy dist to Surge"
description: "部署 dist 到 Surge"
outputs:
url:
description: "Preview URL"
value: ${{ steps.surge_deploy.outputs.url }}
runs:
using: "composite"
steps:
- name: 部署到 Surge
shell: bash
id: surge_deploy
# https://github.com/afc163/surge-preview
# https://github.com/Tencent/tdesign-vue-next/pull/1604#issuecomment-1236244550
# https://github.com/Tencent/tdesign-vue-next/blob/03036a19adccf4657d7792e3a61a6c6a7d902e3e/.github/workflows/preview-publish.yml
# https://github.com/Tencent/tdesign/blob/0c0c9b63897c05d10c58e1a1e36feda2cb99eca7/.github/workflows/preview.yml#L40
run: |
export DEPLOY_DOMAIN=https://${{ github.sha }}.surge.sh
cp dist/index.html dist/200.html
npx surge --project ./dist --domain $DEPLOY_DOMAIN --token d843de16b331c626f10771245c56ed93 # npx surge token
echo the preview URL is $DEPLOY_DOMAIN
echo "url=$DEPLOY_DOMAIN" >> $GITHUB_OUTPUT

View File

@ -0,0 +1,99 @@
# - https://docs.docker.com/build/ci/github-actions/push-multi-registries/
# - https://github.com/docker/build-push-action
name: "打包推送 Docker 镜像"
description: "打包 Docker 镜像并推送到 Docker Hub"
inputs:
file:
description: "Dockerfile 文件路径"
default: "./Dockerfile"
required: false
context:
description: "Docker 构建上下文路径"
default: "."
required: false
platforms:
description: "Docker 构建平台"
default: "linux/amd64,linux/arm64"
required: false
push:
description: "是否推送 Docker 镜像"
default: "false"
required: false
load:
description: "是否加载 Docker 镜像"
default: "false"
required: false
meta_images:
description: "docker/metadata-action 的 images 参数"
required: false
meta_tags:
description: "docker/metadata-action 的 tags 参数"
required: false
cache-from:
description: "docker/build-push-action 的 cache-from 参数"
required: false
cache-to:
description: "docker/build-push-action 的 cache-to 参数"
required: false
build-args:
description: "Docker 构建参数,格式如: KEY1=VALUE1,KEY2=VALUE2"
required: false
outputs:
imageid:
description: "Docker 镜像 ID"
value: ${{ steps.build.outputs.imageid }}
runs:
using: "composite"
steps:
- name: echo Start
shell: bash
run: echo -e "\n[$(date +'%Y-%m-%d %H:%M:%S')] 🤖🤖🤖 Start 🤖🤖🤖"
- id: check-git-folder
shell: bash
run: |
# 🤖 判断是否存在 .git 文件夹 🤖
[ -d .git ] && { echo "🤖 Found .git folder"; echo "git-folder-exists=true" >> $GITHUB_OUTPUT; } || { echo "🤖 No .git folder found"; echo "git-folder-exists=false" >> $GITHUB_OUTPUT; }
- uses: actions/checkout@main
if: steps.check-git-folder.outputs.git-folder-exists == 'false'
with:
filter: blob:none
show-progress: false
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
context: git
# flavor
images: ${{ inputs.meta_images }}
tags: ${{ inputs.meta_tags }}
# sep-tags: ','
# sep-labels: ','
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and push
id: build
uses: docker/build-push-action@v6
with:
file: ${{ inputs.file }}
context: ${{ inputs.context }}
platforms: ${{ inputs.platforms }}
push: ${{ inputs.push }}
load: ${{ inputs.load }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: ${{ inputs.cache-from }}
cache-to: ${{ inputs.cache-to }}
build-args: ${{ inputs.build-args }}
- name: echo End
shell: bash
run: echo -e "\n[$(date +'%Y-%m-%d %H:%M:%S')] 🤖🤖🤖 End 🤖🤖🤖"

View File

@ -0,0 +1,71 @@
name: '发布修复包到 Nexus'
description: '发布 npm 修复包到 Nexus'
inputs:
package_json_url:
description: 'package.json 文件的 URL'
required: true
pack_workspace:
description: '打包工作目录'
required: true
build_command:
description: '构建命令'
required: true
nexus_post_url:
description: 'Nexus URL'
required: true
nexus_auth:
description: 'Nexus 认证信息'
required: true
runs:
using: 'composite'
steps:
- name: 下载 package.json 文件
shell: bash
run: wget ${{ inputs.package_json_url }} -O /tmp/package.json
- name: 更新版本号
shell: bash
run: |
# 获取当前版本
VERSION=$(node -p "require('/tmp/package.json').version")
# 分解版本号
IFS='.' read -r major minor patch <<< "$VERSION"
# 增加patch版本
new_patch=$((patch + 1))
# 生成新版本号基础部分
NEW_VERSION="$major.$minor.$new_patch"
# 添加-fix后缀
NEW_VERSION="$NEW_VERSION-fix"
# 添加时间戳
TIMESTAMP=$(date -u +"%Y%m%d%H%M")
NEW_VERSION="$NEW_VERSION.$TIMESTAMP"
echo "Current version: $VERSION"
echo "New version: $NEW_VERSION"
# 更新package.json中的版本号
sed -i "s/\"version\": \".*\"/\"version\": \"$NEW_VERSION\"/" /tmp/package.json
- uses: yanhao98/composite-actions/setup-node-environment@main
- name: 构建项目
shell: bash
run: ${{ inputs.build_command }}
- name: 打包 tgz
id: pack_tgz
working-directory: ${{ inputs.pack_workspace }}
shell: bash
run: |
rm -rf *.tgz
cp /tmp/package.json .
tgz=$(npm pack)
echo "tgz=$tgz" >> $GITHUB_OUTPUT
- name: 上传到 Nexus
working-directory: ${{ inputs.pack_workspace }}
shell: bash
run: |
curl -i -X POST "${{ inputs.nexus_post_url }}" \
-H "Authorization: Basic ${{ inputs.nexus_auth }}" \
-F "npm.asset=@${{ steps.pack_tgz.outputs.tgz }}"

17
renovate.json Normal file
View File

@ -0,0 +1,17 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"https://git.1-h.cc/examples/renovate-example/raw/branch/main/default.json5",
":automergeAll"
],
"dependencyDashboard": false,
"packageRules": [
{ "minimumReleaseAge": "1 days", "matchPackageNames": [ "*" ] }
],
"ignoreDeps": [],
"ignorePaths": [
"package.json",
".npmrc",
"Dockerfile.test"
]
}

View File

@ -0,0 +1,224 @@
# 🔗 链接:
# 源文件: https://github.com/obytes/react-native-template-obytes/blob/master/.github/actions/setup-node-pnpm-install/action.yml
# 复合操作文档: https://docs.github.com/en/actions/creating-actions/creating-a-composite-action
# ✍️ 描述:
# 这是一个复合操作,意味着它可以在其他操作中使用。
# 它几乎用于所有工作流中,以设置环境并安装依赖项。
# 在此处更新包管理器或 Node 版本将反映在所有工作流中。
# 👀 使用示例:
# - name : 📦 设置 Node + PNPM + 安装依赖
# uses: ./.github/actions/setup-node-pnpm-install
name: '设置 Node 环境'
description: '设置 pnpm + Node.js + 安装依赖项'
inputs:
pnpm_standalone: # 是否将 pnpm 用作独立包 https://github.com/pnpm/action-setup?tab=readme-ov-file#standalone
description: '是否将 pnpm 用作独立包'
required: false
default: 'false'
package_json_cwd: # https://github.com/pnpm/action-setup/blob/d648c2dd069001a242c621c8306af467f150e99d/action.yml#L18C3-L18C20
description: 'package.json 的所在目录'
required: false
default: '.'
runs:
using: 'composite'
steps:
- id: check-git-folder
shell: bash
run: |
# 🤖----判断是否存在 .git 文件夹----🤖 #
[ -d ${{ github.workspace }}/.git ] && { echo "🤖 找到 .git 文件夹"; echo "git-folder-exists=true" >> $GITHUB_OUTPUT; } || { echo "🤖 未找到 .git 文件夹"; echo "git-folder-exists=false" >> $GITHUB_OUTPUT; }
- uses: actions/checkout@v4.2.2
if: steps.check-git-folder.outputs.git-folder-exists == 'false'
with:
# fetch-depth: 0 # 0 代表完整检出semantic-release 需要
filter: blob:none # 我们不需要所有 blob只需要完整的树
show-progress: false
- id: prepare
shell: bash
working-directory: ${{ inputs.package_json_cwd }}
run: |
# 🤖---- 准备环境变量 ----🤖 #
# --- 1. 包管理器 ---
echo "::group::📦 获取包管理器信息"
pkg_manager=$(node -p "try { require('./package.json').packageManager } catch(e) { '' }")
echo "从 package.json 获取的包管理器: $pkg_manager"
echo "::endgroup::"
# --- 2. 确定 PNPM 版本 ---
echo "::group::🔧 确定 PNPM 版本"
pnpm_version=""
# 如果 packageManager 为空、undefined 或 null则使用最新的 pnpm
if [ -z "$pkg_manager" ] || [ "$pkg_manager" == "undefined" ] || [ "$pkg_manager" == "null" ]; then
pnpm_version="latest"
echo "未指定或无效的 packageManager使用 pnpm 版本: latest"
else
# 如果指定了 pnpm 版本(例如 "pnpm@8.6.0"),则提取版本号
if [[ "$pkg_manager" == pnpm* ]]; then
pnpm_version=$(echo "$pkg_manager" | cut -d '@' -f 2)
echo "使用 package.json 中的 pnpm 版本: $pnpm_version"
else
echo "指定了非 pnpm 包管理器: $pkg_manager。将由 pnpm/action-setup 处理版本。"
# 让 pnpm/action-setup 根据 corepack 或其默认设置决定版本
pnpm_version="" # 如果不是 pnpm 或未正确指定,则显式设置为空
fi
fi
echo "::endgroup::"
# --- 3. 检查 PNPM 安装情况 ---
echo "::group::🔍 检查 PNPM 安装情况"
is_pnpm_installed="false"
pnpm_executable_path=""
installed_pnpm_version="无法获取" # 版本检查失败时的默认值
# 使用 command -v 检查 pnpm 是否在 PATH 中并且可执行
if command -v pnpm >/dev/null 2>&1; then
pnpm_executable_path=$(command -v pnpm)
echo "找到 PNPM 可执行文件于: $pnpm_executable_path"
# 尝试获取版本号,但不因失败而退出
if pnpm_version_output=$(pnpm --version 2>/dev/null); then
installed_pnpm_version="$pnpm_version_output"
is_pnpm_installed="true" # 确认 pnpm 可执行且能获取版本
echo "已安装的 PNPM 版本: $installed_pnpm_version"
else
# pnpm 命令存在但获取版本失败,可能安装不完整或有问题
is_pnpm_installed="true" # 标记为已安装,因为命令存在
echo "警告PNPM 命令存在,但无法获取版本号。可能安装不完整或存在问题。"
echo "将继续执行,后续步骤可能会重新安装或修复。"
fi
else
echo "PNPM 未在 PATH 中找到或不可执行。"
is_pnpm_installed="false"
fi
echo "::endgroup::"
# --- 4. 检查 PNPM Lock 文件 ---
echo "::group::📄 检查 PNPM Lock 文件"
has_pnpm_lock="false"
if [ -f pnpm-lock.yaml ]; then
has_pnpm_lock="true"
echo "找到 pnpm-lock.yaml。"
else
echo "未找到 pnpm-lock.yaml。"
fi
echo "::endgroup::"
# --- 5. 确定 Node.js 版本并清理 .npmrc ---
echo "::group::⚙️ 确定 Node.js 版本并清理 .npmrc"
node_version="lts/*" # 默认 Node 版本
if [ ! -f .npmrc ]; then
echo "未找到 .npmrc创建一个空文件。"
touch .npmrc
else
echo "找到 .npmrc 文件。"
fi
# 从 .npmrc 读取 use-node-version
node_version_in_npmrc=$(sed -n 's/.*use-node-version=\([0-9.]*\).*/\1/p' .npmrc)
if [ -n "$node_version_in_npmrc" ]; then
node_major_version_in_npmrc=$(echo "$node_version_in_npmrc" | cut -d. -f1)
if [ -n "$node_major_version_in_npmrc" ]; then
node_version="$node_major_version_in_npmrc"
echo ".npmrc 中指定的 Node 版本: $node_version_in_npmrc -> 使用主版本: $node_version"
else
echo "无法从 .npmrc ($node_version_in_npmrc) 提取主 Node 版本。使用默认值: $node_version"
fi
else
echo ".npmrc 中未找到 'use-node-version'。使用默认值: $node_version"
fi
# 清理 .npmrc删除 use-node-version 和 node-mirror 行
echo "正在清理 .npmrc..."
# 使用 -i.bak 以兼容不同 sed 版本,并在创建备份后删除
sed -i.bak -e '/use-node-version/d' -e '/node-mirror/d' .npmrc
[ -f .npmrc.bak ] && rm .npmrc.bak
echo ".npmrc 已清理。"
echo "::endgroup::"
# --- 6. 设置输出 ---
echo "::group::🚀 设置 GitHub Actions 输出"
echo "packageManager=${pkg_manager}" >> $GITHUB_OUTPUT
echo "pnpmVersion=${pnpm_version}" >> $GITHUB_OUTPUT
echo "pnpmInstalled=${is_pnpm_installed}" >> $GITHUB_OUTPUT
echo "pnpmLockExists=${has_pnpm_lock}" >> $GITHUB_OUTPUT
echo "nodeVersion=${node_version}" >> $GITHUB_OUTPUT
echo "输出已设置:"
printf " %-16s %s\n" "packageManager:" "${pkg_manager}"
printf " %-16s %s\n" "pnpmVersion:" "${pnpm_version}"
printf " %-16s %s\n" "pnpmInstalled:" "${is_pnpm_installed}"
printf " %-16s %s\n" "pnpmLockExists:" "${has_pnpm_lock}"
printf " %-16s %s\n" "nodeVersion:" "${node_version}"
echo "::endgroup::"
- uses: pnpm/action-setup@v4 # https://github.com/pnpm/action-setup?tab=readme-ov-file#inputs
if: steps.prepare.outputs.pnpmInstalled == 'false'
with:
version: ${{ steps.prepare.outputs.pnpmVersion }}
standalone: ${{ inputs.pnpm_standalone }}
- uses: actions/setup-node@v4 # https://github.com/actions/setup-node?tab=readme-ov-file#usage
with:
node-version: ${{ steps.prepare.outputs.nodeVersion }}
cache: ''
- id: pnpm-store-dir
shell: bash
run: |
echo "🤖---- 获取 PNPM 存储目录 ----🤖"
echo "PNPM 存储目录: $(pnpm store path)"
echo "pnpmStoreDir=$(pnpm store path)" >> $GITHUB_OUTPUT
- id: cache-pnpm-restore
uses: actions/cache/restore@v4 # https://github.com/actions/cache/blob/main/restore/action.yml
with:
path: ${{ steps.pnpm-store-dir.outputs.pnpmStoreDir }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- run: echo "package-import-method=hardlink" >> .npmrc
shell: bash
- if: steps.cache-pnpm-restore.outputs.cache-hit == 'true'
working-directory: ${{ inputs.package_json_cwd }}
shell: bash
run: |
echo "🤖---- 缓存命中,安装依赖 ----🤖"
pnpm install --prefer-offline
# --frozen-lockfile
# ERR_PNPM_NO_LOCKFILE Cannot install with "frozen-lockfile" because pnpm-lock.yaml is absent
- if: steps.cache-pnpm-restore.outputs.cache-hit != 'true'
working-directory: ${{ inputs.package_json_cwd }}
shell: bash
run: |
echo "🤖---- 缓存未命中,安装依赖 ----🤖"
set -x;
pnpm fetch # https://pnpm.io/zh/cli/fetch
pnpm install --prefer-offline
# --frozen-lockfile
# ERR_PNPM_NO_LOCKFILE Cannot install with "frozen-lockfile" because pnpm-lock.yaml is absent
pnpm store prune
- id: cache-pnpm-save
if: always() && steps.cache-pnpm-restore.outputs.cache-hit == 'false'
uses: actions/cache/save@v4
with:
path: ${{ steps.pnpm-store-dir.outputs.pnpmStoreDir }}
key: ${{ steps.cache-pnpm-restore.outputs.cache-primary-key }}
# # https://github.com/pnpm/pnpm/issues/7192#issuecomment-2353298966
# package-import-method=hardlink
# rm -r node_modules
# pnpm fetch
# pnpm install --offline
# pnpm store prune
# #
# rm -r node_modules
# pnpm install --offline

View File

@ -0,0 +1,87 @@
name: '上传文件到 Alist'
description: '将文件上传到 Alist 服务器'
inputs:
alist_url:
description: 'Alist 服务器地址(不包含末尾的 /'
required: true
default: 'https://alist.oo1.dev'
alist_username:
description: 'Alist 用户名'
required: true
alist_password:
description: 'Alist 密码'
required: true
alist_target:
description: 'Alist 目标路径(完整路径,如:/folder/subfolder/file.zip'
required: true
file:
description: '要上传的文件路径(完整路径,如:./path/to/file.zip'
required: true
runs:
using: 'composite'
steps:
- name: 检查文件
shell: bash
run: |
if [ ! -f "${{ inputs.file }}" ]; then
echo "错误: 文件 '${{ inputs.file }}' 不存在"
exit 1
fi
# 获取文件大小
file_size=$(stat -f%z "${{ inputs.file }}" 2>/dev/null || stat -c%s "${{ inputs.file }}")
echo "文件大小: $file_size 字节"
if [ "$file_size" -eq 0 ]; then
echo "错误: 文件为空"
exit 1
fi
- name: 获取 Alist Token
shell: bash
id: get_token
run: |
response=$(curl -s --location '${{ inputs.alist_url }}/api/auth/login' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode "Username=${{ inputs.alist_username }}" \
--data-urlencode "Password=${{ inputs.alist_password }}")
if ! echo "$response" | jq -e . >/dev/null 2>&1; then
echo "错误: 服务器返回的不是有效的 JSON 响应"
echo "响应内容: $response"
exit 1
fi
token=$(echo "$response" | jq -r ".data.token")
if [ "$token" = "null" ] || [ -z "$token" ]; then
echo "错误: 获取 token 失败"
echo "响应内容: $response"
exit 1
fi
echo "成功获取 token"
echo "token=$token" >> $GITHUB_OUTPUT
- name: 上传文件到 Alist
shell: bash
run: |
response=$(curl -s --location --request PUT '${{ inputs.alist_url }}/api/fs/form' \
--header "Authorization: ${{ steps.get_token.outputs.token }}" \
--header "file-path: ${{ inputs.alist_target }}" \
--form "file=@${{ inputs.file }}")
if ! echo "$response" | jq -e . >/dev/null 2>&1; then
echo "错误: 服务器返回的不是有效的 JSON 响应"
echo "响应内容: $response"
exit 1
fi
if echo "$response" | jq -e '.code == 200' >/dev/null 2>&1; then
echo "✅ 文件上传成功"
else
echo "❌ 文件上传失败"
echo "错误响应: $response"
exit 1
fi