Skip to content

Conversation

@thoroc
Copy link
Contributor

@thoroc thoroc commented Jan 15, 2026

Summary

This PR completes the mirroring architecture by adding automated npm publishing and GitHub Pages deployment to mirror repositories.

Problem Solved

While the monorepo had workflows to mirror plugin code to separate repositories, the mirror repositories lacked automation to:

  • Publish packages to npm
  • Deploy documentation to GitHub Pages

This meant releases required manual steps after mirroring.

Solution

Added workflow templates that are automatically injected into mirror repositories during the mirroring process, with improved action version management and comprehensive documentation.

What Changed

1. Created Mirror Templates Directory (.github/mirror-templates/)

Composite Actions:

  • actions/setup-bun/ - Sets up Bun with dependency caching
  • actions/setup-node-npm/ - Configures Node.js and npm authentication

Workflows:

  • publish-npm.yml - Publishes to npm with provenance on version tag push
  • deploy-docs.yml - Deploys documentation to GitHub Pages using shared docs-builder

Documentation:

  • README.md - Templates documentation, troubleshooting, and version management

2. Improved Action Version Management

  • Pinned all GitHub Actions to minor versions (e.g., @v4.1 instead of @v4)
  • Provides automatic patch updates while protecting from breaking changes
  • Documented version update process and strategy
  • Created comparison analysis vs generator templates (SHA pinning)

3. Updated Mirror Workflows

  • .github/workflows/mirror-packages.yml - Now copies workflow templates to mirror repos
  • .github/workflows/mirror-docs-builder.yml - Uses --force-with-lease for safer pushes

4. Enhanced Documentation

  • README.md - Complete workflow automation description
  • .github/IMPLEMENTATION_SUMMARY.md - Implementation details and testing plan
  • .github/ARCHITECTURE_DIAGRAM.md - Visual architecture diagrams
  • .github/PLUGIN_WORKFLOWS.md - Comparison of mirrored vs standalone plugin workflows
  • .github/GENERATOR_VS_MIRROR_ANALYSIS.md - In-depth analysis of template differences

How It Works

1. Developer tags release in monorepo
   └─> git tag opencode-my-plugin@v1.0.0

2. mirror-packages.yml workflow extracts code + adds workflows

3. Mirror repository automatically:
   ├─> Publishes to npm (publish-npm.yml)
   └─> Deploys docs to GitHub Pages (deploy-docs.yml)

Benefits

Independent npm packages - Each plugin published from its own repo
Independent GitHub Pages - Each plugin has its own docs site
Automated releases - Tag once, everything else is automatic
Read-only mirrors - All development stays in monorepo
Self-contained repos - Mirror repos are fully standalone
Stable action versions - Minor version pinning prevents breaking changes

Action Version Strategy

Action Version Benefit
oven-sh/setup-bun @v2.0 Stable Bun setup
actions/setup-node @v4.1 Stable Node.js
actions/cache @v4.1 Reliable caching
actions/checkout @v4.2 Latest checkout

Minor version pinning balances stability and maintenance:

  • Automatic patch updates (security fixes)
  • Protection from breaking major changes
  • Suitable for frequently-regenerated files

See .github/GENERATOR_VS_MIRROR_ANALYSIS.md for detailed comparison with generator templates.

Requirements for Existing Mirrors

First-time setup needed for each existing mirror repository:

  1. Add npm token secret:

    • Go to Settings > Secrets and variables > Actions
    • Add secret: NPM_TOKEN (npm automation token)
  2. Enable GitHub Pages:

    • Go to Settings > Pages
    • Set Source to "GitHub Actions"
  3. Trigger new release to receive workflows

Testing Plan

Before Merging

  • ✅ Markdown linting passed (4 commits)
  • ✅ Pre-commit hooks passed
  • ✅ Action versions validated

After Merging

  1. Test with a non-production plugin
  2. Verify mirror repo receives workflows AND composite actions
  3. Verify npm publishing succeeds with provenance
  4. Verify docs deployment succeeds
  5. Verify action versions work correctly

Documentation

Comprehensive documentation included:

  • .github/IMPLEMENTATION_SUMMARY.md - Full implementation details
  • .github/ARCHITECTURE_DIAGRAM.md - Visual architecture
  • .github/PLUGIN_WORKFLOWS.md - Workflow comparison (mirrored vs standalone)
  • .github/GENERATOR_VS_MIRROR_ANALYSIS.md - Template strategy analysis
  • .github/mirror-templates/README.md - Template docs with version management

