Skip to content

Merge branch 'main' into troubleshoot-deploy #119

Merge branch 'main' into troubleshoot-deploy

Merge branch 'main' into troubleshoot-deploy #119

Workflow file for this run

name: CI
on:
push:
branches: ['**']
pull_request:
branches: [main]
jobs:
# Quick smoke test to catch import errors early
import-smoke-test:
name: Import Smoke Test
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Test Python package imports
working-directory: packages/flarelette-jwt-py
run: |
echo "Testing Python package can be imported in standard Python environment..."
python -c "import flarelette_jwt; print('✓ Package version:', flarelette_jwt.__version__)"
python -c "from flarelette_jwt import sign, verify, create_token, check_auth, policy, parse; print('✓ All main functions importable')"
- name: Test version extraction (simulates CD pipeline)
run: |
echo "Simulating CD pipeline version check..."
TS_VERSION=$(node -p "require('./packages/flarelette-jwt-ts/package.json').version")
PY_VERSION=$(python -c "import sys; sys.path.insert(0, 'packages/flarelette-jwt-py'); import flarelette_jwt; print(flarelette_jwt.__version__, end='')")
echo "✓ TypeScript version: $TS_VERSION"
echo "✓ Python version: $PY_VERSION"
lint-and-format:
name: Lint and Format Check
runs-on: ubuntu-latest
needs: import-smoke-test
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
cache: 'pip'
- name: Install Node dependencies
run: npm ci
- name: Install Python dependencies
run: |
python -m pip install --upgrade pip
pip install black ruff mypy pytest pytest-cov pytest-asyncio
- name: Format check (JavaScript/TypeScript)
run: npm run format:js:check
- name: Format check (Python)
run: npm run format:py:check
- name: Lint (JavaScript/TypeScript)
run: npm run lint:js
- name: Lint (Python)
run: npm run lint:py
typecheck:
name: Type Check
runs-on: ubuntu-latest
needs: import-smoke-test
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
cache: 'pip'
- name: Install Node dependencies
run: npm ci
- name: Install Python dependencies
run: |
python -m pip install --upgrade pip
pip install mypy pytest pytest-cov pytest-asyncio
- name: Type check (TypeScript)
run: npm run typecheck:js
- name: Type check (Python)
run: npm run typecheck:py
test:
name: Test (Node ${{ matrix.node }}, Python ${{ matrix.python }})
runs-on: ubuntu-latest
strategy:
matrix:
node: [20, 22]
python: ['3.11', '3.12']
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
cache: 'npm'
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python }}
cache: 'pip'
- name: Install Node dependencies
run: npm ci
- name: Install Python dependencies
run: |
python -m pip install --upgrade pip
pip install pytest pytest-cov pytest-asyncio
- name: Build packages
run: npm run build
- name: Run tests with coverage
run: npm run test:coverage
- name: Upload TypeScript coverage to Codecov
if: matrix.node == 20 && matrix.python == '3.11'
uses: codecov/codecov-action@v4
with:
files: ./coverage/coverage-final.json
flags: typescript
name: typescript-coverage
fail_ci_if_error: false
- name: Upload Python coverage to Codecov
if: matrix.node == 20 && matrix.python == '3.11'
uses: codecov/codecov-action@v4
with:
files: ./packages/flarelette-jwt-py/.coverage
flags: python
name: python-coverage
fail_ci_if_error: false
# Additional checks for pull requests
pr-checks:
name: PR-specific Checks
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch all history for commit message validation
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Validate commit messages
run: npx commitlint --from ${{ github.event.pull_request.base.sha }} --to ${{ github.sha }} --verbose
- name: Check for breaking changes
run: |
echo "Checking for breaking changes in commit messages..."
git log --format=%B ${{ github.event.pull_request.base.sha }}..${{ github.sha }} | grep -i "BREAKING CHANGE" && echo "⚠️ Breaking changes detected" || echo "✓ No breaking changes"
# Security and dependency checks
security:
name: Security Checks
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run npm audit
run: npm audit --audit-level=moderate
continue-on-error: true
- name: Check for known vulnerabilities
run: npm audit --audit-level=high
continue-on-error: false
# Build verification
build:
name: Build Verification
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install Node dependencies
run: npm ci
- name: Install Python build tools
run: |
python -m pip install --upgrade pip
pip install build twine
- name: Build TypeScript packages
run: npm run build
- name: Build Python package
working-directory: packages/flarelette-jwt-py
run: python -m build
- name: Check Python package
working-directory: packages/flarelette-jwt-py
run: twine check dist/*
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: build-artifacts
path: |
packages/*/dist
packages/*/build
retention-days: 7
# Package installation tests
package-install:
name: Package Installation Tests
runs-on: ubuntu-latest
needs: build
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install Node dependencies
run: npm ci
- name: Install Python build tools
run: |
python -m pip install --upgrade pip
pip install build
- name: Build packages
run: |
npm run build
cd packages/flarelette-jwt-py && python prepare.py && python -m build
- name: Test TypeScript package installation (from tarball)
run: |
cd packages/flarelette-jwt-ts
npm pack
TARBALL=$(ls *.tgz)
cd /tmp
npm init -y
npm install "$GITHUB_WORKSPACE/packages/flarelette-jwt-ts/$TARBALL"
node -e "const jwt = require('@chrislyons-dev/flarelette-jwt'); console.log('✓ TypeScript package imports successfully');"
- name: Test Python package installation (from wheel)
run: |
cd /tmp
python -m venv test-env
source test-env/bin/activate
pip install $GITHUB_WORKSPACE/packages/flarelette-jwt-py/dist/*.whl
# Test that package imports successfully (lazy-loaded 'js' module only needed at function call time)
python -c "import flarelette_jwt; print('✓ Python package version:', flarelette_jwt.__version__)"
python -c "from flarelette_jwt import sign, verify, create_token, check_auth, policy, parse; print('✓ All functions importable (js module lazy-loaded at runtime)')"
deactivate
- name: Test TypeScript ESM imports
run: |
cd /tmp
mkdir esm-test && cd esm-test
npm init -y
npm pkg set type="module"
npm install "$GITHUB_WORKSPACE/packages/flarelette-jwt-ts"/*.tgz
node -e "import('@chrislyons-dev/flarelette-jwt').then(m => console.log('✓ ESM imports work'));"
# License compliance checks
license-check:
name: License Compliance
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Check TypeScript dependencies licenses
run: npm run licenses:generate
- name: Verify no GPL/AGPL dependencies
run: |
echo "Checking for incompatible licenses..."
if npm run licenses:generate | grep -iE "(GPL|AGPL)" | grep -vE "(LGPL|Unlicense)"; then
echo "❌ Found GPL/AGPL licensed dependencies"
exit 1
else
echo "✓ No GPL/AGPL dependencies found"
fi
# All checks must pass
all-checks:
name: All Checks Passed
runs-on: ubuntu-latest
needs:
[
import-smoke-test,
lint-and-format,
typecheck,
test,
security,
build,
package-install,
license-check,
]
if: always()
steps:
- name: Check all jobs
run: |
if [[ "${{ needs.import-smoke-test.result }}" != "success" ]] || \
[[ "${{ needs.lint-and-format.result }}" != "success" ]] || \
[[ "${{ needs.typecheck.result }}" != "success" ]] || \
[[ "${{ needs.test.result }}" != "success" ]] || \
[[ "${{ needs.security.result }}" != "success" ]] || \
[[ "${{ needs.build.result }}" != "success" ]] || \
[[ "${{ needs.package-install.result }}" != "success" ]] || \
[[ "${{ needs.license-check.result }}" != "success" ]]; then
echo "❌ One or more checks failed"
exit 1
else
echo "✅ All checks passed"
fi