Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: false

permissions:
contents: read

defaults:
run:
shell: pwsh
Expand Down
60 changes: 60 additions & 0 deletions .github/workflows/copyright-headers.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: Copyright Headers

on:
pull_request:
paths:
- 'docs/docusaurus/src/**'
- '.github/workflows/copyright-headers.yml'
workflow_call:
inputs:
soft-fail:
description: 'Whether to continue on copyright header violations'
required: false
type: boolean
default: false

permissions:
contents: read

jobs:
copyright-headers:
name: Copyright Header Validation
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
fetch-depth: 0

- name: Validate copyright headers
id: validate
shell: bash
run: |
MISSING=0
HEADER_PATTERN="Copyright (c) Microsoft Corporation"

echo "Checking copyright headers in docs/docusaurus/src/..."
while IFS= read -r -d '' file; do
if ! head -5 "$file" | grep -q "$HEADER_PATTERN"; then
echo "::warning file=${file}::Missing copyright header: ${file}"
MISSING=$((MISSING + 1))
fi
done < <(find docs/docusaurus/src -type f \( -name '*.ts' -o -name '*.tsx' -o -name '*.js' -o -name '*.jsx' -o -name '*.css' \) -print0)

echo "Files missing headers: $MISSING"
if [ "$MISSING" -gt 0 ]; then
echo "COPYRIGHT_FAILED=true" >> "$GITHUB_ENV"
fi
continue-on-error: ${{ inputs.soft-fail }}

- name: Check results
if: ${{ !inputs.soft-fail }}
shell: bash
run: |
if [ "$COPYRIGHT_FAILED" = "true" ]; then
echo "::error::Copyright header validation found violations"
exit 1
fi
82 changes: 82 additions & 0 deletions .github/workflows/deploy-docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Docusaurus documentation site deployment
# Prerequisite: Enable GitHub Pages in repo Settings > Pages > Source: GitHub Actions
# and allow the target branch in Settings > Environments > github-pages > Deployment branches

name: Deploy Documentation Site

on:
push:
branches:
- main
paths:
- 'docs/**'
- '.github/workflows/deploy-docs.yml'
workflow_dispatch:

concurrency:
group: pages-deploy-${{ github.ref }}
cancel-in-progress: false

permissions:
contents: read

jobs:
test:
name: Docusaurus Tests
uses: ./.github/workflows/docusaurus-tests.yml
permissions:
contents: read
with:
soft-fail: false

build:
name: Build Docusaurus
needs: test
runs-on: ubuntu-latest
permissions:
contents: read
pages: write
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
fetch-depth: 0

- name: Setup Node.js
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: 20
cache: npm
cache-dependency-path: docs/docusaurus/package-lock.json

- name: Install dependencies
working-directory: docs/docusaurus
run: npm ci

- name: Build site
working-directory: docs/docusaurus
run: npm run build

- name: Configure Pages
uses: actions/configure-pages@983d7736d9b0ae728b81ab479565c72886d7745b # v5.0.0

- name: Upload artifact
uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3.0.1
with:
path: docs/docusaurus/build

deploy:
name: Deploy to GitHub Pages
needs: build
runs-on: ubuntu-latest
permissions:
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4.0.5
58 changes: 58 additions & 0 deletions .github/workflows/docusaurus-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: Docusaurus Tests

on:
pull_request:
paths:
- 'docs/docusaurus/**'
- '.github/workflows/docusaurus-tests.yml'
workflow_call:
inputs:
soft-fail:
description: 'Whether to continue on test failures'
required: false
type: boolean
default: false

permissions:
contents: read

jobs:
docusaurus:
name: Docusaurus Unit Tests
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false

- name: Setup Node.js
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: '20'
cache: npm
cache-dependency-path: docs/docusaurus/package-lock.json

- name: Install dependencies
working-directory: docs/docusaurus
run: npm ci

