Skip to content
Draft
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
43 changes: 41 additions & 2 deletions .github/workflows/audit.yml
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
name: Data Audit
name: Security & Data Audit

on:
pull_request:
paths:
- 'src/docs.json'
- 'scripts/**'
- 'tests/scripts/**'
- 'tests/audit/**'
- 'package.json'
- 'package-lock.json'
schedule:
- cron: '0 0 * * *' # Daily at midnight
workflow_dispatch:

jobs:
audit-links:
documentation-audit:
name: Documentation Audit
runs-on: ubuntu-latest
permissions:
contents: read
Expand All @@ -30,3 +35,37 @@ jobs:
DOCS_AUDIT_MAX_TOTAL: ${{ github.event_name == 'schedule' && '0' || '50' }}
# Advisories are non-blocking for PRs
continue-on-error: ${{ github.event_name == 'pull_request' }}

dependency-audit:
name: Dependency Audit
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@v6.3.0
with:
node-version: 22.x
cache: npm
- name: Run npm audit
run: npm audit --omit-dev --audit-level=critical
# Advisories are non-blocking for PRs
continue-on-error: ${{ github.event_name == 'pull_request' }}

script-audit:
name: Script Audit
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@v6.3.0
with:
node-version: 22.x
cache: npm
- name: Install dependencies
run: npm ci
- name: Run script audit
run: npm run test:scripts
92 changes: 78 additions & 14 deletions .github/workflows/integration.yml
Original file line number Diff line number Diff line change
@@ -1,42 +1,106 @@
name: Build
on:
pull_request:
push:
branches: [ main ]
tags:
- "*"
pull_request:

jobs:
Gatekeeper:
if: ${{ github.event_name == 'pull_request' }}
runs-on: ubuntu-latest
permissions:
pull-requests: write
contents: read
steps:
- name: Trusted configuration
uses: actions/checkout@v6
with:
ref: ${{ github.event.pull_request.base.ref }} # Force our main/base branch
sparse-checkout: |
.github
scripts

- name: Validate PR
uses: actions/github-script@v9
with:
script: |
const path = require('path');
let startFn;
try {
const scriptPath = path.resolve(process.env.GITHUB_WORKSPACE, 'scripts', 'workflow.preCheck.js');
const module = await import(scriptPath);
startFn = module.start || module.default;
} catch (err) {
console.error('PreCheck loading error.', err?.message || err);
core.setFailed('PreCheck loading error. File is missing or unreadable. Has the file been checked in?');
}

if (startFn) {
await startFn({
LABEL_NEEDS_CLEANUP: 'bot:needs-cleanup',
LABEL_NEEDS_MAINTAINER: 'bot:needs-maintainer',
LABEL_PRECHECKS_PASS: 'bot:policy-ready'
}, {
github,
context,
core,
});
}

- name: Lint
uses: actions/github-script@v9
with:
script: |
const path = require('path');
let workflowCommitLint;
try {
const scriptPath = path.resolve(process.env.GITHUB_WORKSPACE, 'scripts', 'workflow.commitLint.js');
const module = await import(scriptPath);
workflowCommitLint = module.workflowCommitLint || module.default;
} catch (err) {
console.error('Lint loading error.', err?.message || err);
core.setFailed('Lint loading error. File is missing or unreadable. Has the file been checked in?');
}

if (workflowCommitLint) {
const { data: commits } = await github.rest.pulls.listCommits({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.issue.number,
});

const { resultsArray, resultsString } = workflowCommitLint(commits);

if (resultsArray.length) {
core.setFailed(resultsString);
}
}

Integration-checks:
runs-on: ubuntu-latest
needs: Gatekeeper
if: ${{ always() && (github.event_name == 'push' || needs.Gatekeeper.result != 'cancelled') }}
permissions:
contents: read
strategy:
matrix:
node-version: [20.x, 22.x, 24.x]
steps:
- uses: actions/checkout@v6

- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v6.3.0
with:
node-version: ${{ matrix.node-version }}
cache: npm
- name: Node.js modules cache
uses: actions/cache@v5
id: modules-cache
with:
path: ${{ github.workspace }}/node_modules
key: ${{ runner.os }}-${{ matrix.node-version }}-modules-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-${{ matrix.node-version }}-modules

