Add automated client fork creation workflow #79

Merged
Copilot merged 7 commits from copilot/create-readme-template into main 2026-02-20 02:00:06 +00:00
Copilot commented 2026-02-20 01:04:10 +00:00 (Migrated from github.com)

Pull Request

Purpose

Automate client fork setup: copy custom color templates, replace documentation, create properly-named branch. Reduces manual 20-minute process to 2-minute workflow execution.

Change Summary

Automation (2 methods)

  1. GitHub Actions workflow (.github/workflows/create-client-fork.yml)

    • Manual dispatch with client name input
    • Creates branch: client-fork/{client-slug}
    • Permissions: contents: write (minimal)
  2. Local bash script (scripts/create-client-fork.sh)

    • Interactive CLI with safety confirmations
    • Identical operations, portable (Linux/macOS/Git Bash)

Operations

  • Copy templates/colors_custom.csssrc/media/css/colors/{light,dark}/colors_custom.css
  • Replace README.md with customized CLIENT_FORK_README.md (client name, date)
  • Remove CLIENT_FORK_README.md and templates/CLIENT_FORK_README_TEMPLATE.md
  • Keep templates/colors_custom.css (reference template)

Documentation

  • docs/CLIENT_FORK_WORKFLOW.md: Complete usage guide for both methods
  • Updated cross-references in README.md, docs/README.md, CLIENT_FORK_README.md

Testing Evidence

  • YAML validated with yamllint (relaxed mode, line-length warnings only)
  • CodeQL: 0 alerts after adding permissions
  • Code review: 0 issues

Risk and Rollback

Risk: None. Additive changes only—no modification to existing fork workflows.

Rollback: Delete .github/workflows/create-client-fork.yml, scripts/create-client-fork.sh, docs/CLIENT_FORK_WORKFLOW.md. Revert documentation updates.

Checklist

  • Follows Conventional Commits
  • Tests added or updated (N/A - automation workflow)
  • Documentation updated if required
  • License header present where applicable
  • Linked issue(s) referenced

Reviewer Notes

Workflow requires "CONFIRM" input—prevents accidental execution.

Branch naming convention: client-fork/{lowercase-hyphenated-name} (e.g., client-fork/acme-corporation).

Post-workflow: Users customize colors in newly-created colors_custom.css files, then push branch to new client repository.

Review and Approval

Standard review process applies.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

# Pull Request ## Purpose Automate client fork setup: copy custom color templates, replace documentation, create properly-named branch. Reduces manual 20-minute process to 2-minute workflow execution. ## Change Summary **Automation (2 methods)** 1. GitHub Actions workflow (`.github/workflows/create-client-fork.yml`) - Manual dispatch with client name input - Creates branch: `client-fork/{client-slug}` - Permissions: `contents: write` (minimal) 2. Local bash script (`scripts/create-client-fork.sh`) - Interactive CLI with safety confirmations - Identical operations, portable (Linux/macOS/Git Bash) **Operations** - Copy `templates/colors_custom.css` → `src/media/css/colors/{light,dark}/colors_custom.css` - Replace `README.md` with customized `CLIENT_FORK_README.md` (client name, date) - Remove `CLIENT_FORK_README.md` and `templates/CLIENT_FORK_README_TEMPLATE.md` - Keep `templates/colors_custom.css` (reference template) **Documentation** - `docs/CLIENT_FORK_WORKFLOW.md`: Complete usage guide for both methods - Updated cross-references in `README.md`, `docs/README.md`, `CLIENT_FORK_README.md` ## Testing Evidence - YAML validated with yamllint (relaxed mode, line-length warnings only) - CodeQL: 0 alerts after adding permissions - Code review: 0 issues ## Risk and Rollback **Risk**: None. Additive changes only—no modification to existing fork workflows. **Rollback**: Delete `.github/workflows/create-client-fork.yml`, `scripts/create-client-fork.sh`, `docs/CLIENT_FORK_WORKFLOW.md`. Revert documentation updates. ## Checklist - [x] Follows Conventional Commits - [x] Tests added or updated (N/A - automation workflow) - [x] Documentation updated if required - [x] License header present where applicable - [x] Linked issue(s) referenced ## Reviewer Notes **Workflow requires "CONFIRM" input**—prevents accidental execution. Branch naming convention: `client-fork/{lowercase-hyphenated-name}` (e.g., `client-fork/acme-corporation`). Post-workflow: Users customize colors in newly-created `colors_custom.css` files, then push branch to new client repository. ## Review and Approval Standard review process applies. <!-- START COPILOT CODING AGENT TIPS --> --- 💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more [Copilot coding agent tips](https://gh.io/copilot-coding-agent-tips) in the docs.
jmiller-moko (Migrated from github.com) reviewed 2026-02-20 01:04:10 +00:00
github-advanced-security[bot] (Migrated from github.com) reviewed 2026-02-20 01:38:49 +00:00
@@ -0,0 +1,152 @@
---
github-advanced-security[bot] (Migrated from github.com) commented 2026-02-20 01:38:49 +00:00