Rollback Plan

If issues occur, revert the merge commit or manually remove workflows from mirror repos.


Ready for review and testing.

Latest improvements (commit 4):

  • 🔒 Pinned actions to minor versions for stability
  • 📚 Documented version management strategy
  • 🔍 Added generator vs mirror template analysis
  • ✅ All pre-commit hooks passing

…ocs deployment

Add CI/CD workflow templates that are automatically deployed to mirror repositories:

- publish-npm.yml: Automatically publishes packages to npm with provenance
- deploy-docs.yml: Deploys documentation to GitHub Pages using shared docs-builder
- Templates are copied to mirror repos during release process

Updates:
- mirror-packages.yml: Add step to inject workflow templates into mirror repos
- mirror-docs-builder.yml: Use --force-with-lease for safer pushes
- README.md: Document complete automation pipeline and requirements
- Add comprehensive documentation in .github/mirror-templates/README.md
- Add implementation summary in .github/IMPLEMENTATION_SUMMARY.md

This completes Option 1: keeping the mirroring approach while adding missing automation.
Each mirror repository is now fully self-contained with automated npm publishing and
GitHub Pages deployment triggered by version tags.

Benefits:
- Independent plugin repos remain clean and focused
- Each plugin gets its own docs site at pantheon-org.github.io/<plugin-name>
- Single tag push in monorepo triggers complete release pipeline
- Zero manual steps required for publishing or deployment
- All development stays in monorepo (read-only mirrors)
- Add setup-bun composite action for dependency caching
- Add setup-node-npm composite action for npm authentication
- Document two plugin workflow approaches (mirrored vs standalone)
- Improve mirror template documentation with troubleshooting
- Update workflows to use composite actions for consistency
@github-actions
Copy link

⚠️ Large PR Warning

This PR is quite large with:

  • 11 changed files
  • 1467 added lines
  • 9 deleted lines

Consider breaking it down into smaller, focused PRs for easier review.

…nces

- Pin GitHub Actions to minor versions for better stability
- Update setup-bun from @v2 to @v2.0
- Update setup-node from @v4 to @v4.1
- Update actions/cache from @v4 to @v4.1
- Update actions/checkout from @v4 to @v4.2
- Update pages actions to minor versions (@v3.0, @v4.0)
- Add comprehensive action version management section to README
- Document version update process and strategy
- Create GENERATOR_VS_MIRROR_ANALYSIS.md with detailed comparison
- Explain why generator uses SHA pinning vs mirror uses minor pins
- Provide recommendations for keeping templates separate but synced
@github-actions
Copy link

⚠️ Large PR Warning

This PR is quite large with:

  • 12 changed files
  • 1831 added lines
  • 9 deleted lines

Consider breaking it down into smaller, focused PRs for easier review.

- Add API call to enable GitHub Pages in mirror repositories
- Configure build_type as 'workflow' for GitHub Actions deployment
- Handle both creation (POST) and update (PUT) scenarios gracefully
- Non-blocking: warns on failure but continues workflow

Benefits:
- Eliminates manual GitHub Pages configuration step
- Automatically sets correct build type for Actions-based deployment
- Works for both new and existing mirror repositories

Updated documentation to reflect automated Pages enablement and
clarified MIRROR_REPO_TOKEN permission requirements.
Convert inline bash scripts to maintainable TypeScript modules under
apps/workflows/src/scripts/mirror-package/ for better testability,
type safety, and code reuse.

New TypeScript Scripts:
- parse-tag.ts: Parse git tags to extract package information
- validate-mirror-url.ts: Extract and validate mirror repository URLs
- detect-changes.ts: Detect changes since last version tag
- enable-github-pages.ts: Enable/update GitHub Pages via Octokit API

Supporting Files:
- types.ts: Shared TypeScript type definitions
- index.ts: Barrel module for clean exports
- README.md: Comprehensive usage documentation
- parse-tag.test.ts: Unit tests (6 passing tests)

Benefits:
- Type safety with full TypeScript checking
- Testable with unit tests vs untestable inline bash
- Maintainable with clear separation of concerns
- Reusable outside GitHub Actions context
- Uses Octokit for consistent API handling with retry logic
- Better error messages and debugging support

Workflow Changes:
- Reduced from 115 lines of bash to 4 clean bun run calls
- Git-heavy operations appropriately remain as bash
- Scripts follow project's Bun + TypeScript standards
Convert all functions to arrow function constants to comply with
prefer-arrow-functions ESLint rule, matching project standards.