- name: Install Node.js packages
if: ${{ steps.modules-cache.outputs.cache-hit != 'true' }}
run: npm ci
- name: Audit packages
run: npm audit --audit-level=high
continue-on-error: true

- name: Lint and test
run: npm run test:ci

- name: Confirm integration
if: ${{ success() }}
run: npm run test:integration
4 changes: 4 additions & 0 deletions cspell.config.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
{
"language": "en",
"words": [
"aiignore",
"amet",
"codemods",
"ized",
"junie",
"llms",
"localappdata",
"midrun",
Expand All @@ -12,6 +14,8 @@
"onsessioninitialized",
"onsessionclosed",
"patternfly",
"precheck",
"prechecks",
"rereview",
"rsort",
"sparkline",
Expand Down
3 changes: 2 additions & 1 deletion eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,8 @@ export default [
{
files: [
'docs/**/*.ts',
'docs/**/*.js'
'docs/**/*.js',
'scripts/**/*.js'
],
rules: {
'jsdoc/require-returns': 0,
Expand Down
12 changes: 9 additions & 3 deletions jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export default {
projects: [
{
displayName: 'unit',
roots: ['src'],
roots: ['<rootDir>/src'],
testMatch: ['<rootDir>/src/**/*.test.ts'],
setupFilesAfterEnv: ['<rootDir>/jest.setupTests.ts'],
...baseConfig,
Expand Down Expand Up @@ -64,7 +64,7 @@ export default {
},
{
displayName: 'e2e',
roots: ['tests/e2e'],
roots: ['<rootDir>/tests/e2e'],
testMatch: ['<rootDir>/tests/e2e/**/*.test.ts'],
setupFilesAfterEnv: ['<rootDir>/tests/e2e/jest.setupTests.ts'],
transformIgnorePatterns: [
Expand All @@ -74,9 +74,15 @@ export default {
},
{
displayName: 'audit',
roots: ['tests/audit'],
roots: ['<rootDir>/tests/audit'],
testMatch: ['<rootDir>/tests/audit/**/*.test.ts'],
...baseConfig
},
{
displayName: 'scripts',
roots: ['<rootDir>/scripts', '<rootDir>/tests/scripts'],
testMatch: ['<rootDir>/tests/scripts/**/*.test.ts'],
...baseConfig
}
]
};
10 changes: 6 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,18 @@
"release": "changelog --non-cc --link-url https://github.com/patternfly/patternfly-mcp.git",
"start": "node dist/cli.js --log-stderr",
"start:dev": "tsx watch src/cli.ts --verbose --log-stderr",
"test": "npm run test:spell && npm run test:spell-docs && npm run test:lint && npm run test:types && jest --selectProjects unit --roots=src/",
"test:audit": "jest --selectProjects audit --roots=tests/audit/",
"test": "npm run test:spell && npm run test:spell-docs && npm run test:lint && npm run test:types && jest --selectProjects unit",
"test:audit": "jest --selectProjects audit",
"test:scripts": "NODE_OPTIONS='--experimental-vm-modules' jest --selectProjects scripts",
"test:scripts-dev": "npm run test:scripts -- --watchAll",
"test:ci": "npm test -- --coverage",
"test:dev": "npm test -- --watchAll",
"test:integration": "npm run build && NODE_OPTIONS='--experimental-vm-modules' jest --selectProjects e2e --roots=tests/e2e/",
"test:integration": "npm run build && NODE_OPTIONS='--experimental-vm-modules' jest --selectProjects e2e",
"test:integration-dev": "npm run test:integration -- --watchAll",
"test:lint": "eslint .",
"test:lint-fix": "eslint . --fix",
"test:spell-docs": "cspell './README.md' './CONTRIBUTING.md' './docs/**/*.md' './guidelines/**/*.md' './docs/**/*.ts' './docs/**/*.js' --config ./cspell.config.json --fail-fast",
"test:spell": "cspell './src/**/*.ts' './tests/**/*.ts' --exclude './src/**/*test*' --exclude './tests/**/*test*' --config ./cspell.config.json --fail-fast",
"test:spell": "cspell './src/**/*.ts' './scripts/**/*.js' './tests/**/*.ts' --exclude './src/**/*test*' --exclude './tests/**/*test*' --config ./cspell.config.json --fail-fast",
"test:types": "tsc --noEmit",
"prepare": "npm run build",
"prepack": "npm run build"
Expand Down
Loading
Loading