From 0655f7b5a0e78c7948dbe28ab7a0c21520c873e3 Mon Sep 17 00:00:00 2001 From: Jatin Pandey Date: Sun, 8 Nov 2026 14:32:02 +0530 Subject: [PATCH 1/3] Establish organization automation and contribution defaults --- .github/ISSUE_TEMPLATE/bug_report.yml | 31 ++++++++++++++ .github/ISSUE_TEMPLATE/config.yml | 5 +++ .github/dependabot.yml | 14 +++++++ .github/pull_request_template.md | 11 +++++ .github/workflows/ci.yml | 36 ++++++++++++++++ .github/workflows/codeql.yml | 35 ++++++++++++++++ .github/workflows/pr-policy.yml | 59 +++++++++++++++++++++++++++ .mergify.yml | 21 ++++++++++ CONTRIBUTING.md | 9 ++++ README.md | 6 +++ SECURITY.md | 7 ++++ docs/automation.md | 52 +++++++++++++++++++++++ 12 files changed, 286 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yml create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 .github/dependabot.yml create mode 100644 .github/pull_request_template.md create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/codeql.yml create mode 100644 .github/workflows/pr-policy.yml create mode 100644 .mergify.yml create mode 100644 CONTRIBUTING.md create mode 100644 SECURITY.md create mode 100644 docs/automation.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..fde2f48 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,31 @@ +name: Bug report +description: Report a reproducible problem with a Beatrice project. +title: "Bug: " +body: + - type: markdown + attributes: + value: For security vulnerabilities, use the private reporting option on the repository's Security tab. + - type: input + id: version + attributes: + label: Version and platform + description: Include the app version or commit, OS and relevant hardware or browser. + validations: + required: true + - type: textarea + id: steps + attributes: + label: Steps to reproduce + validations: + required: true + - type: textarea + id: behavior + attributes: + label: Expected and actual behavior + validations: + required: true + - type: textarea + id: logs + attributes: + label: Relevant logs or screenshots + description: Redact tokens, personal data and sensitive audio. diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..b14fbb7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: true +contact_links: + - name: Report a security vulnerability + url: https://github.com/Project-Beatrice-V2/.github/blob/main/SECURITY.md + about: Follow the private reporting instructions for the affected repository. diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..a9ef4db --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,14 @@ +version: 2 +updates: + - package-ecosystem: github-actions + directory: '/' + schedule: + interval: weekly + day: monday + time: '05:00' + timezone: Etc/UTC + open-pull-requests-limit: 2 + groups: + actions-minor-patch: + patterns: ["*"] + update-types: [minor, patch] diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..d80b667 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,11 @@ +## Summary + + + +## Verification + + + +## Risk and rollout + + diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..b7e13a6 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,36 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + branches: [main] + workflow_dispatch: + +permissions: {} + +concurrency: + group: ci-${{ github.ref }} + cancel-in-progress: true + +jobs: + configuration: + name: Configuration validation + runs-on: ubuntu-24.04 + timeout-minutes: 10 + permissions: + contents: read + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - uses: actions/setup-python@6d4fd22b20465ccc0f7354476588e8df7c9ca0e0 # v7.1.0 + with: + python-version: '3.12' + - run: python -m pip install check-jsonschema==0.39.0 + - name: Validate workflow and community form schemas + run: | + check-jsonschema --builtin-schema vendor.github-workflows .github/workflows/*.yml + check-jsonschema --builtin-schema vendor.github-issue-forms .github/ISSUE_TEMPLATE/bug_report.yml + check-jsonschema --builtin-schema vendor.github-issue-config .github/ISSUE_TEMPLATE/config.yml + check-jsonschema --builtin-schema vendor.mergify .mergify.yml diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000..4d2d77b --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,35 @@ +name: CodeQL + +on: + push: + branches: [main] + pull_request: + branches: [main] + schedule: + - cron: '50 4 * * 1' + workflow_dispatch: + +permissions: {} + +concurrency: + group: codeql-${{ github.ref }} + cancel-in-progress: true + +jobs: + analyze: + name: CodeQL analysis + runs-on: ubuntu-24.04 + timeout-minutes: 35 + permissions: + contents: read + security-events: write + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + # This repository ships assets or documentation and GitHub Actions workflows. + - uses: github/codeql-action/init@33d7b85da1a04171e211befe2c739303b9a4c066 # v4.39.3 + with: + languages: actions + build-mode: none + - uses: github/codeql-action/analyze@33d7b85da1a04171e211befe2c739303b9a4c066 # v4.39.3 diff --git a/.github/workflows/pr-policy.yml b/.github/workflows/pr-policy.yml new file mode 100644 index 0000000..726efca --- /dev/null +++ b/.github/workflows/pr-policy.yml @@ -0,0 +1,59 @@ +name: PR policy + +on: + pull_request: + branches: [main] + types: [opened, reopened, synchronize, edited, ready_for_review] + +permissions: {} + +concurrency: + group: pr-policy-${{ github.event.pull_request.number }} + cancel-in-progress: true + +jobs: + policy: + name: Review policy + if: '!github.event.pull_request.draft' + runs-on: ubuntu-24.04 + timeout-minutes: 5 + permissions: + pull-requests: read + steps: + - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + script: | + const pr = context.payload.pull_request; + const title = pr.title.trim(); + const description = (pr.body ?? '') + .replace(//g, '') + .split('\n') + .filter(line => !/^\s*(?:#|[-*] \[)/.test(line)) + .join(' ') + .trim(); + + if (pr.user.type !== 'Bot') { + if (title.length < 8 || /^(?:draft|wip)(?:\b|:)/i.test(title)) { + core.setFailed('Use a descriptive PR title and keep unfinished work in draft.'); + } + if (description.length < 15) { + core.setFailed('Describe the change and how you verified it in the PR body.'); + } + } + + const files = await github.paginate(github.rest.pulls.listFiles, { + ...context.repo, + pull_number: pr.number, + per_page: 100 + }); + const paths = files.flatMap(file => [file.filename, file.previous_filename].filter(Boolean)); + const tests = /(^|\/)(tests?|__tests__)(\/|$)|(?:^|\/)test_[^/]+\.py$|\.(?:test|spec)\.[cm]?[jt]sx?$/i; + const source = /\.(?:[cm]?[jt]sx?|py|c|h|css|html|ipynb|sh|ps1|bat)$/i; + const risk = /(^\.github\/|(?:^|\/)(?:package(?:-lock)?\.json|(?:uv|poetry)\.lock|requirements[^/]*\.txt|pyproject\.toml|vercel\.json|(?:start|setup)[^/]*\.(?:sh|ps1|bat))$|\.(?:dll|exe|vst3|bin|zip)$)/i; + + if (paths.some(path => source.test(path) && !tests.test(path)) && !paths.some(path => tests.test(path))) { + core.warning('Source changed without a test change. Add coverage where practical or describe manual verification.'); + } + if (paths.some(path => risk.test(path)) || files.length < pr.changed_files) { + core.warning('Review dependency, automation, installer and binary changes with extra care.'); + } diff --git a/.mergify.yml b/.mergify.yml new file mode 100644 index 0000000..ddf3c8b --- /dev/null +++ b/.mergify.yml @@ -0,0 +1,21 @@ +# yaml-language-server: $schema=https://docs.mergify.com/mergify-configuration-schema.json +pull_request_rules: + - name: Squash an approved README-only PR when a maintainer opts in + disabled: + reason: Enable after main has required reviews and checks, and the app is installed without bypass access. + conditions: + - base = main + - -draft + - label = automerge:docs + - -author = dependabot[bot] + - "#files = 1" + - files = README.md + - "#approved-reviews-by >= 1" + - "#changes-requested-reviews-by = 0" + - "#commits-behind = 0" + - check-success = Configuration validation + - check-success = Review policy + - check-success = CodeQL analysis + actions: + merge: + method: squash diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..354c003 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,9 @@ +# Contributing to Project Beatrice V2 + +Open the README in the repository you want to change and follow its platform and dependency setup. For projects with a Node lockfile, use `npm ci`. Keep dependency changes and their lockfile changes together. + +Open pull requests against `main`. Give each PR a descriptive title and summarize the change, why it matters, and how you verified it. Use draft status while the work is in progress. For changes to application behavior, update the existing tests where practical. If the repository has no harness or the change needs audio hardware, record the platform, steps and result of your manual verification. + +Keep generated installers, model weights, sample audio and credentials out of source changes unless the repository specifically manages those assets. Model contributions should follow the model repository's licensing and provenance requirements. Call out changes to dependencies, permissions, GitHub Actions, release scripts, launchers and bundled binaries in the PR so maintainers can review them closely. + +Maintainers should review the diff and all applicable checks before merging. Report vulnerabilities privately as described in [SECURITY.md](SECURITY.md). See the [automation guide](docs/automation.md) for check coverage and maintainer setup. diff --git a/README.md b/README.md index 6d0cb56..3c914d9 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +[![CI](https://github.com/Project-Beatrice-V2/.github/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/Project-Beatrice-V2/.github/actions/workflows/ci.yml) [![CodeQL](https://github.com/Project-Beatrice-V2/.github/actions/workflows/codeql.yml/badge.svg?branch=main)](https://github.com/Project-Beatrice-V2/.github/actions/workflows/codeql.yml) [![PR policy](https://github.com/Project-Beatrice-V2/.github/actions/workflows/pr-policy.yml/badge.svg?event=pull_request)](https://github.com/Project-Beatrice-V2/.github/actions/workflows/pr-policy.yml) +
@@ -161,3 +163,7 @@ Built with ❤️ by the Project Beatrice V2 Team • Released under the MIT License
+ +## Repository automation + +See the [organization automation guide](https://github.com/Project-Beatrice-V2/.github/blob/main/docs/automation.md) for checks, contribution policies, and integration setup. diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..8a42e4d --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,7 @@ +# Security policy + +Report a suspected vulnerability using **Security → Advisories → Report a vulnerability** in the affected repository. The report is private and goes to the maintainers. If the private report button is unavailable, contact a listed maintainer privately to arrange a disclosure channel. + +Include the affected repository and version, platform, steps to reproduce, and the impact you observed. Redact credentials, personal data and sensitive audio. Keep exploit details out of public issues, pull requests and discussions while the report is under review. + +We prioritize issues that affect the current release or the default branch. If you found the issue on an earlier release, include that version and whether the behavior persists on the latest version. diff --git a/docs/automation.md b/docs/automation.md new file mode 100644 index 0000000..b371450 --- /dev/null +++ b/docs/automation.md @@ -0,0 +1,52 @@ +# Repository automation + +Every repository runs CI on pull requests targeting `main` and on pushes to `main`. Pull requests also run a review policy check. The workflows run with read-only tokens except for CodeQL results uploads and the existing deployment or release jobs that need specific write permissions. + +## Checks by repository + +| Repository | CI verification | Dependabot ecosystems | +| --- | --- | --- | +| Beatrice-website | Node 24 and `npm ci`, Oxlint, TypeScript and Vite build, Python helper syntax | npm, GitHub Actions | +| Dataset Web UI (macOS and Windows) | Lockfile-based frontend build with TypeScript. Python 3.12 unit and FastAPI integration tests with CPU PyTorch and isolated SQLite and output directories | npm in `/frontend`, pip in `/voiceforge-backend`, GitHub Actions | +| Trainer (macOS and Windows) | JavaScript, Python and shell syntax. Build the Python wheel from the existing Hatchling package | pip at the root, uv in `/beatrice-trainer`, GitHub Actions | +| Voice Changer (macOS) | JavaScript, Python and shell syntax. Build the Apple Silicon DMG with the existing bundled Python and ad-hoc signing workflow | npm, pip, GitHub Actions | +| Voice Changer (Windows) | JavaScript and Python syntax. Build the installer and portable archive on Windows using the existing package script | npm, pip, GitHub Actions | +| Beatrice-colab | Validate Colab and Kaggle notebook structure with nbformat | GitHub Actions | +| Beatrice-voice-models | Parse model metadata and check ZIP integrity and paths without extraction | GitHub Actions | +| Organization `.github` | Validate Actions workflow, issue form and Mergify schemas | GitHub Actions | + +The dataset repositories have the existing runnable unit and integration suites. The Windows voice changer's DLL diagnostic requires a separately built DLL and only prints on failure. It receives syntax checking in CI. GPU training, live audio devices, VST3 loading and hosted notebook execution still need their target environments. The standalone Python helpers in the website and the installs inside notebook cells have no tracked dependency manifest. Review their dependencies when changing those files. + +The website stays connected to Vercel. Its GitHub Pages workflow publishes the legacy redirect. The Windows voice changer still publishes release assets only when a maintainer dispatches its release workflow for a tag. The packaging job has read-only access and passes files to a separate release upload job. + +## Dependency and code scanning + +Dependabot checks each listed ecosystem weekly. It groups minor and patch version bumps, keeps major updates separate, and limits the number of open version PRs. Python application requirements without lockfiles retain their existing constraints. Review matching trainer changes in both `requirements.txt` and `beatrice-trainer/pyproject.toml` when a shared dependency moves. The Dependency review check rejects newly introduced high or critical advisories in dependency graphs for application repositories. Existing alerts should be triaged separately in the Security tab. + +CodeQL detects supported languages and scans on pull requests, pushes to `main` and a staggered weekly schedule. It uses buildless extraction. The profile, notebook and model repositories are scanned for GitHub Actions workflow code. Notebook cells and binary model contents fall outside CodeQL source analysis. If a repository has CodeQL default setup enabled later, use only one setup to avoid duplicate analyses. Use the advanced workflow in this rollout. + +## Pull request policy + +The Reviewpad app is in maintenance mode and accepts no new installations. The organization has no existing installation. The **Review policy** job checks titles and descriptions on ready-for-review PRs and flags source changes without test changes and changes to sensitive files. The warnings prompt human review. The job has read-only pull request access. [Reviewpad app status](https://github.com/apps/reviewpad) + +## Enable SonarQube analysis + +SonarQube workflows are prepared for the website, dataset apps, trainers and voice changers. Each repository scopes its own application code and excludes build outputs, dependency directories and generated artifacts. The dataset test directories are classified as tests. The existing suites do not produce configured coverage reports, so these scans do not ingest coverage. + +1. Import the GitHub repository into SonarQube Cloud or create a project on a supported SonarQube Server. Connect the GitHub integration if you want PR decoration. For Cloud CI scans, turn off automatic analysis in the Sonar project. +2. Under **Settings → Secrets and variables → Actions**, add a project-scoped analysis token as the Actions secret `SONAR_TOKEN`. +3. Add the Actions variable `SONAR_PROJECT_KEY`. For Cloud, also add `SONAR_ORGANIZATION`. For a server or a Cloud region using a different host, set `SONAR_HOST_URL` to the HTTPS URL the runner can reach. The default host is `https://sonarcloud.io`. +4. Set `SONAR_ENABLED=true` and dispatch **SonarQube** from `main` to verify the scan and quality gate. Set `SONAR_PR_ANALYSIS=true` only if your Sonar plan supports PR analysis and you want it for same-repository PRs. Fork and Dependabot PRs keep the standard CI, Dependency review and CodeQL checks. +5. After the quality gate has run, copy its badge from the Sonar project's Information page if desired. Keep the Sonar job optional unless the required check can be produced for every PR you accept. + +For a server with a private CA, add its certificate according to the scanner action's setup instructions. [SonarQube scan action](https://github.com/SonarSource/sonarqube-scan-action) + +## Enable Mergify after branch rules are in place + +The checked-in Mergify rule ships disabled. It only targets a ready, up-to-date PR that changes exactly `README.md`, has the maintainer-applied `automerge:docs` label and an approval, has no outstanding change requests, and passes the repository's CI, CodeQL, Review policy and applicable Dependency review checks. Dependabot PRs are excluded and dependency manifests cannot match the file constraint. + +1. Install the Mergify GitHub App on selected repositories only. Keep the app out of all protection bypass lists. +2. On `main`, require pull requests, at least one approving review, dismissal of stale approvals, and the successful checks listed in that repository's `.mergify.yml`. Enable squash merging. Confirm your existing protection settings and any additional required security checks. +3. Use Mergify's configuration validator, then enable the rule by removing its `disabled` block in a reviewed PR. Create the `automerge:docs` label and apply it only after inspecting the change. + +Mergify inherits applicable GitHub branch protection and ruleset requirements. [Mergify merge action](https://docs.mergify.com/workflow/actions/merge/) From 4090e8ada5bd981bd5139024587b0508c037a46f Mon Sep 17 00:00:00 2001 From: Jatin Pandey Date: Sun, 8 Nov 2026 14:39:02 +0530 Subject: [PATCH 2/3] Require security results for eligible merges --- .mergify.yml | 8 +++++--- docs/automation.md | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.mergify.yml b/.mergify.yml index ddf3c8b..d766efe 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -13,9 +13,11 @@ pull_request_rules: - "#approved-reviews-by >= 1" - "#changes-requested-reviews-by = 0" - "#commits-behind = 0" - - check-success = Configuration validation - - check-success = Review policy - - check-success = CodeQL analysis + - "#check-failure = 0" + - check-success = @github-actions/Configuration validation + - check-success = @github-actions/Review policy + - check-success = @github-actions/CodeQL analysis + - check-success = @github-advanced-security/CodeQL actions: merge: method: squash diff --git a/docs/automation.md b/docs/automation.md index b371450..6ed6302 100644 --- a/docs/automation.md +++ b/docs/automation.md @@ -43,10 +43,10 @@ For a server with a private CA, add its certificate according to the scanner act ## Enable Mergify after branch rules are in place -The checked-in Mergify rule ships disabled. It only targets a ready, up-to-date PR that changes exactly `README.md`, has the maintainer-applied `automerge:docs` label and an approval, has no outstanding change requests, and passes the repository's CI, CodeQL, Review policy and applicable Dependency review checks. Dependabot PRs are excluded and dependency manifests cannot match the file constraint. +The checked-in Mergify rule ships disabled. It only targets a ready, up-to-date PR that changes exactly `README.md`, has the maintainer-applied `automerge:docs` label and an approval, has no outstanding change requests, and passes the repository's CI, CodeQL scan and results, Review policy and applicable Dependency review checks. Any failing check blocks the rule. Dependabot PRs are excluded and dependency manifests cannot match the file constraint. 1. Install the Mergify GitHub App on selected repositories only. Keep the app out of all protection bypass lists. -2. On `main`, require pull requests, at least one approving review, dismissal of stale approvals, and the successful checks listed in that repository's `.mergify.yml`. Enable squash merging. Confirm your existing protection settings and any additional required security checks. +2. On `main`, require pull requests, at least one approving review, dismissal of stale approvals, and the successful checks listed in that repository's `.mergify.yml`. Enable squash merging. Use GitHub's **Require code scanning results** rule for CodeQL and choose the alert severity that must block merges. Confirm existing protections and any additional required checks. 3. Use Mergify's configuration validator, then enable the rule by removing its `disabled` block in a reviewed PR. Create the `automerge:docs` label and apply it only after inspecting the change. Mergify inherits applicable GitHub branch protection and ruleset requirements. [Mergify merge action](https://docs.mergify.com/workflow/actions/merge/) From 2edc9ceb526b451761d3efba70694ca127d2312e Mon Sep 17 00:00:00 2001 From: Jatin Pandey Date: Sun, 8 Nov 2026 14:41:56 +0530 Subject: [PATCH 3/3] Verify pull requests against every base branch --- .github/workflows/ci.yml | 1 - .github/workflows/codeql.yml | 1 - .github/workflows/pr-policy.yml | 1 - docs/automation.md | 2 +- 4 files changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b7e13a6..7faa3d0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,7 +4,6 @@ on: push: branches: [main] pull_request: - branches: [main] workflow_dispatch: permissions: {} diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 4d2d77b..e00a9c6 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -4,7 +4,6 @@ on: push: branches: [main] pull_request: - branches: [main] schedule: - cron: '50 4 * * 1' workflow_dispatch: diff --git a/.github/workflows/pr-policy.yml b/.github/workflows/pr-policy.yml index 726efca..69ab4fc 100644 --- a/.github/workflows/pr-policy.yml +++ b/.github/workflows/pr-policy.yml @@ -2,7 +2,6 @@ name: PR policy on: pull_request: - branches: [main] types: [opened, reopened, synchronize, edited, ready_for_review] permissions: {} diff --git a/docs/automation.md b/docs/automation.md index 6ed6302..e87617c 100644 --- a/docs/automation.md +++ b/docs/automation.md @@ -1,6 +1,6 @@ # Repository automation -Every repository runs CI on pull requests targeting `main` and on pushes to `main`. Pull requests also run a review policy check. The workflows run with read-only tokens except for CodeQL results uploads and the existing deployment or release jobs that need specific write permissions. +Every repository runs CI on pull requests and on pushes to `main`. Pull requests also run a review policy check. The workflows run with read-only tokens except for CodeQL results uploads and the existing deployment or release jobs that need specific write permissions. ## Checks by repository