Skip to content

feat(stash): sync templates to dedicated repository #208

feat(stash): sync templates to dedicated repository

feat(stash): sync templates to dedicated repository #208

Workflow file for this run

name: Validate repository
on:
workflow_call:
inputs:
revision:
description: Exact repository revision to validate
required: true
type: string
push:
branches:
- main
# Resource and documentation changes use their focused publication flows.
paths:
- '.github/**'
- 'py/**'
- 'script/**/*.js'
- 'shell/**/*.sh'
- 'cfg/*.ini'
- 'cfg/yaml/**'
- 'requirements*.txt'
- 'workers/repository-mirror/**'
pull_request:
branches:
- main
paths:
- '.github/**'
- 'py/**'
- 'rule/Custom_Direct.list'
- 'rule/Custom_Proxy.list'
- 'rule/Steam_CDN.list'
- 'rule/Encrypted_DNS.list'
- 'rule/Game_Download_CDN.list'
- 'rule/game_rule/**/*.list'
- 'script/**/*.js'
- 'shell/**/*.sh'
- 'cfg/*.ini'
- 'cfg/yaml/**'
- 'requirements*.txt'
- 'workers/repository-mirror/**'
workflow_dispatch:
permissions:
contents: read
concurrency:
group: >-
validate-${{ inputs.revision && 'snapshot' || 'event' }}-${{
inputs.revision || github.ref
}}
cancel-in-progress: true
jobs:
dependency-review:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Reject newly introduced vulnerable dependencies
uses: actions/dependency-review-action@a1d282b36b6f3519aa1f3fc636f609c47dddb294 # v5.0.0
with:
fail-on-severity: low
fail-on-scopes: development, runtime, unknown
retry-on-snapshot-warnings: true
retry-on-snapshot-warnings-timeout: 120
show-openssf-scorecard: true
warn-on-openssf-scorecard-level: 5
show-patched-versions: true
validate:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
ref: ${{ inputs.revision || github.sha }}
fetch-depth: 0
- name: Set up Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: '24'
- name: Validate JavaScript
shell: bash
run: |
git ls-files -z -- '*.js' '*.mjs' '*.cjs' |
xargs -0 -r -n 1 -t node --check
node --test .github/scripts/*.test.cjs
- name: Set up Python
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: '3.13'
- name: Set up pinned Mihomo
uses: ./.github/actions/setup-mihomo
- name: Materialize derived rules for changed sources
if: github.event_name == 'push' || github.event_name == 'pull_request'
shell: bash
env:
EVENT_NAME: ${{ github.event_name }}
EVENT_BEFORE: ${{ github.event.before }}
EVENT_SHA: ${{ github.sha }}
BASE_SHA: ${{ github.event.pull_request.base.sha }}
run: |
set -euo pipefail
if [ "$EVENT_NAME" = "pull_request" ]; then
diff_base="$BASE_SHA"
elif [ -n "$EVENT_BEFORE" ] && [ "${EVENT_BEFORE//0/}" != "" ]; then
diff_base="$EVENT_BEFORE"
else
diff_base="$(git rev-parse "${EVENT_SHA}^")"
fi
source_pathspecs=(
'rule/Custom_Direct.list'
'rule/Custom_Proxy.list'
'rule/Steam_CDN.list'
'rule/Encrypted_DNS.list'
'rule/Game_Download_CDN.list'
':(glob)rule/game_rule/**/*.list'
'py/generate_rules.py'
)
if git diff --quiet "$diff_base" "$EVENT_SHA" -- \
"${source_pathspecs[@]}"; then
echo "No derived-rule source changed."
exit 0
fi
echo "Materializing derived rules for validation only."
python py/generate_rules.py --mihomo mihomo
- name: Download and verify static analysis tools
env:
SHELLCHECK_VERSION: v0.11.0
SHELLCHECK_SHA256: 8c3be12b05d5c177a04c29e3c78ce89ac86f1595681cab149b65b97c4e227198
ACTIONLINT_VERSION: 1.7.12
ACTIONLINT_SHA256: 8aca8db96f1b94770f1b0d72b6dddcb1ebb8123cb3712530b08cc387b349a3d8
run: |
set -euo pipefail
shellcheck_archive="shellcheck-${SHELLCHECK_VERSION}.linux.x86_64.tar.xz"
actionlint_archive="actionlint_${ACTIONLINT_VERSION}_linux_amd64.tar.gz"
curl --fail --location --show-error \
--retry 3 --retry-delay 3 --retry-all-errors --retry-max-time 120 \
--connect-timeout 15 --max-time 60 \
--output "$shellcheck_archive" \
"https://github.com/koalaman/shellcheck/releases/download/${SHELLCHECK_VERSION}/${shellcheck_archive}"
curl --fail --location --show-error \
--retry 3 --retry-delay 3 --retry-all-errors --retry-max-time 120 \
--connect-timeout 15 --max-time 60 \
--output "$actionlint_archive" \
"https://github.com/rhysd/actionlint/releases/download/v${ACTIONLINT_VERSION}/${actionlint_archive}"
printf '%s %s\n' "$SHELLCHECK_SHA256" "$shellcheck_archive" | sha256sum --check --strict
printf '%s %s\n' "$ACTIONLINT_SHA256" "$actionlint_archive" | sha256sum --check --strict
tar -xJf "$shellcheck_archive"
tar -xzf "$actionlint_archive"
install -m 0755 "shellcheck-${SHELLCHECK_VERSION}/shellcheck" "$RUNNER_TEMP/shellcheck"
install -m 0755 actionlint "$RUNNER_TEMP/actionlint"
- name: Validate scripts and generated rules
run: |
sh -n shell/check_cpu_version.sh
sh -n shell/install_openclash_dev.sh
sh -n shell/install_openclash_dev_update.sh
sh -n .github/scripts/test_installers.sh
shellcheck --shell=sh shell/check_cpu_version.sh shell/install_openclash_dev.sh shell/install_openclash_dev_update.sh .github/scripts/test_installers.sh
actionlint .github/workflows/*.yml
sh shell/check_cpu_version.sh --self-check
python -m unittest discover -s py -p 'test_rule_generation.py'
python -m unittest discover -s .github/scripts -p 'test_*.py'
python .github/scripts/jsdelivr_purge.py check-contract --revision HEAD
sh .github/scripts/test_installers.sh
python py/sync_installer_common.py --check
python py/generate_game_cdn.py --check
python py/update_encrypted_dns.py --check
python py/generate_rules.py --check --mihomo mihomo
python py/generate_stash_configs.py --check
- name: Validate complete Mihomo templates
run: |
for config in cfg/yaml/*.yaml; do
mihomo -t -d "$RUNNER_TEMP/mihomo-config" -f "$config"
done
- name: Build and validate Cloudflare mirror bundle
env:
MIRROR_REVISION: ${{ inputs.revision || github.sha }}
run: |
python .github/scripts/jsdelivr_purge.py build-worker-assets \
--revision "$MIRROR_REVISION" \
--output workers/repository-mirror/dist
npm ci --prefix workers/repository-mirror
(
cd workers/repository-mirror
npm exec -- wrangler deploy \
--dry-run --outdir "$RUNNER_TEMP/wrangler-dry-run"
)