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
15 changes: 15 additions & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# These are supported funding model platforms

github: rsalmn
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: rsalman
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
polar: # Replace with a single Polar username
buy_me_a_coffee: # Replace with a single Buy Me a Coffee username
thanks_dev: # Replace with a single thanks.dev username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
54 changes: 54 additions & 0 deletions .github/workflows/claude.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: Claude Code

on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
issues:
types: [opened, assigned]
pull_request_review:
types: [submitted]

# Least-privilege default: no token permissions at the top level; the `claude` job
# grants exactly what it needs below (Scorecard TokenPermissions).
permissions: {}

jobs:
claude:
if: |
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
issues: read
id-token: write
actions: read # Required for Claude to read CI results on PRs
steps:
- name: Checkout repository
uses: actions/checkout@v7
with:
persist-credentials: false
fetch-depth: 1

- name: Run Claude Code
id: claude
uses: anthropics/claude-code-action@v1
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}

# This is an optional setting that allows Claude to read CI results on PRs
additional_permissions: |
actions: read

# Optional: Give a custom prompt to Claude. If this is not specified, Claude will perform the instructions specified in the comment that tagged it.
# prompt: 'Update the pull request description to include a summary of changes.'

# Optional: Add claude_args to customize behavior and configuration
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
# or https://code.claude.com/docs/en/cli-reference for available options
# claude_args: '--allowed-tools Bash(gh pr *)'
5 changes: 5 additions & 0 deletions .github/workflows/docker-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,12 @@ env:
DOCKERHUB_IMAGE: rsalmn/extremerouter

jobs:
quality:
name: Quality gate
uses: ./.github/workflows/quality-gate.yml

build-and-push:
needs: quality
runs-on: ubuntu-latest
permissions:
contents: read
Expand Down
7 changes: 6 additions & 1 deletion .github/workflows/npm-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,13 @@ permissions:
contents: read

jobs:
quality:
name: Quality gate
uses: ./.github/workflows/quality-gate.yml

publish:
name: Build & Publish CLI
needs: quality
runs-on: ubuntu-latest

steps:
Expand All @@ -26,7 +31,7 @@ jobs:
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
node-version: "22"
registry-url: "https://registry.npmjs.org"
cache: "npm"

Expand Down
80 changes: 80 additions & 0 deletions .github/workflows/quality-gate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
name: Quality Gate

on:
workflow_call:
workflow_dispatch:
pull_request:
push:
branches:
- main

permissions:
contents: read

concurrency:
group: quality-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

env:
NODE_VERSION: "22"

jobs:
lint:
name: Lint
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: npm

- name: Install dependencies
run: npm ci

- name: Run ESLint
run: npm run lint

test:
name: Deterministic tests
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: npm

- name: Install dependencies
run: npm ci

- name: Run deterministic tests
run: npm test

security:
name: Production dependency audit
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: npm

- name: Install dependencies
run: npm ci

- name: Audit production dependencies
run: npm run security:audit
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ PUBLIC.md
Thanks.md
PUBLIC.en.md
PR/*
package-lock.json

# Keep the root lockfile tracked so CI and release builds can use npm ci.

#Ignore vscode AI rules
.github/instructions/codacy.instructions.md
Expand Down
4 changes: 4 additions & 0 deletions .workbuddy-ai/memory/2026-07-29.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# 2026-07-29

- Completed the production engineering audit for ExtremeRouter and delivered `outputs/PROJECT-AUDIT-REPORT.md`. The audit covers runtime architecture, security, deployment, dependencies, testing/CI, performance/scalability, maintainability, UI/UX, legacy branding, target architecture, and a 30/60/90-day roadmap. Highest priorities: establish deterministic Vitest and CI release gates, patch production dependency vulnerabilities, remove the universal default password, make `custom-server.js` the enforced production entrypoint, and harden artifact provenance/container reproducibility. Build status remains unverified because sandbox permission for Next.js generated-output replacement was denied; the build was not retried or bypassed.
- Implemented a strict reusable GitHub Actions quality gate for npm and Docker releases. Publishing jobs now require parallel lint, deterministic Vitest, and high/critical production dependency audit jobs to pass. Added pinned Vitest 3.2.4, tracked root package lock support, canonical quality scripts, and a separate live-test configuration. Validation confirmed fail-closed behavior: YAML and workflow dependencies are valid, while current deterministic tests (30 failed files / 42 failed tests) and production audit (3 high issues) block publishing as intended. Full-root lint was configured strictly but its local validation was stopped after 4.5 minutes; CI keeps a 15-minute timeout.
Loading
Loading