Skip to content
Open
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
27 changes: 5 additions & 22 deletions .github/workflows/jest-testing.yml
Original file line number Diff line number Diff line change
@@ -1,29 +1,12 @@
name: Run Jest testing suite

on:
workflow_dispatch:
pull_request:

env:
NODE_ENV: "test"

jobs:
testing:
permissions: write-all
runs-on: ubuntu-latest
steps:
- uses: oven-sh/setup-bun@v2
with:
bun-version: latest

- uses: actions/checkout@v5
with:
fetch-depth: 0

- name: Jest With Coverage
run: |
bun install --frozen-lockfile
bun run test

- name: Add Jest Report to Summary
if: always()
run: echo "$(cat test-dashboard.md)" >> $GITHUB_STEP_SUMMARY
uses: ./.github/workflows/reusable/jest.yml
with:
package_manager: bun
enable_summary: true
40 changes: 0 additions & 40 deletions .github/workflows/knip-reporter.yml

This file was deleted.

29 changes: 4 additions & 25 deletions .github/workflows/knip.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,7 @@ on:

jobs:
run-knip:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v5

- name: Setup Bun
uses: oven-sh/setup-bun@v2

- name: Install toolchain
run: bun install

- name: Store PR number
run: echo ${{ github.event.number }} > pr-number.txt

- name: Run Knip
run: bun run knip || bun run knip --reporter json > knip-results.json

- name: Upload knip result
if: failure()
uses: actions/upload-artifact@v4
with:
name: knip-results
path: |
knip-results.json
pr-number.txt
uses: ./.github/workflows/reusable/knip.yml
with:
package_manager: bun
enable_reporter: true
144 changes: 144 additions & 0 deletions .github/workflows/reusable/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
# Reusable Workflows

This directory contains reusable GitHub workflows that can be used across multiple repositories in the UbiquityOS ecosystem.

## Available Workflows

### Knip Workflow

**File:** `reusable/knip.yml`

Reusable Knip workflow with configurable package manager support.

#### Inputs

| Input | Type | Default | Description |
|-------|------|---------|-------------|
| `package_manager` | string | `bun` | Package manager to use (bun, yarn, npm, pnpm) |
| `yarn_version` | string | `latest` | Yarn version (only used if package_manager is yarn) |
| `node_version` | string | `latest` | Node.js version |
| `working_directory` | string | `.` | Working directory for the workflow |
| `knip_script` | string | `knip` | Knip script name to run |
| `enable_reporter` | boolean | `true` | Enable Knip reporter for PR comments |

#### Usage Example

```yaml
name: Knip Check

on:
pull_request:
workflow_dispatch:

jobs:
knip:
uses: ubiquity-os/plugin-template/.github/workflows/reusable/knip.yml@main
with:
package_manager: bun
enable_reporter: true
```

#### Usage with Yarn

```yaml
name: Knip Check

on:
pull_request:

jobs:
knip:
uses: ubiquity-os/plugin-template/.github/workflows/reusable/knip.yml@main
with:
package_manager: yarn
yarn_version: '3.6.0'
enable_reporter: true
```

---

### Jest Testing Workflow

**File:** `reusable/jest.yml`

Reusable Jest testing workflow with configurable package manager and coverage support.

#### Inputs

| Input | Type | Default | Description |
|-------|------|---------|-------------|
| `package_manager` | string | `bun` | Package manager to use (bun, yarn, npm, pnpm) |
| `yarn_version` | string | `latest` | Yarn version (only used if package_manager is yarn) |
| `node_version` | string | `latest` | Node.js version |
| `working_directory` | string | `.` | Working directory for the workflow |
| `test_script` | string | `test` | Test script name to run |
| `coverage` | boolean | `false` | Enable code coverage |
| `coverage_script` | string | `test:coverage` | Coverage script name (if different from test script) |
| `enable_summary` | boolean | `true` | Enable Jest summary in GitHub Actions summary |

#### Usage Example

```yaml
name: Test Suite

on:
pull_request:
workflow_dispatch:

jobs:
test:
uses: ubiquity-os/plugin-template/.github/workflows/reusable/jest.yml@main
with:
package_manager: bun
enable_summary: true
```

#### Usage with Coverage

```yaml
name: Test Suite with Coverage

on:
pull_request:

jobs:
test:
uses: ubiquity-os/plugin-template/.github/workflows/reusable/jest.yml@main
with:
package_manager: yarn
yarn_version: '3.6.0'
coverage: true
coverage_script: 'test:coverage'
enable_summary: true
```

---

## Benefits

1. **Centralized Maintenance**: Update workflows in one place, propagate to all repositories
2. **Consistency**: Ensure all repositories use the same testing and linting standards
3. **Flexibility**: Configure package manager, versions, and scripts per repository
4. **Reduced Duplication**: No need to maintain identical workflow files across repos

## Migration Guide

To migrate an existing repository to use these reusable workflows:

1. Remove existing `knip.yml`, `knip-reporter.yml`, and `jest-testing.yml` files
2. Create new workflow files that call the reusable workflows (see examples above)
3. Test the workflows on a pull request
4. Commit and push changes

## Permissions

Both workflows require the following permissions:

```yaml
permissions:
contents: read
pull-requests: write
actions: read
```

The Knip workflow additionally needs `actions: read` permission to download artifacts from the workflow run.
Comment on lines +133 to +144
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Permissions section contradicts itself and the Jest workflow.

The code block lists actions: read as required for both, but the follow-up sentence says it's Knip-only — and indeed reusable/jest.yml only declares contents: read + pull-requests: write. Split the blocks per workflow to avoid confusion.

📝 Suggested fix
-Both workflows require the following permissions:
+**Jest workflow:**
+
+```yaml
+permissions:
+  contents: read
+  pull-requests: write
+```
+
+**Knip workflow** (needs `actions: read` to download artifacts between jobs):

 ```yaml
 permissions:
   contents: read
   pull-requests: write
   actions: read

-The Knip workflow additionally needs actions: read permission to download artifacts from the workflow run.

</details>

<!-- fingerprinting:phantom:poseidon:nectarine:fc6fe64d-33c1-4664-943f-04e0bf26173a -->

<!-- This is an auto-generated comment by CodeRabbit -->

128 changes: 128 additions & 0 deletions .github/workflows/reusable/jest.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
name: Reusable Jest Testing Workflow

on:
workflow_call:
inputs:
package_manager:
description: 'Package manager to use (bun, yarn, npm, pnpm)'
required: false
default: 'bun'
type: string
yarn_version:
description: 'Yarn version (only used if package_manager is yarn)'
required: false
default: 'latest'
type: string
node_version:
description: 'Node.js version'
required: false
default: 'latest'
type: string
working_directory:
description: 'Working directory for the workflow'
required: false
default: '.'
type: string
test_script:
description: 'Test script name to run'
required: false
default: 'test'
type: string
coverage:
description: 'Enable code coverage'
required: false
default: false
type: boolean
coverage_script:
description: 'Coverage script name (if different from test script)'
required: false
default: 'test:coverage'
type: string
enable_summary:
description: 'Enable Jest summary in GitHub Actions summary'
required: false
default: true
type: boolean

permissions:
contents: read
pull-requests: write

env:
NODE_ENV: 'test'

jobs:
testing:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v5
with:
fetch-depth: 0

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node_version }}

- name: Setup Bun
if: inputs.package_manager == 'bun'
uses: oven-sh/setup-bun@v2
with:
bun-version: latest

- name: Setup Yarn
if: inputs.package_manager == 'yarn'
uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node_version }}
- run: corepack enable && corepack prepare yarn@${{ inputs.yarn_version }} --activate
if: inputs.package_manager == 'yarn'

- name: Install dependencies
working-directory: ${{ inputs.working_directory }}
run: |
if [ "${{ inputs.package_manager }}" = "bun" ]; then
bun install --frozen-lockfile
elif [ "${{ inputs.package_manager }}" = "yarn" ]; then
yarn install --frozen-lockfile
elif [ "${{ inputs.package_manager }}" = "npm" ]; then
npm ci
elif [ "${{ inputs.package_manager }}" = "pnpm" ]; then
pnpm install --frozen-lockfile
fi
Comment on lines +82 to +93
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Yarn Berry breaks with --frozen-lockfile (same as knip.yml).

Yarn 2+ uses --immutable. See the Knip review for the suggested gate on yarn --version. Worth extracting a shared composite action or script to avoid drift between the two reusable workflows.


- name: Run Jest Tests
id: test-run
working-directory: ${{ inputs.working_directory }}
run: |
if [ "${{ inputs.package_manager }}" = "bun" ]; then
bun run ${{ inputs.test_script }}
elif [ "${{ inputs.package_manager }}" = "yarn" ]; then
yarn ${{ inputs.test_script }}
elif [ "${{ inputs.package_manager }}" = "npm" ]; then
npm run ${{ inputs.test_script }}
elif [ "${{ inputs.package_manager }}" = "pnpm" ]; then
pnpm run ${{ inputs.test_script }}
fi

- name: Run Coverage (if enabled)
if: inputs.coverage
working-directory: ${{ inputs.working_directory }}
run: |
if [ "${{ inputs.package_manager }}" = "bun" ]; then
bun run ${{ inputs.coverage_script }}
elif [ "${{ inputs.package_manager }}" = "yarn" ]; then
yarn ${{ inputs.coverage_script }}
elif [ "${{ inputs.package_manager }}" = "npm" ]; then
npm run ${{ inputs.coverage_script }}
elif [ "${{ inputs.package_manager }}" = "pnpm" ]; then
pnpm run ${{ inputs.coverage_script }}
fi
Comment on lines +95 to +121
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Coverage runs in addition to tests, not instead.

When coverage: true, the suite executes twice (test_script, then coverage_script), roughly doubling CI time. Typically coverage supersedes the plain test run.

♻️ Suggested fix
-      - name: Run Jest Tests
-        id: test-run
+      - name: Run Jest Tests
+        id: test-run
+        if: ${{ !inputs.coverage }}
         working-directory: ${{ inputs.working_directory }}
         run: |
           ...
-      - name: Run Coverage (if enabled)
+      - name: Run Jest Tests with Coverage
         if: inputs.coverage


- name: Add Jest Report to Summary
if: always() && inputs.enable_summary && github.event_name == 'pull_request'
run: |
if [ -f test-dashboard.md ]; then
echo "$(cat test-dashboard.md)" >> $GITHUB_STEP_SUMMARY
fi
Loading