mirror of
https://github.com/affaan-m/ECC.git
synced 2026-08-17 21:15:40 +02:00
Make Antigravity 2.0 installs native and safely migrate legacy state. Ensure doctor, repair, status projection, repeat installs, legacy Codex sync, and uninstall converge without losing user files. Exclude Python bytecode and harden repo-scan bootstrap guidance. Gate publishing and pull-request merges on one exact packed artifact completing install, repeat, drift, repair, status, and uninstall across Linux, macOS, and Windows. Co-authored-by: lorencifernando-coder <lorenci.fernando@gmail.com> Co-authored-by: Suliman Abdulrazzaq <suliman9000a@gmail.com> Co-authored-by: Wu Shuwen <mikewushuwen@outlook.com>
349 lines
11 KiB
YAML
349 lines
11 KiB
YAML
name: CI
|
|
|
|
on:
|
|
push:
|
|
branches: [main, 'release/**']
|
|
tags: ['v*']
|
|
pull_request:
|
|
branches: [main]
|
|
|
|
# Prevent duplicate runs
|
|
concurrency:
|
|
group: ${{ github.workflow }}-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
# Minimal permissions
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
test:
|
|
name: Test (${{ matrix.os }}, Node ${{ matrix.node }}, ${{ matrix.pm }})
|
|
runs-on: ${{ matrix.os }}
|
|
timeout-minutes: 20
|
|
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
os: [ubuntu-latest, windows-latest, macos-latest]
|
|
node: ['18.x', '20.x', '22.x']
|
|
pm: [npm, pnpm, yarn, bun]
|
|
exclude:
|
|
# Bun has limited Windows support
|
|
- os: windows-latest
|
|
pm: bun
|
|
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- name: Setup Node.js ${{ matrix.node }}
|
|
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
|
with:
|
|
node-version: ${{ matrix.node }}
|
|
|
|
# Package manager setup
|
|
- name: Setup pnpm
|
|
if: matrix.pm == 'pnpm' && matrix.node != '18.x'
|
|
uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9
|
|
with:
|
|
# Keep an explicit pnpm major because this repo's packageManager is Yarn.
|
|
version: 10
|
|
|
|
- name: Setup pnpm (via Corepack)
|
|
if: matrix.pm == 'pnpm' && matrix.node == '18.x'
|
|
shell: bash
|
|
run: |
|
|
corepack enable
|
|
corepack prepare pnpm@9 --activate
|
|
|
|
- name: Setup Yarn (via Corepack)
|
|
if: matrix.pm == 'yarn'
|
|
shell: bash
|
|
run: |
|
|
corepack enable
|
|
corepack prepare yarn@stable --activate
|
|
|
|
- name: Setup Bun
|
|
if: matrix.pm == 'bun'
|
|
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
|
|
|
|
# Install dependencies
|
|
# COREPACK_ENABLE_STRICT=0 allows pnpm to install even though
|
|
# package.json declares "packageManager": "yarn@..."
|
|
- name: Install dependencies
|
|
shell: bash
|
|
env:
|
|
COREPACK_ENABLE_STRICT: '0'
|
|
npm_config_ignore_scripts: 'true'
|
|
YARN_ENABLE_SCRIPTS: 'false'
|
|
run: |
|
|
case "${{ matrix.pm }}" in
|
|
npm) npm ci --ignore-scripts ;;
|
|
# pnpm v10 can fail CI on ignored native build scripts
|
|
# (for example msgpackr-extract) even though this repo is Yarn-native
|
|
# and pnpm is only exercised here as a compatibility lane.
|
|
pnpm) pnpm install --ignore-scripts --config.strict-dep-builds=false --no-frozen-lockfile ;;
|
|
# Yarn Berry (v4+) removed --ignore-engines; engine checking is no longer a core feature
|
|
yarn) yarn install --mode=skip-build ;;
|
|
bun) bun install --ignore-scripts ;;
|
|
*) echo "Unsupported package manager: ${{ matrix.pm }}" && exit 1 ;;
|
|
esac
|
|
|
|
# Run tests
|
|
- name: Run tests
|
|
run: node tests/run-all.js
|
|
env:
|
|
CLAUDE_CODE_PACKAGE_MANAGER: ${{ matrix.pm }}
|
|
|
|
# Upload test artifacts on failure
|
|
- name: Upload test artifacts
|
|
if: failure()
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: test-results-${{ matrix.os }}-node${{ matrix.node }}-${{ matrix.pm }}
|
|
path: |
|
|
tests/
|
|
!tests/node_modules/
|
|
|
|
pack-installer:
|
|
name: Pack Installer Artifact
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 10
|
|
outputs:
|
|
package_file: ${{ steps.pack.outputs.package_file }}
|
|
package_sha256: ${{ steps.pack.outputs.package_sha256 }}
|
|
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- name: Setup Node.js
|
|
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
|
with:
|
|
node-version: '20.x'
|
|
|
|
- name: Install dependencies
|
|
run: npm ci --ignore-scripts
|
|
|
|
- name: Pack exact installer artifact
|
|
id: pack
|
|
run: |
|
|
npm pack --json > npm-pack.json
|
|
node -e "const crypto = require('crypto'); const fs = require('fs'); const data = JSON.parse(fs.readFileSync('npm-pack.json', 'utf8')); const file = data[0]?.filename; if (!/^ecc-universal-[0-9A-Za-z.+-]+\.tgz$/.test(file || '')) throw new Error('Unexpected packed filename'); const archives = fs.readdirSync('.').filter(name => name.endsWith('.tgz')); if (archives.length !== 1 || archives[0] !== file) throw new Error('Expected exactly one packed archive'); const digest = crypto.createHash('sha256').update(fs.readFileSync(file)).digest('hex'); fs.appendFileSync(process.env.GITHUB_OUTPUT, 'package_file=' + file + '\npackage_sha256=' + digest + '\n')"
|
|
|
|
- name: Upload exact installer artifact
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: ecc-ci-installer-artifact
|
|
path: ${{ steps.pack.outputs.package_file }}
|
|
if-no-files-found: error
|
|
|
|
packed-install-lifecycle:
|
|
name: Packed Install (${{ matrix.os }})
|
|
needs: pack-installer
|
|
runs-on: ${{ matrix.os }}
|
|
timeout-minutes: 15
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
|
|
steps:
|
|
- name: Checkout lifecycle test
|
|
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- name: Setup Node.js
|
|
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
|
with:
|
|
node-version: '20.x'
|
|
|
|
- name: Download exact installer artifact
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
name: ecc-ci-installer-artifact
|
|
path: release-artifacts
|
|
|
|
- name: Verify packed install lifecycle
|
|
env:
|
|
ECC_RELEASE_PACKAGE: release-artifacts/${{ needs.pack-installer.outputs.package_file }}
|
|
ECC_RELEASE_SHA256: ${{ needs.pack-installer.outputs.package_sha256 }}
|
|
run: node tests/ci/packed-artifact-lifecycle.js
|
|
|
|
validate:
|
|
name: Validate Components
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 5
|
|
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- name: Setup Node.js
|
|
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
|
with:
|
|
node-version: '20.x'
|
|
|
|
- name: Install validation dependencies
|
|
run: npm ci --ignore-scripts
|
|
|
|
- name: Validate agents
|
|
run: node scripts/ci/validate-agents.js
|
|
continue-on-error: false
|
|
|
|
- name: Validate hooks
|
|
run: node scripts/ci/validate-hooks.js
|
|
continue-on-error: false
|
|
|
|
- name: Validate commands
|
|
run: node scripts/ci/validate-commands.js
|
|
continue-on-error: false
|
|
|
|
- name: Validate skills
|
|
run: node scripts/ci/validate-skills.js
|
|
continue-on-error: false
|
|
|
|
- name: Validate install manifests
|
|
run: node scripts/ci/validate-install-manifests.js
|
|
continue-on-error: false
|
|
|
|
- name: Validate workflow security
|
|
run: node scripts/ci/validate-workflow-security.js
|
|
continue-on-error: false
|
|
|
|
- name: Validate rules
|
|
run: node scripts/ci/validate-rules.js
|
|
continue-on-error: false
|
|
|
|
- name: Validate catalog counts
|
|
run: node scripts/ci/catalog.js --text
|
|
continue-on-error: false
|
|
|
|
- name: Validate command registry
|
|
run: npm run command-registry:check
|
|
continue-on-error: false
|
|
|
|
- name: Check unicode safety
|
|
run: node scripts/ci/check-unicode-safety.js
|
|
continue-on-error: false
|
|
|
|
- name: Validate no personal paths
|
|
run: node scripts/ci/validate-no-personal-paths.js
|
|
continue-on-error: false
|
|
|
|
python-tests:
|
|
name: Python Lint, Type Check & Test
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 10
|
|
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- name: Setup Python
|
|
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
|
with:
|
|
python-version: '3.11'
|
|
|
|
- name: Install Python dependencies
|
|
run: python -m pip install --upgrade pip && python -m pip install -e '.[dev]'
|
|
|
|
- name: Run ruff (lint)
|
|
run: python -m ruff check src tests
|
|
|
|
- name: Run mypy (type check)
|
|
run: python -m mypy src
|
|
|
|
- name: Run Python tests
|
|
run: python -m pytest tests/test_*.py -m "not integration"
|
|
|
|
security:
|
|
name: Security Scan
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 5
|
|
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- name: Setup Node.js
|
|
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
|
with:
|
|
node-version: '20.x'
|
|
|
|
- name: Install audit dependencies
|
|
run: npm ci --ignore-scripts
|
|
|
|
- name: Run npm audit
|
|
run: |
|
|
npm audit signatures
|
|
# Runtime/package advisories are release blockers. Development-only
|
|
# lint tooling remains covered by signature and IOC verification.
|
|
npm audit --omit=dev --audit-level=high
|
|
|
|
- name: Run supply-chain IOC scan
|
|
run: npm run security:ioc-scan
|
|
|
|
coverage:
|
|
name: Coverage
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 10
|
|
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- name: Setup Node.js
|
|
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
|
with:
|
|
node-version: '20.x'
|
|
|
|
- name: Install dependencies
|
|
run: npm ci --ignore-scripts
|
|
|
|
- name: Run coverage
|
|
run: npm run coverage
|
|
|
|
- name: Upload coverage report
|
|
if: always()
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: coverage-ubuntu-node20-npm
|
|
path: coverage/
|
|
|
|
lint:
|
|
name: Lint
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 5
|
|
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- name: Setup Node.js
|
|
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
|
with:
|
|
node-version: '20.x'
|
|
|
|
- name: Install dependencies
|
|
run: npm ci --ignore-scripts
|
|
|
|
- name: Run lint
|
|
run: npm run lint
|