Workflow does not contain permissions

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {{contents: read}}

Show more details

## Workflow does not contain permissions Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {{contents: read}} [Show more details](https://github.com/mokoconsulting-tech/MokoCassiopeia/security/code-scanning/1)
github-advanced-security[bot] (Migrated from github.com) reviewed 2026-02-20 01:40:22 +00:00
@@ -0,0 +1,152 @@
---
github-advanced-security[bot] (Migrated from github.com) commented 2026-02-20 01:40:22 +00:00

Workflow does not contain permissions

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {{contents: read}}

Show more details

## Workflow does not contain permissions Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {{contents: read}} [Show more details](https://github.com/mokoconsulting-tech/MokoCassiopeia/security/code-scanning/2)
copilot-pull-request-reviewer[bot] (Migrated from github.com) reviewed 2026-02-20 02:07:48 +00:00
copilot-pull-request-reviewer[bot] (Migrated from github.com) left a comment

Pull request overview

Adds an automated “client fork setup” capability to the MokoCassiopeia repo (GitHub Actions + local script), along with templates and documentation to standardize how client-specific forks are created and documented.

Changes:

  • Introduces a GitHub Actions workflow to generate a client-fork/{client-slug} branch and apply fork setup steps automatically.
  • Adds a local bash script alternative that performs the same fork setup steps interactively.
  • Adds/updates documentation and templates for client fork workflows and fork README guidance.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
.github/workflows/create-client-fork.yml New workflow to create a client-fork branch, copy custom color templates, replace README, delete template docs, commit, and push.
scripts/create-client-fork.sh New interactive local script to perform the same fork setup steps.
docs/CLIENT_FORK_WORKFLOW.md New end-to-end documentation describing both automation methods and post-setup steps.
docs/README.md Adds a “Client Fork Documentation” section and updates the project structure tree to include templates/workflow docs.
README.md Adds links/sections pointing users to the client fork workflow and guide.
CLIENT_FORK_README.md Adds a comprehensive client fork guide/template intended to be transformed into the fork’s root README.
templates/README.md Adds documentation for what’s inside /templates and how to use the templates.
templates/CLIENT_FORK_README_TEMPLATE.md Adds a lightweight README template for client forks.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