Changes:
- Convert function declarations to const arrow functions
- Fix TSDoc syntax (escape @ symbols)
- Remove unused imports (GitHubPagesConfig)
- Remove unused catch binding

All linting and tests now pass:
✓ 35 tests passing
✓ 0 linting errors
Add comprehensive test suites for mirror-package scripts:

New Tests:
- parse-tag.test.ts: Added setOutput() tests (3 new tests)
- validate-mirror-url.test.ts: 11 tests covering all scenarios
- detect-changes.test.ts: Type structure tests
- enable-github-pages.test.ts: Type structure tests

Coverage Improvements:
- Functions: 85.00% (up from 76.67%)
- Lines: 76.44% (up from 73.58%)
- Total tests: 56 passing (up from 35)

Test Coverage:
✓ parseTag() - 6 tests (edge cases, validation)
✓ setOutput() - 3 tests (file writing, console fallback)
✓ validateMirrorUrl() - 11 tests (various formats, errors)
✓ Type structures - 8 tests (type safety validation)

Remaining uncovered code is main() entry points (CLI handlers)
which are tested via actual workflow execution.
@github-actions
Copy link

⚠️ Large PR Warning

This PR is quite large with:

  • 23 changed files
  • 2862 added lines
  • 86 deleted lines

Consider breaking it down into smaller, focused PRs for easier review.

- Add set-branch-readonly.ts script to make mirror repos read-only
- Uses GitHub branch protection API with lock_branch: true
- Prevents accidental direct commits to mirror repositories
- Allows force pushes from monorepo workflow only
- Add comprehensive tests for BranchProtectionResult type
- Update mirror-packages.yml to call set-branch-readonly
- Update README documentation for new feature
- Add BranchProtectionResult type to types.ts
- Export setBranchReadonly in index.ts

This ensures mirror repositories maintain single source of truth
by preventing direct commits and requiring all updates to come
from the monorepo via the mirror workflow.
@github-actions
Copy link

⚠️ Large PR Warning

This PR is quite large with:

  • 25 changed files
  • 3100 added lines
  • 86 deleted lines

Consider breaking it down into smaller, focused PRs for easier review.

- Document commit 7: Linting fixes (26 errors resolved)
- Document commit 8: Test coverage improvements (56 → 60 tests)
- Document commit 9: Branch protection implementation
- Add complete commit history (9 commits)
- Update success criteria with new achievements
- Add testing recommendations for branch protection
- Document token permission requirements
- Update coverage metrics (86% functions, 77% lines)
- Fix markdown linting errors (add blank lines before lists)
@github-actions
Copy link

⚠️ Large PR Warning

This PR is quite large with:

  • 26 changed files
  • 3820 added lines
  • 86 deleted lines

Consider breaking it down into smaller, focused PRs for easier review.

- Add disable-repo-features.ts script to disable interactive features
- Uses GitHub API to set has_issues, has_projects, has_wiki to false
- Prevents content creation in mirror repositories
- Add comprehensive tests for DisableFeaturesResult type (5 tests)
- Update mirror-packages.yml to call disable-repo-features
- Update README documentation for new feature
- Add DisableFeaturesResult type to types.ts
- Export disableRepoFeatures in index.ts

Mirror repos now automatically disable Issues, Projects, and Wiki
to ensure all development activity happens in the monorepo. This
prevents confusion and maintains single source of truth.

Test results: 65 tests passing (up from 60), 85% function coverage
@github-actions
Copy link

⚠️ Large PR Warning

This PR is quite large with:

  • 28 changed files
  • 4059 added lines
  • 86 deleted lines

Consider breaking it down into smaller, focused PRs for easier review.

- Add @types/bun as dev dependency to fix CI type-check failures
- Update apps/workflows/tsconfig.app.json to include 'bun' types
- Resolves: Cannot find module 'bun' error in GitHub Actions

The CI environment needs explicit @types/bun since Bun's built-in
types aren't available during tsc type-checking in GitHub Actions.
Local development works fine, but CI requires the types package.
@github-actions
Copy link

⚠️ Large PR Warning

This PR is quite large with:

  • 31 changed files
  • 4069 added lines
  • 90 deleted lines

Consider breaking it down into smaller, focused PRs for easier review.

@thoroc thoroc merged commit d2a73b8 into main Jan 16, 2026
4 checks passed
@thoroc thoroc deleted the feature/complete-mirror-implementation branch January 16, 2026 00:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants