Files
openhuman/.github/workflows/pr-protection.yml
T
Steven EnamakelandGitHub 58969667d9 fix: add ESLint and Prettier configuration (#15)
* ran prettier

* Refactor ESLint configuration to use ES module syntax and enhance TypeScript support

- Converted CommonJS `require` statements to ES module `import` syntax for better compatibility with modern JavaScript.
- Added new paths to ignore in ESLint configuration to exclude additional directories.
- Updated TypeScript file patterns to be more specific, improving linting accuracy.
- Adjusted React hooks rules to allow certain patterns, enhancing flexibility in component design.

These changes improve the maintainability and clarity of the ESLint configuration, aligning it with current best practices.

* Refactor ESLint configuration to use ES module syntax and enhance TypeScript support

- Converted CommonJS `require` statements to ES module `import` syntax for better compatibility with modern JavaScript.
- Added new paths to ignore in ESLint configuration to exclude additional directories.
- Updated TypeScript file patterns to be more specific, improving linting accuracy.
- Introduced new React hooks rules and adjusted existing rules for better adherence to best practices.
- Made minor adjustments to import statements across various files for consistency and clarity.

These changes improve the overall linting setup and ensure better code quality across the project.

* Refactor import statements across multiple files for consistency

- Updated import statements to use TypeScript's `type` syntax for type imports, enhancing clarity and consistency across the codebase.
- Consolidated imports from the same module into single statements, improving readability and maintainability.

These changes streamline the code structure and align with best practices for TypeScript imports.

* Refactor import statements in memory manager for improved clarity

- Updated import statements to consolidate type imports and enhance readability.
- Removed redundant imports, streamlining the code structure in the memory manager file.

These changes align with best practices for TypeScript imports and improve maintainability.

* Add Husky for pre-commit and pre-push hooks

- Introduced Husky to manage Git hooks, enhancing the development workflow.
- Added pre-commit and pre-push scripts to enforce code formatting and linting checks before commits and pushes.
- Updated package.json to include Husky as a dependency and added a prepare script for setup.

These changes improve code quality and ensure adherence to formatting and linting standards during the development process.

* Refactor import statements for improved clarity and consistency

- Updated import statements across multiple files to consolidate type imports and enhance readability.
- Adjusted the order of imports for better organization and alignment with best practices in TypeScript.

These changes streamline the code structure and improve maintainability throughout the project.

* ran formatter

* Refactor import statements and improve code formatting across multiple files

- Consolidated and reordered import statements for better clarity and consistency in `SkillsGrid.tsx`, `SkillProvider.tsx`, and `index.ts`.
- Enhanced readability by adjusting formatting and removing redundant lines.
- These changes align with best practices for TypeScript imports and improve overall maintainability of the codebase.

* Refactor and optimize code in multiple components

- Removed redundant properties from the `STATUS_DISPLAY` object in `SkillsGrid.tsx` to streamline status handling.
- Consolidated import statements in `SettingsModal.tsx` for improved organization.
- Simplified state management and error handling in `BillingPanel.tsx`, enhancing performance and readability.
- Added `REHYDRATE` import to `index.ts` for better state persistence management.

These changes improve code clarity, maintainability, and align with best practices in TypeScript development.

* Consolidate import statements in SettingsModal.tsx for improved organization

* Add Prettier and ESLint checks to typecheck workflow

- Integrated a Prettier formatting check to ensure code style consistency.
- Added an ESLint step to enforce code quality and catch potential issues.
- These enhancements improve the development workflow by automating formatting and linting checks during the typecheck process.

* Add activeSkillDescription state to ConnectionsPanel and ConnectStep

- Introduced activeSkillDescription state in both ConnectionsPanel and ConnectStep components to store and manage skill descriptions.
- Updated the SkillSetupModal to accept skillDescription as a prop, enhancing the modal's functionality and data handling.

These changes improve the user experience by providing more detailed information about skills during the connection setup process.

* Enhance pre-push hook to include TypeScript compile check

- Added a TypeScript compile check to the pre-push script, ensuring that code compiles successfully before pushing.
- Updated error handling to include compile errors alongside formatting and linting issues, providing clearer feedback to developers.

These changes improve the reliability of the codebase by preventing non-compiling code from being pushed.

* Update GitHub workflows for pull request handling and publishing logic

- Modified the package-and-publish workflow to support pull request events, ensuring proper handling of branches.
- Adjusted the SHOULD_PUBLISH environment variable to differentiate between pull requests and main branch events.
- Updated the pr-protection workflow to focus solely on the main branch, removing references to the master branch.

These changes enhance the CI/CD process by refining branch handling and improving clarity in workflow conditions.
2026-02-02 06:24:50 +05:30

177 lines
8.8 KiB
YAML

name: PR Protection - Main Branch
on:
pull_request:
types: [opened, synchronize, reopened]
permissions:
pull-requests: write
contents: read
jobs:
check-pr-protection:
runs-on: ubuntu-latest
steps:
- name: Check PR target branch
id: check-target
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const pr = context.payload.pull_request;
const baseBranch = pr.base.ref;
const headBranch = pr.head.ref;
const prAuthor = pr.user.login;
const prTitle = pr.title;
const prBody = pr.body || '';
// Check if PR is targeting main
const isTargetingMain = baseBranch === 'main';
if (!isTargetingMain) {
console.log(`PR is targeting ${baseBranch}, not main. Skipping protection check.`);
core.setOutput('needs_check', 'false');
return;
}
console.log(`PR #${pr.number} is targeting ${baseBranch}`);
console.log(`PR author: ${prAuthor}`);
console.log(`PR title: ${prTitle}`);
console.log(`Head branch: ${headBranch}`);
// Check if PR title follows conventional commit format
// Allowed prefixes: feat, fix, chore, refactor, docs, test, style, perf, revert
const conventionalCommitPattern = /^(feat|fix|chore|refactor|docs|test|style|perf|revert)(\(.+\))?: .+/;
const followsConventionalFormat = conventionalCommitPattern.test(prTitle);
console.log(`Conventional commit format check: ${followsConventionalFormat ? 'PASSED' : 'FAILED'}`);
if (!followsConventionalFormat) {
console.log(`PR title must follow conventional commit format: <type>: <description>`);
console.log(`Allowed types: feat, fix, chore, refactor, docs, test, style, perf, revert`);
}
// Check if this is the automated PR from create-develop-to-main-pr workflow
// The automated PR has these characteristics:
// 1. Created by github-actions[bot]
// 2. From develop branch to main
// 3. Title matches pattern: "chore: merge develop into main (vX.Y.Z)"
// 4. Body contains "This PR automatically merges changes from develop into main"
// Validate PR title matches expected pattern: "chore: merge develop into main" followed by optional version
const expectedTitlePattern = /^chore: merge develop into main( \(v\d+\.\d+\.\d+\))?$/;
const titleMatches = expectedTitlePattern.test(prTitle);
console.log(`Automated PR title validation: ${titleMatches ? 'PASSED' : 'FAILED'}`);
console.log(`Expected pattern: "chore: merge develop into main" or "chore: merge develop into main (vX.Y.Z)"`);
const isAutomatedPR =
prAuthor === 'github-actions[bot]' &&
headBranch === 'develop' &&
titleMatches &&
prBody.includes('This PR automatically merges changes from develop into main');
if (isAutomatedPR) {
console.log('This PR is from the automated workflow. Allowing it.');
core.setOutput('needs_check', 'false');
core.setOutput('is_allowed', 'true');
} else {
console.log('This PR is NOT from the automated workflow.');
// Even if not automated, check if title follows conventional commit format
if (!followsConventionalFormat) {
console.log('PR title does not follow conventional commit format. Blocking it.');
core.setOutput('needs_check', 'true');
core.setOutput('is_allowed', 'false');
core.setOutput('conventional_format_failed', 'true');
} else {
console.log('PR title follows conventional commit format, but PR is not from automated workflow. Blocking it.');
core.setOutput('needs_check', 'true');
core.setOutput('is_allowed', 'false');
core.setOutput('conventional_format_failed', 'false');
}
}
// Store the conventional format check result
core.setOutput('conventional_format', followsConventionalFormat ? 'true' : 'false');
- name: Block unauthorized PR to main
if: steps.check-target.outputs.needs_check == 'true' && steps.check-target.outputs.is_allowed == 'false'
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const pr = context.payload.pull_request;
const baseBranch = pr.base.ref;
const prAuthor = pr.user.login;
const prTitle = pr.title;
const headBranch = pr.head.ref;
const prBody = pr.body || '';
// Check which validation criteria failed
const conventionalCommitPattern = /^(feat|fix|chore|refactor|docs|test|style|perf|revert)(\(.+\))?: .+/;
const followsConventionalFormat = conventionalCommitPattern.test(prTitle);
const checks = {
author: prAuthor === 'github-actions[bot]',
branch: headBranch === 'develop',
automatedTitle: /^chore: merge develop into main( \(v\d+\.\d+\.\d+\))?$/.test(prTitle),
body: prBody.includes('This PR automatically merges changes from develop into main'),
conventionalFormat: followsConventionalFormat
};
const failedChecks = Object.entries(checks)
.filter(([_, passed]) => !passed)
.map(([check]) => check);
console.log('Validation checks:', JSON.stringify(checks, null, 2));
console.log('Failed checks:', failedChecks.join(', '));
// Build detailed error message
let errorDetails = '';
if (failedChecks.length > 0) {
errorDetails = `\n\n**Failed validation checks:**\n`;
if (!checks.author) errorDetails += `- ❌ Author must be \`github-actions[bot]\` (found: \`${prAuthor}\`)\n`;
if (!checks.branch) errorDetails += `- ❌ Head branch must be \`develop\` (found: \`${headBranch}\`)\n`;
if (!checks.automatedTitle) errorDetails += `- ❌ Title must match pattern: \`chore: merge develop into main\` or \`chore: merge develop into main (vX.Y.Z)\` (found: \`${prTitle}\`)\n`;
if (!checks.body) errorDetails += `- ❌ Body must contain: "This PR automatically merges changes from develop into main"\n`;
if (!checks.conventionalFormat) errorDetails += `- ❌ PR title must follow conventional commit format: \`<type>: <description>\`\n`;
if (!checks.conventionalFormat) errorDetails += ` Allowed types: \`feat\`, \`fix\`, \`chore\`, \`refactor\`, \`docs\`, \`test\`, \`style\`, \`perf\`, \`revert\`\n`;
if (!checks.conventionalFormat) errorDetails += ` Example: \`feat: add new authentication endpoint\`\n`;
}
// Comment on the PR explaining why it was blocked
const codeBlock = '`';
const commentBody = [
'## PR Protection Rule Violation',
'',
`This PR targets the ${codeBlock}${baseBranch}${codeBlock} branch, which is protected.`,
'',
`**Only automated PRs from the ${codeBlock}create-develop-to-main-pr.yml${codeBlock} workflow are allowed to target ${codeBlock}${baseBranch}${codeBlock}.**${errorDetails}`,
'',
`**To merge changes into ${codeBlock}${baseBranch}${codeBlock}:**`,
`1. Create your PR targeting the ${codeBlock}develop${codeBlock} branch instead`,
`2. Once merged to ${codeBlock}develop${codeBlock}, the automated workflow will create a PR from ${codeBlock}develop${codeBlock} to ${codeBlock}${baseBranch}${codeBlock}`,
'',
`Please update this PR to target ${codeBlock}develop${codeBlock} instead, or close it and create a new PR targeting ${codeBlock}develop${codeBlock}.`
].join('\n');
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.number,
body: commentBody
});
// Fail the workflow to block the PR
let failureMessage = `PR #${pr.number} cannot target ${baseBranch} branch. `;
if (!checks.conventionalFormat) {
failureMessage += `PR title does not follow conventional commit format. `;
}
failureMessage += `Failed checks: ${failedChecks.join(', ')}. `;
failureMessage += `Only automated PRs from create-develop-to-main-pr.yml workflow are allowed.`;
core.setFailed(failureMessage);