## Pull request overview Adds an automated “client fork setup” capability to the MokoCassiopeia repo (GitHub Actions + local script), along with templates and documentation to standardize how client-specific forks are created and documented. **Changes:** - Introduces a GitHub Actions workflow to generate a `client-fork/{client-slug}` branch and apply fork setup steps automatically. - Adds a local bash script alternative that performs the same fork setup steps interactively. - Adds/updates documentation and templates for client fork workflows and fork README guidance. ### Reviewed changes Copilot reviewed 8 out of 8 changed files in this pull request and generated 10 comments. <details> <summary>Show a summary per file</summary> | File | Description | | ---- | ----------- | | `.github/workflows/create-client-fork.yml` | New workflow to create a client-fork branch, copy custom color templates, replace README, delete template docs, commit, and push. | | `scripts/create-client-fork.sh` | New interactive local script to perform the same fork setup steps. | | `docs/CLIENT_FORK_WORKFLOW.md` | New end-to-end documentation describing both automation methods and post-setup steps. | | `docs/README.md` | Adds a “Client Fork Documentation” section and updates the project structure tree to include templates/workflow docs. | | `README.md` | Adds links/sections pointing users to the client fork workflow and guide. | | `CLIENT_FORK_README.md` | Adds a comprehensive client fork guide/template intended to be transformed into the fork’s root README. | | `templates/README.md` | Adds documentation for what’s inside `/templates` and how to use the templates. | | `templates/CLIENT_FORK_README_TEMPLATE.md` | Adds a lightweight README template for client forks. | </details> --- 💡 <a href="/mokoconsulting-tech/MokoCassiopeia/new/main/.github/instructions?filename=*.instructions.md" class="Link--inTextBlock" target="_blank" rel="noopener noreferrer">Add Copilot custom instructions</a> for smarter, more guided reviews. <a href="https://docs.github.com/en/copilot/customizing-copilot/adding-repository-custom-instructions-for-github-copilot" class="Link--inTextBlock" target="_blank" rel="noopener noreferrer">Learn how to get started</a>.
@@ -0,0 +46,4 @@
- name: Create client fork branch
run: |
CLIENT_NAME="${{ inputs.client_name }}"
CLIENT_SLUG=$(echo "${CLIENT_NAME}" | tr '[:upper:]' '[:lower:]' | tr ' ' '-')
copilot-pull-request-reviewer[bot] (Migrated from github.com) commented 2026-02-20 02:07:46 +00:00

CLIENT_SLUG is derived only by lowercasing and replacing spaces. Client names containing characters like /, &, ., or multiple whitespace can produce invalid git branch names (and could also lead to awkward paths in automation output). Consider sanitizing to [a-z0-9-], collapsing runs of -, and trimming leading/trailing dashes before forming BRANCH_NAME.

          CLIENT_SLUG=$(
            printf '%s' "${CLIENT_NAME}" \
              | tr '[:upper:]' '[:lower:]' \
              | sed -E 's/[^a-z0-9]+/-/g; s/^-+//; s/-+$//'
          )
`CLIENT_SLUG` is derived only by lowercasing and replacing spaces. Client names containing characters like `/`, `&`, `.`, or multiple whitespace can produce invalid git branch names (and could also lead to awkward paths in automation output). Consider sanitizing to `[a-z0-9-]`, collapsing runs of `-`, and trimming leading/trailing dashes before forming `BRANCH_NAME`. ```suggestion CLIENT_SLUG=$( printf '%s' "${CLIENT_NAME}" \ | tr '[:upper:]' '[:lower:]' \ | sed -E 's/[^a-z0-9]+/-/g; s/^-+//; s/-+$//' ) ```
@@ -0,0 +47,4 @@
run: |
CLIENT_NAME="${{ inputs.client_name }}"
CLIENT_SLUG=$(echo "${CLIENT_NAME}" | tr '[:upper:]' '[:lower:]' | tr ' ' '-')
BRANCH_NAME="client-fork/${CLIENT_SLUG}"
copilot-pull-request-reviewer[bot] (Migrated from github.com) commented 2026-02-20 02:07:47 +00:00

git checkout -b "${BRANCH_NAME}" will fail if the branch already exists (e.g., reruns for the same client). Consider adding an explicit existence check and emitting a clear ::error:: message (or switching to git checkout -B if overwriting is acceptable) so the failure mode is predictable.

          BRANCH_NAME="client-fork/${CLIENT_SLUG}"
          if git rev-parse --verify "${BRANCH_NAME}" >/dev/null 2>&1; then
            echo "::error::Branch ${BRANCH_NAME} already exists. Aborting to avoid overwriting existing client fork."
            exit 1
          fi
`git checkout -b "${BRANCH_NAME}"` will fail if the branch already exists (e.g., reruns for the same client). Consider adding an explicit existence check and emitting a clear `::error::` message (or switching to `git checkout -B` if overwriting is acceptable) so the failure mode is predictable. ```suggestion BRANCH_NAME="client-fork/${CLIENT_SLUG}" if git rev-parse --verify "${BRANCH_NAME}" >/dev/null 2>&1; then echo "::error::Branch ${BRANCH_NAME} already exists. Aborting to avoid overwriting existing client fork." exit 1 fi ```
@@ -0,0 +80,4 @@
CURRENT_DATE=$(date +"%Y-%m-%d")
sed -i "s/\[DATE\]/${CURRENT_DATE}/g" README.md
sed -i "s/\[YOUR-FORK-URL\]/https:\/\/github.com\/${GITHUB_REPOSITORY}/g" README.md
copilot-pull-request-reviewer[bot] (Migrated from github.com) commented 2026-02-20 02:07:48 +00:00

