From 0aeec6b566738ff332e0afa8796b11f8c48ff402 Mon Sep 17 00:00:00 2001 From: Kurdistan Tech Ministry Date: Thu, 19 Feb 2026 05:56:31 +0300 Subject: [PATCH] ci: add Code Quality and Security workflows (Python lint, JSON validation, chain integrity, secret scan) --- .github/workflows/code-quality.yml | 145 +++++++++++++++++++++++++++++ .github/workflows/codeql.yml | 99 -------------------- .github/workflows/security.yml | 93 ++++++++++++++++++ 3 files changed, 238 insertions(+), 99 deletions(-) create mode 100644 .github/workflows/code-quality.yml delete mode 100644 .github/workflows/codeql.yml create mode 100644 .github/workflows/security.yml diff --git a/.github/workflows/code-quality.yml b/.github/workflows/code-quality.yml new file mode 100644 index 0000000..bfe92e5 --- /dev/null +++ b/.github/workflows/code-quality.yml @@ -0,0 +1,145 @@ +name: Code Quality + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + python-lint: + name: Python Lint + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.12' + + - name: Install ruff + run: pip install ruff + + - name: Run ruff linter + run: ruff check scripts/ + continue-on-error: true + + - name: Run ruff formatter check + run: ruff format --check scripts/ + continue-on-error: true + + json-validation: + name: JSON Validation + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + submodules: true + + - name: Validate JSON files + run: | + ERRORS=0 + echo "Validating chain config JSON files..." + + for f in chains/v22/android/chains.json chains/v22/chains.json chains/v22/chains_dev.json pezkuwi-overlay/chains/pezkuwi-chains.json; do + if [ -f "$f" ]; then + if python3 -m json.tool "$f" > /dev/null 2>&1; then + echo " $f: valid" + else + echo "::error file=$f::Invalid JSON: $f" + ERRORS=$((ERRORS + 1)) + fi + fi + done + + exit $ERRORS + + chain-integrity: + name: Chain Config Integrity + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + submodules: true + + - name: Verify Pezkuwi chains are present + run: | + CHAINS_FILE="chains/v22/android/chains.json" + if [ ! -f "$CHAINS_FILE" ]; then + echo "::error::$CHAINS_FILE not found" + exit 1 + fi + + ERRORS=0 + + # Pezkuwi Relay + if ! python3 -c "import json; chains=json.load(open('$CHAINS_FILE')); assert any(c['chainId'].startswith('1aa94987') for c in chains), 'Missing Pezkuwi Relay'"; then + echo "::error::Pezkuwi Relay chain missing from $CHAINS_FILE" + ERRORS=$((ERRORS + 1)) + else + echo "Pezkuwi Relay: present" + fi + + # Pezkuwi Asset Hub + if ! python3 -c "import json; chains=json.load(open('$CHAINS_FILE')); assert any(c['chainId'].startswith('e7c15092') for c in chains), 'Missing Asset Hub'"; then + echo "::error::Pezkuwi Asset Hub missing from $CHAINS_FILE" + ERRORS=$((ERRORS + 1)) + else + echo "Pezkuwi Asset Hub: present" + fi + + # Pezkuwi People + if ! python3 -c "import json; chains=json.load(open('$CHAINS_FILE')); assert any(c['chainId'].startswith('69a8d025') for c in chains), 'Missing People Chain'"; then + echo "::error::Pezkuwi People chain missing from $CHAINS_FILE" + ERRORS=$((ERRORS + 1)) + else + echo "Pezkuwi People: present" + fi + + # Verify Pezkuwi chains are first in array + FIRST_CHAIN=$(python3 -c "import json; print(json.load(open('$CHAINS_FILE'))[0]['chainId'][:8])") + if [ "$FIRST_CHAIN" != "1aa94987" ]; then + echo "::warning::Pezkuwi Relay is not the first chain (found: $FIRST_CHAIN)" + else + echo "Pezkuwi Relay is first chain: OK" + fi + + exit $ERRORS + + sync-script-test: + name: Sync Script Dry Run + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + submodules: true + + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.12' + + - name: Run sync script + run: python3 scripts/sync_from_nova.py + + - name: Verify output was generated + run: | + if [ ! -f "chains/v22/android/chains.json" ]; then + echo "::error::Sync script failed to generate chains/v22/android/chains.json" + exit 1 + fi + COUNT=$(python3 -c "import json; print(len(json.load(open('chains/v22/android/chains.json'))))") + echo "Generated $COUNT chains" + if [ "$COUNT" -lt 4 ]; then + echo "::error::Expected at least 4 chains, got $COUNT" + exit 1 + fi diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml deleted file mode 100644 index 9ed29c2..0000000 --- a/.github/workflows/codeql.yml +++ /dev/null @@ -1,99 +0,0 @@ -# For most projects, this workflow file will not need changing; you simply need -# to commit it to your repository. -# -# You may wish to alter this file to override the set of languages analyzed, -# or to provide custom queries or build logic. -# -# ******** NOTE ******** -# We have attempted to detect the languages in your repository. Please check -# the `language` matrix defined below to confirm you have the correct set of -# supported CodeQL languages. -# -name: "CodeQL Advanced" - -on: - push: - branches: [ "main" ] - pull_request: - branches: [ "main" ] - schedule: - - cron: '33 7 * * 4' - -jobs: - analyze: - name: Analyze (${{ matrix.language }}) - # Runner size impacts CodeQL analysis time. To learn more, please see: - # - https://gh.io/recommended-hardware-resources-for-running-codeql - # - https://gh.io/supported-runners-and-hardware-resources - # - https://gh.io/using-larger-runners (GitHub.com only) - # Consider using larger runners or machines with greater resources for possible analysis time improvements. - runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }} - permissions: - # required for all workflows - security-events: write - - # required to fetch internal or private CodeQL packs - packages: read - - # only required for workflows in private repositories - actions: read - contents: read - - strategy: - fail-fast: false - matrix: - include: - - language: python - build-mode: none - # CodeQL supports the following values keywords for 'language': 'actions', 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'rust', 'swift' - # Use `c-cpp` to analyze code written in C, C++ or both - # Use 'java-kotlin' to analyze code written in Java, Kotlin or both - # Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both - # To learn more about changing the languages that are analyzed or customizing the build mode for your analysis, - # see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning. - # If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how - # your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - # Add any setup steps before running the `github/codeql-action/init` action. - # This includes steps like installing compilers or runtimes (`actions/setup-node` - # or others). This is typically only required for manual builds. - # - name: Setup runtime (example) - # uses: actions/setup-example@v1 - - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v4 - with: - languages: ${{ matrix.language }} - build-mode: ${{ matrix.build-mode }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - - # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs - # queries: security-extended,security-and-quality - - # If the analyze step fails for one of the languages you are analyzing with - # "We were unable to automatically build your code", modify the matrix above - # to set the build mode to "manual" for that language. Then modify this step - # to build your code. - # â„šī¸ Command-line programs to run using the OS shell. - # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun - - name: Run manual build steps - if: matrix.build-mode == 'manual' - shell: bash - run: | - echo 'If you are using a "manual" build mode for one or more of the' \ - 'languages you are analyzing, replace this with the commands to build' \ - 'your code, for example:' - echo ' make bootstrap' - echo ' make release' - exit 1 - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v4 - with: - category: "/language:${{matrix.language}}" diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml new file mode 100644 index 0000000..43b1eb7 --- /dev/null +++ b/.github/workflows/security.yml @@ -0,0 +1,93 @@ +name: Security + +on: + push: + branches: [main] + pull_request: + branches: [main] + schedule: + - cron: '0 6 * * 1' + +permissions: + contents: read + security-events: write + +jobs: + codeql: + name: CodeQL Analysis + runs-on: ubuntu-latest + continue-on-error: true + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: python + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 + + secret-scan: + name: Secret Scan + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: TruffleHog Secret Scan + uses: trufflesecurity/trufflehog@main + with: + path: ./ + base: ${{ github.event.repository.default_branch }} + extra_args: --only-verified + + hardcoded-secrets: + name: Hardcoded Secret Detection + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Scan for hardcoded secrets + run: | + FOUND=0 + + echo "Checking for private keys in config files..." + if grep -rn --include="*.json" --include="*.py" -E "(0x[a-fA-F0-9]{64}|-----BEGIN.*PRIVATE)" . | grep -v node_modules | grep -v "chainId\|genesisHash\|parentId"; then + echo "::error::Possible private key found" + FOUND=1 + fi + + echo "Checking for hardcoded credentials..." + if grep -rn --include="*.py" --include="*.json" -iE "(password|secret_key|api_key)\s*[:=]\s*['\"][^'\"]{8,}" . | grep -v node_modules; then + echo "::error::Possible hardcoded credential found" + FOUND=1 + fi + + if [ "$FOUND" -eq 0 ]; then + echo "No hardcoded secrets found." + else + exit 1 + fi + + dependency-review: + name: Dependency Review + runs-on: ubuntu-latest + if: github.event_name == 'pull_request' + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Dependency Review + uses: actions/dependency-review-action@v4 + with: + fail-on-severity: high + deny-licenses: GPL-3.0, AGPL-3.0