Skip to content

fix: carry forward high court monthly metrics by active publication lineage (#307) #833

fix: carry forward high court monthly metrics by active publication lineage (#307)

fix: carry forward high court monthly metrics by active publication lineage (#307) #833

Workflow file for this run

name: CI
on:
push:
branches:
- main
- "phase-*"
- "implement-*"
pull_request:
types:
- opened
- synchronize
- reopened
permissions:
contents: read
jobs:
secret-scan:
runs-on: ubuntu-latest
env:
GITLEAKS_VERSION: 8.30.1
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
fetch-depth: 0
- name: Install gitleaks CLI
run: |
curl -fsSL \
"https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}/gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz" \
-o "$RUNNER_TEMP/gitleaks.tar.gz"
tar -xzf "$RUNNER_TEMP/gitleaks.tar.gz" -C "$RUNNER_TEMP"
chmod +x "$RUNNER_TEMP/gitleaks"
- name: Scan for committed secrets
run: |
"$RUNNER_TEMP/gitleaks" git . \
--config .gitleaks.toml \
--no-banner \
--redact
verify:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
- name: Set up Node.js
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e
with:
node-version: 22
cache: npm
- name: Install dependencies
run: npm install
- name: Install Rollup Linux binary
run: npm install --no-save @rollup/rollup-linux-x64-gnu
- name: Install Playwright Chromium
run: npx playwright install --with-deps chromium
- name: Typecheck
run: npm run typecheck
- name: Unit and integration tests
run: npm test
- name: Start local persistent stack
run: npm run docker:up
- name: Persistent stack replay and rollback tests
run: npm run test:persistent
env:
RUN_PERSISTENT_STACK_TESTS: "1"
DATABASE_URL: postgres://postgres:postgres@127.0.0.1:5432/postgres
AWS_REGION: ap-south-1
AWS_ENDPOINT_URL_S3: http://127.0.0.1:4566
AWS_S3_FORCE_PATH_STYLE: "true"
AWS_ACCESS_KEY_ID: test
AWS_SECRET_ACCESS_KEY: test
OPERATOR_API_TOKEN: operator-test-token
- name: Browser E2E tests
run: npm run test:e2e
- name: Install Lighthouse CI
run: npm install --no-save @lhci/cli
- name: Start E2E server for Lighthouse
run: |
NODE_ENV=test E2E_PORT=4211 npx tsx tests/e2e/test-server.ts &
echo $! > /tmp/lhci-server.pid
for i in $(seq 1 30); do curl -sf http://127.0.0.1:4211/health && break || sleep 1; done
env:
DATABASE_URL: postgres://postgres:postgres@127.0.0.1:5432/postgres
AWS_REGION: ap-south-1
AWS_ENDPOINT_URL_S3: http://127.0.0.1:4566
AWS_S3_FORCE_PATH_STYLE: "true"
AWS_ACCESS_KEY_ID: test
AWS_SECRET_ACCESS_KEY: test
OPERATOR_API_TOKEN: operator-test-token
- name: Run Lighthouse CI
run: npx lhci autorun --config=.lighthouserc.cjs || echo "Lighthouse warnings present — not blocking"
- name: Stop E2E server
if: always()
run: |
if [ -f /tmp/lhci-server.pid ]; then
kill "$(cat /tmp/lhci-server.pid)" 2>/dev/null || true
fi
deploy:
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
needs:
- secret-scan
- verify
runs-on: ubuntu-latest
concurrency:
group: deploy-main
cancel-in-progress: false
permissions:
contents: read
id-token: write
env:
AWS_REGION: ap-south-1
AWS_ACCOUNT_ID: "723951822728"
ECR_REPOSITORY: nyaaywatch-staging
PRODUCTION_STACK_NAME: nyaaywatch-production
STATE_INTERNAL_FETCH_SCHEDULE_EXPRESSION: "cron(0 8 * * ? *)"
STATE_INTERNAL_FETCH_SCHEDULE_TIMEZONE: Asia/Kolkata
STATE_INTERNAL_FETCH_SCHEDULE_STATE: ENABLED
SUPREME_COURT_INTERNAL_FETCH_SCHEDULE_EXPRESSION: "cron(10 8 * * ? *)"
SUPREME_COURT_INTERNAL_FETCH_SCHEDULE_TIMEZONE: Asia/Kolkata
SUPREME_COURT_INTERNAL_FETCH_SCHEDULE_STATE: ENABLED
HIGH_COURT_INTERNAL_FETCH_SCHEDULE_EXPRESSION: "cron(20 8 * * ? *)"
HIGH_COURT_INTERNAL_FETCH_SCHEDULE_TIMEZONE: Asia/Kolkata
HIGH_COURT_INTERNAL_FETCH_SCHEDULE_STATE: ENABLED
INTERNAL_FETCH_MANAGE_IAM: never
INTERNAL_FETCH_SCHEDULER_ROLE_ARN: arn:aws:iam::723951822728:role/nyaaywatch-production-internal-fetch-scheduler
PUBLIC_BASE_URL: https://nyaaywatch.in
CLOUDFLARE_ZONE_NAME: nyaaywatch.in
CLOUDFLARE_API_TOKEN_SECRET_ARN: ${{ secrets.CLOUDFLARE_API_TOKEN_SECRET_ARN }}
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@d979d5b3a71173a29b74b5b88418bfda9437d885
with:
aws-region: ${{ env.AWS_REGION }}
role-to-assume: arn:aws:iam::723951822728:role/nyaaywatch-github-deploy-role
- name: Build and push deployment images
env:
IMAGE_SHA: ${{ env.AWS_ACCOUNT_ID }}.dkr.ecr.${{ env.AWS_REGION }}.amazonaws.com/${{ env.ECR_REPOSITORY }}:${{ github.sha }}
IMAGE_LATEST: ${{ env.AWS_ACCOUNT_ID }}.dkr.ecr.${{ env.AWS_REGION }}.amazonaws.com/${{ env.ECR_REPOSITORY }}:latest
run: |
chmod +x infra/aws/staging/build-and-push.sh
./infra/aws/staging/build-and-push.sh "$IMAGE_SHA" "$IMAGE_LATEST"
- name: Roll ECS service to the new image
env:
IMAGE_SHA: ${{ env.AWS_ACCOUNT_ID }}.dkr.ecr.${{ env.AWS_REGION }}.amazonaws.com/${{ env.ECR_REPOSITORY }}:${{ github.sha }}
run: |
chmod +x infra/aws/staging/redeploy-service.sh
./infra/aws/staging/redeploy-service.sh "$PRODUCTION_STACK_NAME" "$IMAGE_SHA"
- name: Reconcile daily internal fetch schedule
run: |
chmod +x infra/aws/staging/reconcile-internal-fetch-schedule.sh
./infra/aws/staging/reconcile-internal-fetch-schedule.sh "$PRODUCTION_STACK_NAME"
preview:
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository
needs:
- secret-scan
runs-on: ubuntu-latest
concurrency:
group: preview-pr-${{ github.event.pull_request.number }}
cancel-in-progress: true
permissions:
contents: read
pull-requests: write
id-token: write
env:
AWS_REGION: ap-south-1
AWS_ACCOUNT_ID: "723951822728"
ECR_REPOSITORY: nyaaywatch-staging
PREVIEW_SERVICE_NAME: nyaaywatch-pr-${{ github.event.pull_request.number }}
APP_RUNNER_ACCESS_ROLE_ARN: arn:aws:iam::723951822728:role/nyaaywatch-apprunner-ecr-access-role
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@d979d5b3a71173a29b74b5b88418bfda9437d885
with:
aws-region: ${{ env.AWS_REGION }}
role-to-assume: arn:aws:iam::723951822728:role/nyaaywatch-github-preview-role
- name: Compute active preview allowlist
id: preview-allowlist
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const fs = require("fs");
const path = `${process.env.RUNNER_TEMP}/open-preview-services.txt`;
const pulls = await github.paginate(github.rest.pulls.list, {
owner: context.repo.owner,
repo: context.repo.repo,
state: "open",
per_page: 100,
});
const lines = pulls.map((pull) => `nyaaywatch-pr-${pull.number}`);
fs.writeFileSync(path, lines.join("\n") + (lines.length > 0 ? "\n" : ""));
core.setOutput("path", path);
- name: Reconcile stale preview services
run: |
chmod +x infra/aws/preview/reconcile-services.sh infra/aws/preview/delete-service.sh
./infra/aws/preview/reconcile-services.sh "${{ steps.preview-allowlist.outputs.path }}"
- name: Build and push preview image
env:
IMAGE_SHA: ${{ env.AWS_ACCOUNT_ID }}.dkr.ecr.${{ env.AWS_REGION }}.amazonaws.com/${{ env.ECR_REPOSITORY }}:pr-${{ github.event.pull_request.number }}-${{ github.sha }}
run: |
chmod +x infra/aws/staging/build-and-push.sh
./infra/aws/staging/build-and-push.sh "$IMAGE_SHA"
- name: Deploy preview service
id: preview
env:
IMAGE_SHA: ${{ env.AWS_ACCOUNT_ID }}.dkr.ecr.${{ env.AWS_REGION }}.amazonaws.com/${{ env.ECR_REPOSITORY }}:pr-${{ github.event.pull_request.number }}-${{ github.sha }}
run: |
chmod +x infra/aws/preview/reconcile-services.sh infra/aws/preview/delete-service.sh infra/aws/preview/deploy-service.sh
deploy_once() {
local stderr_file="$1"
set +e
preview_url="$(./infra/aws/preview/deploy-service.sh "$PREVIEW_SERVICE_NAME" "$IMAGE_SHA" "$APP_RUNNER_ACCESS_ROLE_ARN" 2>"$stderr_file")"
status=$?
set -e
return "$status"
}
final_status=""
final_url=""
if deploy_once preview-stderr.log; then
final_status="ready"
final_url="$preview_url"
else
cat preview-stderr.log >&2
if grep -q 'ServiceQuotaExceededException' preview-stderr.log; then
./infra/aws/preview/reconcile-services.sh "${{ steps.preview-allowlist.outputs.path }}"
if deploy_once preview-retry-stderr.log; then
final_status="ready"
final_url="$preview_url"
else
cat preview-retry-stderr.log >&2
if grep -q 'ServiceQuotaExceededException' preview-retry-stderr.log; then
final_status="quota-exceeded"
final_url=""
else
exit "$status"
fi
fi
else
exit "$status"
fi
fi
echo "status=$final_status" >> "$GITHUB_OUTPUT"
echo "url=$final_url" >> "$GITHUB_OUTPUT"
- name: Comment preview URL
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3
env:
PREVIEW_URL: ${{ steps.preview.outputs.url }}
PREVIEW_STATUS: ${{ steps.preview.outputs.status }}
SERVICE_NAME: ${{ env.PREVIEW_SERVICE_NAME }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const marker = "<!-- nyaaywatch-preview -->";
const body =
process.env.PREVIEW_STATUS === "quota-exceeded"
? `${marker}
Preview unavailable: AWS App Runner preview quota is currently full, even after stale preview cleanup and one retry.
Service: \`${process.env.SERVICE_NAME}\`
Mode: fixture-backed public web preview
Status: quota exceeded after reconcile and retry`
: `${marker}
Preview ready: ${process.env.PREVIEW_URL}
Service: \`${process.env.SERVICE_NAME}\`
Mode: fixture-backed public web preview`;
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
per_page: 100,
});
const existing = comments.find((comment) => comment.body.includes(marker));
if (existing) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: existing.id,
body,
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body,
});
}