The sed replacement uses the raw inputs.client_name as the replacement string. If the client name contains characters meaningful to sed replacements (e.g., &, /, or backslashes), README generation can break or produce incorrect output. Escape the replacement string before substituting, or use a tool/approach that safely handles arbitrary text.

The sed replacement uses the raw `inputs.client_name` as the replacement string. If the client name contains characters meaningful to sed replacements (e.g., `&`, `/`, or backslashes), README generation can break or produce incorrect output. Escape the replacement string before substituting, or use a tool/approach that safely handles arbitrary text.
@@ -0,0 +99,4 @@
if [ -f "templates/README.md" ]; then
sed -i '/CLIENT_FORK_README_TEMPLATE.md/d' templates/README.md
sed -i '/Client Fork README Template/,/^---$/d' templates/README.md
copilot-pull-request-reviewer[bot] (Migrated from github.com) commented 2026-02-20 02:07:47 +00:00

The workflow removes CLIENT_FORK_README.md but the templates/README.md edits only remove the client fork template section. templates/README.md still contains links/instructions pointing to ../CLIENT_FORK_README.md, which will be broken after deletion. Update the cleanup step to remove or rewrite all references to files that are deleted in the fork branch.

            sed -i '/Client Fork README Template/,/^---$/d' templates/README.md
            sed -i '/CLIENT_FORK_README.md/d' templates/README.md
The workflow removes `CLIENT_FORK_README.md` but the `templates/README.md` edits only remove the client fork template section. `templates/README.md` still contains links/instructions pointing to `../CLIENT_FORK_README.md`, which will be broken after deletion. Update the cleanup step to remove or rewrite all references to files that are deleted in the fork branch. ```suggestion sed -i '/Client Fork README Template/,/^---$/d' templates/README.md sed -i '/CLIENT_FORK_README.md/d' templates/README.md ```
@@ -0,0 +119,4 @@
-m "Removed CLIENT_FORK_README.md" \
-m "Removed templates/CLIENT_FORK_README_TEMPLATE.md" \
-m "Kept templates/colors_custom.css as template"
echo "✓ Changes committed"
copilot-pull-request-reviewer[bot] (Migrated from github.com) commented 2026-02-20 02:07:46 +00:00

The custom color files you copy into src/media/css/colors/*/colors_custom.css are ignored by .gitignore, so git add . will not stage them and the fork branch won’t actually contain the generated color files. Force-add just those files (e.g., explicit git add -f <paths>), or adjust the workflow to temporarily override the ignore rules before committing.

The custom color files you copy into src/media/css/colors/*/colors_custom.css are ignored by .gitignore, so `git add .` will not stage them and the fork branch won’t actually contain the generated color files. Force-add just those files (e.g., explicit `git add -f <paths>`), or adjust the workflow to temporarily override the ignore rules before committing.
@@ -0,0 +32,4 @@
fi
CLIENT_NAME="$1"
CLIENT_SLUG=$(echo "${CLIENT_NAME}" | tr '[:upper:]' '[:lower:]' | tr ' ' '-')
copilot-pull-request-reviewer[bot] (Migrated from github.com) commented 2026-02-20 02:07:47 +00:00

CLIENT_SLUG only lowercases and replaces spaces, so client names with punctuation or characters like / can generate invalid git branch names. Sanitize the slug to an allowlist (e.g., [a-z0-9-]), collapse repeated -, and trim leading/trailing dashes before creating BRANCH_NAME.

CLIENT_SLUG=$(echo "${CLIENT_NAME}" \
    | tr '[:upper:]' '[:lower:]' \
    | sed -e 's/[^a-z0-9]/-/g' \
          -e 's/-\{2,\}/-/g' \
          -e 's/^-//' \
          -e 's/-$//')

if [ -z "${CLIENT_SLUG}" ]; then
    print_error "Client name '${CLIENT_NAME}' results in an empty slug after sanitization."
    exit 1