- name: Run tests
working-directory: docs/docusaurus
run: npm test
continue-on-error: ${{ inputs.soft-fail }}

- name: Build verification
working-directory: docs/docusaurus
run: npm run build

- name: Upload test results
if: always()
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: docusaurus-test-results
path: docs/docusaurus/test-results/
retention-days: 30
if-no-files-found: ignore
129 changes: 129 additions & 0 deletions .github/workflows/gitleaks-scan.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
name: Gitleaks Secret Scan

on:
pull_request:
push:
branches:
- main
workflow_call:
inputs:
soft-fail:
description: 'Whether to continue on secret detection'
required: false
type: boolean
default: false

permissions:
contents: read

jobs:
scan:
name: Gitleaks Secret Scan
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
fetch-depth: 0

- name: Download and verify gitleaks
shell: bash
run: |
set -euo pipefail

GITLEAKS_VERSION="8.30.0"
GITLEAKS_SHA256="79a3ab579b53f71efd634f3aaf7e04a0fa0cf206b7ed434638d1547a2470a66e"
GITLEAKS_URL="https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}/gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz"
GITLEAKS_TARBALL="gitleaks.tar.gz"

echo "Downloading gitleaks v${GITLEAKS_VERSION}..."
curl -fsSL -o "${GITLEAKS_TARBALL}" "${GITLEAKS_URL}"

echo "Verifying SHA256 checksum..."
echo "${GITLEAKS_SHA256} ${GITLEAKS_TARBALL}" | sha256sum -c -

echo "Extracting gitleaks binary..."
tar -xzf "${GITLEAKS_TARBALL}" gitleaks
chmod +x gitleaks

echo "Gitleaks version:"
./gitleaks version

- name: Run gitleaks scan
id: gitleaks
shell: bash
run: |
set -euo pipefail

mkdir -p logs

SCAN_ARGS=(
"git"
"--report-format" "sarif"
"--report-path" "logs/gitleaks-results.sarif"
"--redact"
"--log-level" "info"
)

if [ -f ".gitleaksignore" ]; then
echo "Found .gitleaksignore — known secrets will be suppressed."
fi

echo "Running gitleaks scan..."
EXIT_CODE=0
./gitleaks "${SCAN_ARGS[@]}" || EXIT_CODE=$?

if [ "$EXIT_CODE" -eq 0 ]; then
echo "No secrets detected."
echo "leaks-found=false" >> "$GITHUB_OUTPUT"
elif [ "$EXIT_CODE" -eq 1 ]; then
echo "::warning::Gitleaks detected secrets in the repository."
echo "leaks-found=true" >> "$GITHUB_OUTPUT"
if [ "${{ inputs.soft-fail }}" != "true" ]; then
echo "::error::Secret scanning failed. Review detected secrets in logs/gitleaks-results.sarif"
exit 1
fi
else
echo "::error::Gitleaks encountered an unexpected error (exit code: $EXIT_CODE)"
exit "$EXIT_CODE"
fi

- name: Upload SARIF to Security tab
if: always()
uses: github/codeql-action/upload-sarif@0d579ffd059c29b07949a3cce3983f0780820c98 # v4.32.6
with:
sarif_file: logs/gitleaks-results.sarif
category: gitleaks
continue-on-error: true

- name: Upload scan results
if: always()
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: gitleaks-results
path: logs/gitleaks-results.sarif
retention-days: 90

- name: Add job summary
if: always()
shell: bash
run: |
LEAKS_FOUND="${{ steps.gitleaks.outputs.leaks-found }}"
if [ "$LEAKS_FOUND" = "true" ]; then
STATUS="⚠️ Secrets Detected"
else
STATUS="✅ No Secrets Found"
fi

cat >> "$GITHUB_STEP_SUMMARY" <<EOF
## Gitleaks Secret Scan Results

| Metric | Value |
|--------|-------|
| Status | $STATUS |

EOF
Loading
Loading