feat: CN 资源镜像 (mcpp-res) + GLOBAL/CN url 表 #105
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: validate | |
| on: | |
| pull_request: | |
| paths: ["pkgs/**/*.lua", "tests/**", "README.md", ".github/workflows/validate.yml"] | |
| push: | |
| branches: [main] | |
| jobs: | |
| lint: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install lua | |
| run: sudo apt-get install -y --no-install-recommends lua5.4 | |
| - name: Lint package descriptors | |
| run: | | |
| fail=0 | |
| for f in pkgs/*/*.lua; do | |
| # 1. Lua syntax check — load (= compile) without executing. | |
| # `loadfile(name, 't')` rejects bytecode and parses text only. | |
| if ! lua5.4 -e "assert(loadfile('$f', 't'))" >/dev/null 2>&1; then | |
| echo "::error file=$f::lua syntax error" | |
| fail=1 | |
| fi | |
| # 2. xpkg V1 baseline: the file has to populate `package = { ... }` | |
| # with at least `spec`, `name`, and an `xpm` table. Form A vs | |
| # Form B (mcpp = "<path>" / mcpp = { ... }) is descriptor-author | |
| # choice and not enforced here. | |
| for needle in 'spec *=' 'name *=' 'xpm *='; do | |
| if ! grep -q "$needle" "$f"; then | |
| echo "::error file=$f::missing required field ($needle)" | |
| fail=1 | |
| fi | |
| done | |
| # 3. Package version identifiers and dependency versions should be | |
| # bare versions ("1.2.3"), not upstream tag names ("v1.2.3"). | |
| # Download URLs may still contain refs/tags/v* when upstream | |
| # uses that tag spelling. | |
| if grep -nE '\["v[0-9]+|\["[^"]+"\][[:space:]]*=[[:space:]]*"v[0-9]+' "$f"; then | |
| echo "::error file=$f::version identifiers must not use a leading v" | |
| fail=1 | |
| fi | |
| # 4. Mirror table sanity: when a download `url` is written as a | |
| # { GLOBAL=..., CN=... } table, both regions must be present and | |
| # the CN entry must point at the gitcode mcpp-res mirror. | |
| if ! lua5.4 tests/check_mirror_urls.lua "$f"; then | |
| fail=1 | |
| fi | |
| done | |
| [ $fail -eq 0 ] && echo "All package files valid." | |
| exit $fail | |
| mirror-cn-reachable: | |
| # Closed-loop guard for the CN mirror: every CN url referenced by a | |
| # descriptor must be a live, downloadable gitcode release asset. | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install lua | |
| run: sudo apt-get install -y --no-install-recommends lua5.4 | |
| - name: Check CN mirror assets are reachable | |
| run: | | |
| fail=0 | |
| # collect unique CN urls across all descriptors | |
| : > /tmp/cn.tsv | |
| for f in pkgs/*/*.lua; do | |
| lua5.4 tests/list_cn_urls.lua "$f" >> /tmp/cn.tsv || true | |
| done | |
| sort -u /tmp/cn.tsv -o /tmp/cn.tsv | |
| total=$(grep -c . /tmp/cn.tsv || true) | |
| echo "checking $total CN mirror url(s)" | |
| while IFS=$'\t' read -r url sha; do | |
| [ -z "$url" ] && continue | |
| # follow redirects; gitcode release assets resolve to object storage | |
| code=$(curl -fsSL -o /dev/null -w '%{http_code}' --retry 2 --max-time 60 "$url" || echo "000") | |
| if [ "$code" != "200" ]; then | |
| echo "::error::CN mirror unreachable ($code): $url" | |
| fail=1 | |
| else | |
| echo "ok: $url" | |
| fi | |
| done < /tmp/cn.tsv | |
| [ $fail -eq 0 ] && echo "All CN mirror urls reachable." | |
| exit $fail | |
| smoke-linux: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Restore mcpp registry cache | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.mcpp/registry | |
| key: mcpp-registry-${{ runner.os }}-0.0.46-${{ hashFiles('pkgs/**/*.lua', 'tests/*.sh', '.github/workflows/validate.yml') }} | |
| restore-keys: | | |
| mcpp-registry-${{ runner.os }}-0.0.46- | |
| - name: Download mcpp | |
| env: | |
| MCPP_VERSION: "0.0.46" | |
| run: | | |
| curl -L -fsS -o mcpp.tar.gz \ | |
| "https://github.com/mcpp-community/mcpp/releases/download/v${MCPP_VERSION}/mcpp-${MCPP_VERSION}-linux-x86_64.tar.gz" | |
| tar -xzf mcpp.tar.gz | |
| root="$PWD/mcpp-${MCPP_VERSION}-linux-x86_64" | |
| mkdir -p "$HOME/.mcpp/registry" | |
| cp -a "$root/registry/." "$HOME/.mcpp/registry/" | |
| echo "MCPP=$root/bin/mcpp" >> "$GITHUB_ENV" | |
| echo "MCPP_VENDORED_XLINGS=$root/registry/bin/xlings" >> "$GITHUB_ENV" | |
| echo "$root/bin" >> "$GITHUB_PATH" | |
| - name: Run compat smoke tests | |
| env: | |
| MCPP_INDEX_SMOKE_MCPP_HOME: ${{ runner.temp }}/mcpp-smoke-home | |
| MCPP_INDEX_SMOKE_CACHE_DIR: ${{ runner.temp }}/mcpp-smoke-cache | |
| run: | | |
| mkdir -p "$MCPP_INDEX_SMOKE_MCPP_HOME" | |
| "$MCPP" --version | |
| timeout 1800 bash tests/smoke_compat_core.sh | |
| timeout 1800 bash tests/smoke_compat_imgui.sh | |
| timeout 1800 bash tests/smoke_compat_archive.sh | |
| timeout 1800 bash tests/smoke_compat_imgui_window.sh | |
| timeout 1800 bash tests/smoke_imgui_module.sh | |
| smoke-portable: | |
| name: smoke-${{ matrix.platform }} | |
| runs-on: ${{ matrix.os }} | |
| timeout-minutes: 60 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - platform: macos | |
| os: macos-15 | |
| archive: mcpp-0.0.46-macosx-arm64.tar.gz | |
| root: mcpp-0.0.46-macosx-arm64 | |
| mcpp: bin/mcpp | |
| xlings: registry/bin/xlings | |
| - platform: windows | |
| os: windows-latest | |
| archive: mcpp-0.0.46-windows-x86_64.zip | |
| root: mcpp-0.0.46-windows-x86_64 | |
| mcpp: bin/mcpp.exe | |
| xlings: registry/bin/xlings.exe | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Restore mcpp registry cache | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.mcpp/registry | |
| key: mcpp-registry-${{ runner.os }}-0.0.46-${{ hashFiles('pkgs/**/*.lua', 'tests/*.sh', '.github/workflows/validate.yml') }} | |
| restore-keys: | | |
| mcpp-registry-${{ runner.os }}-0.0.46- | |
| - name: Download mcpp | |
| shell: bash | |
| env: | |
| MCPP_VERSION: "0.0.46" | |
| MCPP_ARCHIVE: ${{ matrix.archive }} | |
| MCPP_ROOT: ${{ matrix.root }} | |
| run: | | |
| curl -L -fsS -o "$MCPP_ARCHIVE" \ | |
| "https://github.com/mcpp-community/mcpp/releases/download/v${MCPP_VERSION}/${MCPP_ARCHIVE}" | |
| case "$MCPP_ARCHIVE" in | |
| *.zip) | |
| powershell -NoProfile -Command "Expand-Archive -Force -Path '${MCPP_ARCHIVE}' -DestinationPath '.'" | |
| ;; | |
| *) | |
| tar -xzf "$MCPP_ARCHIVE" | |
| ;; | |
| esac | |
| root="$PWD/$MCPP_ROOT" | |
| mkdir -p "$HOME/.mcpp/registry" | |
| cp -a "$root/registry/." "$HOME/.mcpp/registry/" | |
| if [[ "$RUNNER_OS" == "Windows" ]]; then | |
| echo "MCPP=$(cygpath -m "$root/${{ matrix.mcpp }}")" >> "$GITHUB_ENV" | |
| echo "MCPP_VENDORED_XLINGS=$(cygpath -m "$root/${{ matrix.xlings }}")" >> "$GITHUB_ENV" | |
| echo "$(cygpath -m "$root/bin")" >> "$GITHUB_PATH" | |
| else | |
| echo "MCPP=$root/${{ matrix.mcpp }}" >> "$GITHUB_ENV" | |
| echo "MCPP_VENDORED_XLINGS=$root/${{ matrix.xlings }}" >> "$GITHUB_ENV" | |
| echo "$root/bin" >> "$GITHUB_PATH" | |
| fi | |
| - name: Run portable compat smoke tests | |
| shell: bash | |
| env: | |
| MCPP_INDEX_MIRROR: GLOBAL | |
| run: | | |
| "$MCPP" --version | |
| bash tests/smoke_compat_portable.sh |