fi
`CLIENT_SLUG` only lowercases and replaces spaces, so client names with punctuation or characters like `/` can generate invalid git branch names. Sanitize the slug to an allowlist (e.g., `[a-z0-9-]`), collapse repeated `-`, and trim leading/trailing dashes before creating `BRANCH_NAME`. ```suggestion CLIENT_SLUG=$(echo "${CLIENT_NAME}" \ | tr '[:upper:]' '[:lower:]' \ | sed -e 's/[^a-z0-9]/-/g' \ -e 's/-\{2,\}/-/g' \ -e 's/^-//' \ -e 's/-$//') if [ -z "${CLIENT_SLUG}" ]; then print_error "Client name '${CLIENT_NAME}' results in an empty slug after sanitization." exit 1 fi ```
@@ -0,0 +61,4 @@
# Create new branch
print_info "Creating branch: ${BRANCH_NAME}"
git checkout -b "${BRANCH_NAME}"
print_success "Branch created"
copilot-pull-request-reviewer[bot] (Migrated from github.com) commented 2026-02-20 02:07:46 +00:00

The script creates a new branch immediately, but it doesn’t verify the working tree is clean first. If the user has unrelated local changes, they may be unintentionally carried into the client fork branch/commit. Consider failing early when git status --porcelain is non-empty (and/or stage only the specific expected files rather than git add .).

The script creates a new branch immediately, but it doesn’t verify the working tree is clean first. If the user has unrelated local changes, they may be unintentionally carried into the client fork branch/commit. Consider failing early when `git status --porcelain` is non-empty (and/or stage only the specific expected files rather than `git add .`).
@@ -0,0 +79,4 @@
# Replace README with client fork README
print_info "Replacing README.md with CLIENT_FORK_README.md..."
sed "s/\[CLIENT NAME\]/${CLIENT_NAME}/g" CLIENT_FORK_README.md > README.md.new
mv README.md.new README.md
copilot-pull-request-reviewer[bot] (Migrated from github.com) commented 2026-02-20 02:07:48 +00:00

The sed replacement uses ${CLIENT_NAME} unescaped as the replacement string. Names containing &, /, or backslashes can break the substitution or yield incorrect README content. Escape the replacement string (and ideally use a delimiter that avoids common characters) before running sed.

The sed replacement uses `${CLIENT_NAME}` unescaped as the replacement string. Names containing `&`, `/`, or backslashes can break the substitution or yield incorrect README content. Escape the replacement string (and ideally use a delimiter that avoids common characters) before running sed.
@@ -0,0 +113,4 @@
rm -f templates/README.md.bak
print_success "Updated templates/README.md"
fi
copilot-pull-request-reviewer[bot] (Migrated from github.com) commented 2026-02-20 02:07:48 +00:00

This update to templates/README.md only deletes lines containing CLIENT_FORK_README_TEMPLATE.md, which will leave an incomplete/broken section (headings and instructions remain but the referenced file is deleted). Match the workflow behavior by removing the entire client-fork template section and any other references to files you delete during setup.

This update to `templates/README.md` only deletes lines containing `CLIENT_FORK_README_TEMPLATE.md`, which will leave an incomplete/broken section (headings and instructions remain but the referenced file is deleted). Match the workflow behavior by removing the entire client-fork template section and any other references to files you delete during setup.
@@ -0,0 +135,4 @@
- Removed CLIENT_FORK_README.md and templates/CLIENT_FORK_README_TEMPLATE.md
- Kept templates/colors_custom.css as template
This commit prepares the repository for ${CLIENT_NAME}'s custom fork."
copilot-pull-request-reviewer[bot] (Migrated from github.com) commented 2026-02-20 02:07:47 +00:00

The custom color files copied into src/media/css/colors/{light,dark}/colors_custom.css are ignored by this repo’s .gitignore, so git add . will not stage them. If the goal is for client forks to track these files, force-add those specific paths (or modify ignore rules as part of the fork setup) before committing.

The custom color files copied into `src/media/css/colors/{light,dark}/colors_custom.css` are ignored by this repo’s `.gitignore`, so `git add .` will not stage them. If the goal is for client forks to track these files, force-add those specific paths (or modify ignore rules as part of the fork setup) before committing.
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: MokoConsulting/MokoCassiopeia#79