Skip to content

fix(ios): disable optional beauty pods in public CI #11

fix(ios): disable optional beauty pods in public CI

fix(ios): disable optional beauty pods in public CI #11

name: Repository Policy
on:
push:
branches:
- main
- 'dev/**'
pull_request:
permissions:
contents: read
concurrency:
group: repository-policy-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
gitleaks:
name: Sensitive information
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Resolve commits to scan
id: commits
env:
EVENT_NAME: ${{ github.event_name }}
BEFORE_SHA: ${{ github.event.before }}
DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
PR_BASE_SHA: ${{ github.event.pull_request.base.sha }}
PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
PUSH_HEAD_SHA: ${{ github.sha }}
run: |
set -euo pipefail
if [[ "$EVENT_NAME" == "pull_request" ]]; then
base_sha="$PR_BASE_SHA"
head_sha="$PR_HEAD_SHA"
else
base_sha="$BEFORE_SHA"
head_sha="$PUSH_HEAD_SHA"
fi
if [[ ! "$head_sha" =~ ^[0-9a-f]{40}$ ]]; then
echo "Invalid head commit: $head_sha" >&2
exit 1
fi
git cat-file -e "${head_sha}^{commit}"
zero_sha="0000000000000000000000000000000000000000"
if [[ "$base_sha" == "$zero_sha" || ! "$base_sha" =~ ^[0-9a-f]{40}$ ]] || ! git cat-file -e "${base_sha}^{commit}" 2>/dev/null; then
git fetch --no-tags origin "+refs/heads/$DEFAULT_BRANCH:refs/remotes/origin/$DEFAULT_BRANCH"
base_sha="$(git merge-base "$head_sha" "refs/remotes/origin/$DEFAULT_BRANCH" || true)"
fi
if [[ -n "$base_sha" ]]; then
revision="$base_sha..$head_sha"
else
revision="$head_sha"
fi
echo "revision=$revision" >> "$GITHUB_OUTPUT"
- name: Scan commits with Gitleaks
uses: docker://ghcr.io/gitleaks/gitleaks@sha256:c00b6bd0aeb3071cbcb79009cb16a60dd9e0a7c60e2be9ab65d25e6bc8abbb7f
with:
args: git --redact --verbose --config=.gitleaks.toml --log-opts=${{ steps.commits.outputs.revision }} .
- name: Create Gitleaks regression fixtures
run: |
set -euo pipefail
mkdir -p .gitleaks-fixtures/positive .gitleaks-fixtures/negative
sample_id="0123456789abcdef"
sample_id="${sample_id}fedcba9876543210"
zero_id="0000000000000000"
zero_id="${zero_id}${zero_id}"
printf 'static let AppId: String = "%s"\n' "$sample_id" > .gitleaks-fixtures/positive/swift-app-id.swift
printf 'static NSString * const APPID = @"%s";\n' "$sample_id" > .gitleaks-fixtures/positive/objc-app-id.m
printf 'static NSString * const Certificate = @"%s";\n' "$sample_id" > .gitleaks-fixtures/positive/objc-certificate.m
printf '#define APP_ID "%s"\n' "$sample_id" > .gitleaks-fixtures/positive/windows-app-id.h
printf 'AGORA_APP_CERT=%s\n' "$sample_id" > .gitleaks-fixtures/positive/android-certificate.properties
printf 'static let AppId: String = "%s"\n' "$zero_id" > .gitleaks-fixtures/negative/zero-app-id.swift
- name: Scan representative credential formats
id: credential-formats
continue-on-error: true
uses: docker://ghcr.io/gitleaks/gitleaks@sha256:c00b6bd0aeb3071cbcb79009cb16a60dd9e0a7c60e2be9ab65d25e6bc8abbb7f
with:
args: dir --no-banner --redact --config=.gitleaks.toml --report-format=json --report-path=.gitleaks-positive.json .gitleaks-fixtures/positive
- name: Verify representative credentials were detected
env:
SCAN_OUTCOME: ${{ steps.credential-formats.outcome }}
run: |
python3 - <<'PY'
import json
import os
import sys
from pathlib import Path
expected = {
"swift-app-id.swift",
"objc-app-id.m",
"objc-certificate.m",
"windows-app-id.h",
"android-certificate.properties",
}
report_path = Path(".gitleaks-positive.json")
findings = json.loads(report_path.read_text()) if report_path.exists() else []
detected = {Path(item["File"]).name for item in findings}
missing = expected - detected
if os.environ["SCAN_OUTCOME"] != "failure" or missing:
print(f"Gitleaks regression failed; missing detections: {sorted(missing)}", file=sys.stderr)
raise SystemExit(1)
PY
- name: Verify placeholder App ID is allowed
uses: docker://ghcr.io/gitleaks/gitleaks@sha256:c00b6bd0aeb3071cbcb79009cb16a60dd9e0a7c60e2be9ab65d25e6bc8abbb7f
with:
args: dir --no-banner --redact --config=.gitleaks.toml .gitleaks-fixtures/negative
commit-messages:
name: Commit messages
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Resolve and validate commit messages
env:
EVENT_NAME: ${{ github.event_name }}
BEFORE_SHA: ${{ github.event.before }}
DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
PR_BASE_SHA: ${{ github.event.pull_request.base.sha }}
PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
PUSH_HEAD_SHA: ${{ github.sha }}
run: |
set -euo pipefail
if [[ "$EVENT_NAME" == "pull_request" ]]; then
base_sha="$PR_BASE_SHA"
head_sha="$PR_HEAD_SHA"
else
base_sha="$BEFORE_SHA"
head_sha="$PUSH_HEAD_SHA"
fi
if [[ ! "$head_sha" =~ ^[0-9a-f]{40}$ ]]; then
echo "Invalid head commit: $head_sha" >&2
exit 1
fi
git cat-file -e "${head_sha}^{commit}"
zero_sha="0000000000000000000000000000000000000000"
if [[ "$base_sha" == "$zero_sha" || ! "$base_sha" =~ ^[0-9a-f]{40}$ ]] || ! git cat-file -e "${base_sha}^{commit}" 2>/dev/null; then
git fetch --no-tags origin "+refs/heads/$DEFAULT_BRANCH:refs/remotes/origin/$DEFAULT_BRANCH"
base_sha="$(git merge-base "$head_sha" "refs/remotes/origin/$DEFAULT_BRANCH" || true)"
fi
if [[ -n "$base_sha" ]]; then
revision="$base_sha..$head_sha"
else
revision="$head_sha"
fi
message_file="$RUNNER_TEMP/commit-message.txt"
failed=0
while IFS= read -r commit_sha; do
git show -s --format=%B "$commit_sha" > "$message_file"
if ! .git-hooks/check-commit-message.sh "$message_file"; then
echo "Commit $commit_sha has an invalid message." >&2
failed=1
fi
done < <(git rev-list --reverse "$revision")
exit "$failed"
ai-assets:
name: AI asset integrity
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: pip
cache-dependency-path: .github/ci/policy/requirements.txt
- name: Install AI asset validation dependencies
run: python3 -m pip install --requirement .github/ci/policy/requirements.txt
- name: Test AI asset validator
run: python3 -m unittest discover --start-directory .github/ci/policy/tests --pattern 'test_validate_ai_assets.py'
- name: Validate AI assets
run: python3 .github/ci/policy/validate_ai_assets.py
template-lifecycle:
name: Template lifecycle (${{ matrix.check }})
runs-on: ${{ matrix.runner }}
timeout-minutes: 10
strategy:
fail-fast: false
matrix:
include:
- check: apple
runner: macos-14
- check: kotlin
runner: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
if: matrix.check == 'kotlin'
with:
distribution: temurin
java-version: "17"
- name: Compile and exercise template lifecycles
env:
TEMPLATE_CHECK: ${{ matrix.check }}
run: python3 .github/ci/policy/check_templates.py "$TEMPLATE_CHECK"