mirror of
https://github.com/yanhao98/composite-actions.git
synced 2025-09-18 03:57:03 +08:00
✔
This commit is contained in:
1
.github/_files/.npmrc
vendored
Normal file
1
.github/_files/.npmrc
vendored
Normal 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
6
.github/_files/package.json
vendored
Normal 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
125
.github/_files/pnpm-lock.yaml
generated
vendored
Normal 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
|
35
.github/gh-packages-delete.sh
vendored
Normal file
35
.github/gh-packages-delete.sh
vendored
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# 设置变量
|
||||||
|
OWNER="yanhao98"
|
||||||
|
REPO="gemini-balance"
|
||||||
|
PACKAGE_NAME="gemini-balance"
|
||||||
|
|
||||||
|
# 重新登录 GitHub CLI 获取更多权限
|
||||||
|
echo "正在更新 GitHub CLI 权限..."
|
||||||
|
gh auth refresh -h github.com -s read:packages,delete:packages
|
||||||
|
|
||||||
|
# 列出所有版本的容器镜像
|
||||||
|
echo "正在获取 $PACKAGE_NAME 所有版本..."
|
||||||
|
VERSIONS=$(gh api \
|
||||||
|
"/user/packages/container/$PACKAGE_NAME/versions" \
|
||||||
|
--paginate \
|
||||||
|
--jq '.[].id')
|
||||||
|
|
||||||
|
# 检查是否有版本存在
|
||||||
|
if [ -z "$VERSIONS" ]; then
|
||||||
|
echo "没有找到 $PACKAGE_NAME 的任何版本"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 删除每个版本
|
||||||
|
echo "开始删除 $PACKAGE_NAME 的所有版本..."
|
||||||
|
for version_id in $VERSIONS; do
|
||||||
|
echo "正在删除版本 ID: $version_id"
|
||||||
|
gh api \
|
||||||
|
--method DELETE \
|
||||||
|
"/user/packages/container/$PACKAGE_NAME/versions/$version_id"
|
||||||
|
echo "版本 $version_id 已删除"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "所有 $PACKAGE_NAME 容器镜像版本已成功删除"
|
4
.github/gh-run-delete.sh
vendored
Normal file
4
.github/gh-run-delete.sh
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
while gh run list --json databaseId --jq '.[].databaseId' | grep -q .; do
|
||||||
|
for id in $(gh run list --json databaseId --jq '.[].databaseId'); do gh run delete $id; done
|
||||||
|
echo "继续删除下一批..."
|
||||||
|
done
|
66
.github/workflows/_delete-workflow-runs.yaml
vendored
Normal file
66
.github/workflows/_delete-workflow-runs.yaml
vendored
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
name: 删除旧的工作流运行
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
days:
|
||||||
|
description: '为每个工作流保留的运行天数'
|
||||||
|
required: true
|
||||||
|
default: '30'
|
||||||
|
minimum_runs:
|
||||||
|
description: '为每个工作流保留的最小运行次数'
|
||||||
|
required: true
|
||||||
|
default: '6'
|
||||||
|
delete_workflow_pattern:
|
||||||
|
description: '工作流的名称或文件名(如果未设置,则针对所有工作流)'
|
||||||
|
required: false
|
||||||
|
delete_workflow_by_state_pattern:
|
||||||
|
description: '按状态筛选工作流:active, deleted, disabled_fork, disabled_inactivity, disabled_manually'
|
||||||
|
required: true
|
||||||
|
default: "ALL"
|
||||||
|
type: choice
|
||||||
|
options:
|
||||||
|
- "ALL"
|
||||||
|
- active
|
||||||
|
- deleted
|
||||||
|
- disabled_inactivity
|
||||||
|
- disabled_manually
|
||||||
|
delete_run_by_conclusion_pattern:
|
||||||
|
description: '根据结论删除运行:action_required, cancelled, failure, skipped, success'
|
||||||
|
required: true
|
||||||
|
default: "ALL"
|
||||||
|
type: choice
|
||||||
|
options:
|
||||||
|
- "ALL"
|
||||||
|
- "Unsuccessful: action_required,cancelled,failure,skipped"
|
||||||
|
- action_required
|
||||||
|
- cancelled
|
||||||
|
- failure
|
||||||
|
- skipped
|
||||||
|
- success
|
||||||
|
dry_run:
|
||||||
|
description: '记录模拟的更改,不执行任何删除操作'
|
||||||
|
required: false
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
del_runs:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
actions: write
|
||||||
|
contents: read
|
||||||
|
steps:
|
||||||
|
- name: 删除工作流运行
|
||||||
|
uses: Mattraks/delete-workflow-runs@v2
|
||||||
|
with:
|
||||||
|
token: ${{ github.token }}
|
||||||
|
repository: ${{ github.repository }}
|
||||||
|
retain_days: ${{ github.event.inputs.days }}
|
||||||
|
keep_minimum_runs: ${{ github.event.inputs.minimum_runs }}
|
||||||
|
delete_workflow_pattern: ${{ github.event.inputs.delete_workflow_pattern }}
|
||||||
|
delete_workflow_by_state_pattern: ${{ github.event.inputs.delete_workflow_by_state_pattern }}
|
||||||
|
delete_run_by_conclusion_pattern: >-
|
||||||
|
${{
|
||||||
|
startsWith(github.event.inputs.delete_run_by_conclusion_pattern, 'Unsuccessful:')
|
||||||
|
&& 'action_required,cancelled,failure,skipped'
|
||||||
|
|| github.event.inputs.delete_run_by_conclusion_pattern
|
||||||
|
}}
|
||||||
|
dry_run: ${{ github.event.inputs.dry_run }}
|
64
.github/workflows/deploy-dist-to-surge-tetst.yaml
vendored
Normal file
64
.github/workflows/deploy-dist-to-surge-tetst.yaml
vendored
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
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: Checkout code # Required to use the local version of the action
|
||||||
|
uses: actions/checkout@main
|
||||||
|
|
||||||
|
- name: 准备部署文件 (Testing working_dir and dist_dir)
|
||||||
|
run: |
|
||||||
|
mkdir -p test_project/build_output
|
||||||
|
html="<!DOCTYPE html><html><body><h1>Test: ${{ github.event_name }}: ${{ github.sha }} - Custom Dirs</h1></body></html>"
|
||||||
|
echo $html > test_project/build_output/index.html
|
||||||
|
|
||||||
|
- name: Deploy with custom working_dir and dist_dir
|
||||||
|
uses: ./deploy-dist-to-surge # Use local action
|
||||||
|
id: surge_deploy_custom
|
||||||
|
with:
|
||||||
|
working_dir: ./test_project
|
||||||
|
dist_dir: build_output
|
||||||
|
domain_suffix: -custom
|
||||||
|
|
||||||
|
- name: Check Surge URL (Custom Dirs)
|
||||||
|
run: |
|
||||||
|
echo "Custom dirs deployment URL: ${{ steps.surge_deploy_custom.outputs.url }}"
|
||||||
|
# Add a basic check if the URL is not empty
|
||||||
|
if [ -z "${{ steps.surge_deploy_custom.outputs.url }}" ]; then
|
||||||
|
echo "Error: Surge URL for custom dirs is empty!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: 准备部署文件 (Testing default dist_dir)
|
||||||
|
run: |
|
||||||
|
mkdir dist
|
||||||
|
html="<!DOCTYPE html><html><body><h1>Test: ${{ github.event_name }}: ${{ github.sha }} - Default Dist</h1></body></html>"
|
||||||
|
echo $html > dist/index.html
|
||||||
|
|
||||||
|
- name: Deploy with default dist_dir
|
||||||
|
uses: ./deploy-dist-to-surge # Use local action
|
||||||
|
id: surge_deploy_default
|
||||||
|
with:
|
||||||
|
domain_suffix: -default
|
||||||
|
|
||||||
|
- name: Check Surge URL (Default Dist)
|
||||||
|
run: |
|
||||||
|
echo "Default dist deployment URL: ${{ steps.surge_deploy_default.outputs.url }}"
|
||||||
|
# Add a basic check if the URL is not empty
|
||||||
|
if [ -z "${{ steps.surge_deploy_default.outputs.url }}" ]; then
|
||||||
|
echo "Error: Surge URL for default dist is empty!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
# The following line was from the old version and is redundant as we check specific outputs above.
|
||||||
|
# echo "steps.surge_deploy.outputs.url: ${{ steps.surge_deploy.outputs.url }}"
|
134
.github/workflows/docker-build-push-test.yaml
vendored
Normal file
134
.github/workflows/docker-build-push-test.yaml
vendored
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
# 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 }}
|
||||||
|
BUILDKIT_INLINE_CACHE=1
|
||||||
|
# #####
|
||||||
|
# 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;
|
26
.github/workflows/npm-build-fix-to-nexus-test.yaml
vendored
Normal file
26
.github/workflows/npm-build-fix-to-nexus-test.yaml
vendored
Normal 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 }}
|
126
.github/workflows/setup-node-environment-test.yaml
vendored
Normal file
126
.github/workflows/setup-node-environment-test.yaml
vendored
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
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:
|
||||||
|
npmrc_content:
|
||||||
|
- ''
|
||||||
|
- |
|
||||||
|
use-node-version=22.14.0 # https://pnpm.io/zh/npmrc#use-node-version
|
||||||
|
lock_file:
|
||||||
|
- 'true'
|
||||||
|
- 'false'
|
||||||
|
cwd:
|
||||||
|
- ''
|
||||||
|
- 'test'
|
||||||
|
steps:
|
||||||
|
# - uses: actions/checkout@main
|
||||||
|
- name: 打印 matrix
|
||||||
|
run: |
|
||||||
|
echo "🤖---- 打印 matrix ----🤖"
|
||||||
|
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 }}
|
||||||
|
set -x;
|
||||||
|
ls -l -R .
|
||||||
|
pwd
|
||||||
|
|
||||||
|
- name: Create .npmrc
|
||||||
|
working-directory: ${{ matrix.cwd }}
|
||||||
|
if: matrix.npmrc_content != ''
|
||||||
|
run: |
|
||||||
|
cat <<EOF > .npmrc
|
||||||
|
${{ matrix.npmrc_content }}
|
||||||
|
EOF
|
||||||
|
set -x;
|
||||||
|
ls -l -R .
|
||||||
|
pwd
|
||||||
|
cat .npmrc
|
||||||
|
|
||||||
|
- 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 .
|
||||||
|
pwd
|
||||||
|
cat package.json
|
||||||
|
|
||||||
|
- name: Create pnpm-lock.yaml
|
||||||
|
working-directory: ${{ matrix.cwd }}
|
||||||
|
if: matrix.lock_file == 'true'
|
||||||
|
run: |
|
||||||
|
cat <<EOF > pnpm-lock.yaml
|
||||||
|
${{ needs.generate_lock.outputs.lock_file_content }}
|
||||||
|
EOF
|
||||||
|
set -x;
|
||||||
|
ls -l -R .
|
||||||
|
pwd
|
||||||
|
cat pnpm-lock.yaml
|
||||||
|
|
||||||
|
- name: ⚙️ 设置 Node 环境
|
||||||
|
uses: yanhao98/composite-actions/setup-node-environment@main
|
||||||
|
with:
|
||||||
|
working-directory: ${{ matrix.cwd }}
|
50
.github/workflows/upload-to-alist-example-test.yaml
vendored
Normal file
50
.github/workflows/upload-to-alist-example-test.yaml
vendored
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
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@main
|
||||||
|
|
||||||
|
- 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
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
node_modules
|
7
.releaserc.json
Normal file
7
.releaserc.json
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"plugins": [
|
||||||
|
"@semantic-release/commit-analyzer",
|
||||||
|
"@semantic-release/release-notes-generator",
|
||||||
|
"@semantic-release/changelog"
|
||||||
|
]
|
||||||
|
}
|
12
Dockerfile.test
Normal file
12
Dockerfile.test
Normal 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
|
||||||
|
|
||||||
|
|
||||||
|
|
67
README.md
Normal file
67
README.md
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
# GitHub Actions Collection
|
||||||
|
|
||||||
|
This repository contains a collection of reusable GitHub Actions.
|
||||||
|
|
||||||
|
## Actions
|
||||||
|
|
||||||
|
### Deploy dist to Surge (`deploy-dist-to-surge`)
|
||||||
|
|
||||||
|
Deploys a distribution folder (typically `dist/`) to Surge.sh.
|
||||||
|
|
||||||
|
#### Inputs
|
||||||
|
|
||||||
|
| 名称 | 描述 | 是否必须 | 默认值 |
|
||||||
|
|---------------|-----------------------------------------------------------------------------------------------------------------|----------|---------|
|
||||||
|
| `working_dir` | 执行 Surge 部署的工作目录。默认为仓库根目录。 | `false` | `.` |
|
||||||
|
| `dist_dir` | 包含要部署的构建产物的目录。如果指定了 `working_dir`,则相对于 `working_dir`,否则相对于仓库根目录。 | `false` | `dist` |
|
||||||
|
| `domain_suffix` | 部署时用于创建唯一域名的后缀(例如,用于在同一工作流程中测试多个实例)。最终域名将是 `<sha><suffix>.surge.sh`。 | `false` | `''` |
|
||||||
|
| `surge_token` | **已弃用.** 用于部署的 Surge 令牌。建议在工作流程中将其设置为环境变量 `SURGE_TOKEN`。 | `false` | (从 `SURGE_TOKEN` 环境变量读取,如果未设置则使用硬编码令牌) |
|
||||||
|
|
||||||
|
|
||||||
|
#### Outputs
|
||||||
|
|
||||||
|
| Name | Description |
|
||||||
|
|-------|------------------|
|
||||||
|
| `url` | The Preview URL. |
|
||||||
|
|
||||||
|
#### Example Usage
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
name: Deploy to Surge
|
||||||
|
|
||||||
|
on: [push]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
deploy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@main
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: '18'
|
||||||
|
# Assuming your build process outputs to 'build_output' inside 'frontend' directory
|
||||||
|
- name: Build application
|
||||||
|
run: |
|
||||||
|
cd frontend
|
||||||
|
npm install
|
||||||
|
npm run build
|
||||||
|
- name: Deploy to Surge
|
||||||
|
uses: YOUR_USERNAME/YOUR_REPONAME/deploy-dist-to-surge@main # Replace with your actual repo path
|
||||||
|
with:
|
||||||
|
working_dir: frontend
|
||||||
|
dist_dir: build_output
|
||||||
|
env:
|
||||||
|
SURGE_TOKEN: ${{ secrets.SURGE_TOKEN }} # Recommended way to provide the token
|
||||||
|
```
|
||||||
|
|
||||||
|
### Other Actions
|
||||||
|
|
||||||
|
- **`docker-build-push`**: Builds and pushes Docker images.
|
||||||
|
- **`npm-build-fix-to-nexus`**: Builds and fixes NPM packages for Nexus.
|
||||||
|
- **`setup-node-environment`**: Sets up a Node.js environment.
|
||||||
|
- **`upload-to-alist`**: Uploads files to Alist.
|
||||||
|
|
||||||
|
---
|
||||||
|
*Original reference note (can be removed or integrated elsewhere):*
|
||||||
|
- https://github.com/renovatebot/renovate/blob/81fc75630b0b43fb4b89a0b65c1086d487e65d2e/.github/actions/setup-node/action.yml
|
37
deploy-dist-to-surge/action.yml
Normal file
37
deploy-dist-to-surge/action.yml
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
name: "Deploy dist to Surge"
|
||||||
|
description: "部署 dist 到 Surge"
|
||||||
|
inputs:
|
||||||
|
working_dir:
|
||||||
|
description: '执行 Surge 部署的工作目录。默认为仓库根目录。'
|
||||||
|
required: false
|
||||||
|
default: '.'
|
||||||
|
dist_dir:
|
||||||
|
description: '包含要部署的构建产物的目录。如果指定了 `working_dir`,则相对于 `working_dir`,否则相对于仓库根目录。'
|
||||||
|
required: false
|
||||||
|
default: 'dist'
|
||||||
|
domain_suffix:
|
||||||
|
description: '部署时用于创建唯一域名的后缀(例如,用于在同一工作流程中测试多个实例)。最终域名将是 `<sha><suffix>.surge.sh`。'
|
||||||
|
required: false
|
||||||
|
default: ''
|
||||||
|
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: |
|
||||||
|
if [ "${{ inputs.working_dir }}" != "." ]; then cd ${{ inputs.working_dir }}; fi
|
||||||
|
export DEPLOY_DOMAIN_PREFIX=${{ github.sha }}${{ inputs.domain_suffix }}
|
||||||
|
export DEPLOY_DOMAIN=https://${DEPLOY_DOMAIN_PREFIX}.surge.sh
|
||||||
|
cp ${{ inputs.dist_dir }}/index.html ${{ inputs.dist_dir }}/200.html
|
||||||
|
npx surge --project ./${{ inputs.dist_dir }} --domain $DEPLOY_DOMAIN --token d843de16b331c626f10771245c56ed93 # npx surge token
|
||||||
|
echo the preview URL is $DEPLOY_DOMAIN
|
||||||
|
echo "url=$DEPLOY_DOMAIN" >> $GITHUB_OUTPUT
|
99
docker-build-push/action.yml
Normal file
99
docker-build-push/action.yml
Normal 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 🤖🤖🤖"
|
71
npm-build-fix-to-nexus/action.yml
Normal file
71
npm-build-fix-to-nexus/action.yml
Normal 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
17
renovate.json
Normal 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"
|
||||||
|
]
|
||||||
|
}
|
230
setup-node-environment/action.yml
Normal file
230
setup-node-environment/action.yml
Normal file
@@ -0,0 +1,230 @@
|
|||||||
|
# 🔗 链接:
|
||||||
|
# 源文件: 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'
|
||||||
|
# https://github.com/pnpm/action-setup/blob/d648c2dd069001a242c621c8306af467f150e99d/action.yml#L18C3-L18C20
|
||||||
|
working-directory:
|
||||||
|
description: '工作目录'
|
||||||
|
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@main
|
||||||
|
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.working-directory }}
|
||||||
|
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:
|
||||||
|
# https://github.com/pnpm/action-setup/blob/master/action.yml
|
||||||
|
version: ${{ steps.prepare.outputs.pnpmVersion }}
|
||||||
|
standalone: ${{ inputs.pnpm_standalone }}
|
||||||
|
package_json_file: ${{ inputs.working-directory }}/package.json
|
||||||
|
|
||||||
|
- 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-id${{ github.event.repository.id }}-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-pnpm-store-id${{ github.event.repository.id }}-
|
||||||
|
${{ runner.os }}-pnpm-store-
|
||||||
|
|
||||||
|
# https://github.com/pnpm/pnpm/issues/7192#issuecomment-2353298966
|
||||||
|
- run: echo "package-import-method=hardlink" >> .npmrc
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
- if: steps.cache-pnpm-restore.outputs.cache-hit == 'true'
|
||||||
|
working-directory: ${{ inputs.working-directory }}
|
||||||
|
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.working-directory }}
|
||||||
|
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
|
||||||
|
|
||||||
|
- name: 📊 显示缓存命中状态
|
||||||
|
run: |
|
||||||
|
echo "cache-hit: ${{ steps.cache-pnpm-restore.outputs.cache-hit }}"
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
- id: cache-pnpm-save
|
||||||
|
if: always() && steps.cache-pnpm-restore.outputs.cache-hit != 'true'
|
||||||
|
uses: actions/cache/save@v4
|
||||||
|
with:
|
||||||
|
path: ${{ steps.pnpm-store-dir.outputs.pnpmStoreDir }}
|
||||||
|
key: ${{ steps.cache-pnpm-restore.outputs.cache-primary-key }}
|
||||||
|
# rm -r node_modules
|
||||||
|
# pnpm fetch
|
||||||
|
# pnpm install --offline
|
||||||
|
# pnpm store prune
|
||||||
|
# #
|
||||||
|
# rm -r node_modules
|
||||||
|
# pnpm install --offline
|
87
upload-to-alist/action.yml
Normal file
87
upload-to-alist/action.yml
Normal 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
|
Reference in New Issue
Block a user