Template
Compare commits
31 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 657b122736 | |||
| bacb977fac | |||
| fec05ff9ac | |||
| ff156d3df8 | |||
| bc80d64de0 | |||
| ee2590e1e9 | |||
| 6e5322bd27 | |||
| 7a7d855d1e | |||
| 6a3e066b4b | |||
| 5d4ca460fb | |||
| e2d82f294e | |||
| 9a1c1cd37d | |||
| d316fe89b5 | |||
| 42f6730a4c | |||
| 03f41cc0d0 | |||
| 587c0fc5b7 | |||
| c4c008feff | |||
| bcb4698213 | |||
| a5c7dc4040 | |||
| 7b4a1533f7 | |||
| 98d2303ebd | |||
| c4fc5fd0b9 | |||
| 92b76c4a22 | |||
| 31718da51a | |||
| b51b8698d9 | |||
| f983d3771b | |||
| 9ed5e2a6ed | |||
| 0f72a807be | |||
| f117c0de0f | |||
| 27fc4dddcf | |||
| 5cea5c5b6b |
+1
-1
@@ -41,7 +41,7 @@
|
|||||||
# CI and automation
|
# CI and automation
|
||||||
.github/ export-ignore
|
.github/ export-ignore
|
||||||
.github/workflows/ export-ignore
|
.github/workflows/ export-ignore
|
||||||
.gitea/ export-ignore
|
.mokogit/ export-ignore
|
||||||
.gitlab/ export-ignore
|
.gitlab/ export-ignore
|
||||||
|
|
||||||
# Development and tooling
|
# Development and tooling
|
||||||
|
|||||||
@@ -205,6 +205,14 @@ hypothesis/
|
|||||||
profile.ps1
|
profile.ps1
|
||||||
.mcp.json
|
.mcp.json
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
# AI client working directories and instruction files
|
||||||
|
# ============================================================
|
||||||
|
.gemini/
|
||||||
|
.mokoai/
|
||||||
|
/GEMINI.md
|
||||||
|
/MOKOAI.md
|
||||||
|
|
||||||
# ============================================================
|
# ============================================================
|
||||||
# Local wiki clone (not version controlled)
|
# Local wiki clone (not version controlled)
|
||||||
# ============================================================
|
# ============================================================
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
# {{REPO_NAME}}
|
||||||
|
|
||||||
|
{{REPO_DESCRIPTION}}
|
||||||
|
|
||||||
|
> AI-client instructions for **Gemini**. Mirrors `.mokogit/CLAUDE.md` — keep CLAUDE.md, GEMINI.md, and MOKOAI.md in sync.
|
||||||
|
|
||||||
|
## First-Run Setup
|
||||||
|
|
||||||
|
> Before starting any work, complete these steps:
|
||||||
|
>
|
||||||
|
> 1. Replace all `{{REPO_NAME}}` placeholders with the actual repository name
|
||||||
|
> 2. Replace `{{REPO_DESCRIPTION}}` with a one-line project description
|
||||||
|
> 3. Replace `{{PLATFORM_TYPE}}` with the project type (e.g. `generic`, `npm`, `joomla`)
|
||||||
|
> 4. Replace `{{PRIMARY_LANGUAGE}}` with the dominant language
|
||||||
|
> 5. Set repository metadata via the MokoGIT **Metadata** field — repository **Settings → Metadata**, or the REST API `PUT /api/v1/repos/{owner}/{repo}/manifest` (identity, platform, language, package-type, entry-point). There is no metadata file in the repo.
|
||||||
|
> 6. Update the **Architecture** section for your project
|
||||||
|
> 7. Update the Commands section with actual build commands
|
||||||
|
> 8. Delete this setup block after completing all steps
|
||||||
|
> 9. Commit: `chore: initialize {{REPO_NAME}}`
|
||||||
|
|
||||||
|
## Quick Reference
|
||||||
|
|
||||||
|
| Field | Value |
|
||||||
|
|---|---|
|
||||||
|
| **Platform** | {{PLATFORM_TYPE}} |
|
||||||
|
| **Language** | {{PRIMARY_LANGUAGE}} |
|
||||||
|
| **Branch** | develop on `dev`, merge to `main` (protected) |
|
||||||
|
| **Wiki** | [Wiki](https://git.mokoconsulting.tech/MokoConsulting/{{REPO_NAME}}/wiki) |
|
||||||
|
|
||||||
|
## Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make build # Build the project
|
||||||
|
make lint # Run linters
|
||||||
|
make validate # Validate structure
|
||||||
|
make release # Full release pipeline
|
||||||
|
make clean # Clean build artifacts
|
||||||
|
```
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
<!-- Update this section for your project -->
|
||||||
|
|
||||||
|
## Rules
|
||||||
|
|
||||||
|
- **Never commit** `.gemini/`, `.mcp.json`, `TODO.md`, `*.min.css`/`*.min.js`
|
||||||
|
- **Attribution**: `Authored-by: Moko Consulting`
|
||||||
|
- **Workflow directory**: `.mokogit/` (not `.gitea/` or `.github/`)
|
||||||
|
- **Metadata**: set via the MokoGIT **Metadata** field (API / Settings → Metadata), never a committed manifest file
|
||||||
|
- **Wiki**: documentation lives in the MokoGIT wiki, not `docs/` files
|
||||||
|
- **Standards**: [MokoCLI](https://git.mokoconsulting.tech/MokoConsulting/mokocli/wiki/Home)
|
||||||
@@ -7,8 +7,8 @@ contact_links:
|
|||||||
- name: 💬 Ask a Question
|
- name: 💬 Ask a Question
|
||||||
url: https://mokoconsulting.tech/
|
url: https://mokoconsulting.tech/
|
||||||
about: Get help or ask questions through our website
|
about: Get help or ask questions through our website
|
||||||
- name: 📚 MokoStandards Documentation
|
- name: 📚 MokoCLI Documentation
|
||||||
url: https://git.mokoconsulting.tech/MokoConsulting/MokoCLI
|
url: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
||||||
about: View our coding standards and best practices
|
about: View our coding standards and best practices
|
||||||
- name: 🔒 Report a Security Vulnerability
|
- name: 🔒 Report a Security Vulnerability
|
||||||
url: https://git.mokoconsulting.tech/MokoConsulting/.github-private/security/advisories/new
|
url: https://git.mokoconsulting.tech/MokoConsulting/.github-private/security/advisories/new
|
||||||
+1
-1
@@ -42,7 +42,7 @@ Suggested text here
|
|||||||
<!-- Add any other context, screenshots, or references -->
|
<!-- Add any other context, screenshots, or references -->
|
||||||
|
|
||||||
## Standards Alignment
|
## Standards Alignment
|
||||||
- [ ] Follows MokoStandards documentation guidelines
|
- [ ] Follows MokoCLI documentation guidelines
|
||||||
- [ ] Uses en_US/en_GB localization
|
- [ ] Uses en_US/en_GB localization
|
||||||
- [ ] Includes proper SPDX headers where applicable
|
- [ ] Includes proper SPDX headers where applicable
|
||||||
|
|
||||||
+1
-1
@@ -37,7 +37,7 @@ If you have ideas about how this could be implemented, share them here:
|
|||||||
Add any other context, mockups, or screenshots about the feature request here.
|
Add any other context, mockups, or screenshots about the feature request here.
|
||||||
|
|
||||||
## Relevant Standards
|
## Relevant Standards
|
||||||
Does this relate to any standards in [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/MokoStandards)?
|
Does this relate to any standards in [MokoCLI](https://git.mokoconsulting.tech/MokoConsulting/mokocli)?
|
||||||
- [ ] Accessibility (WCAG 2.1 AA)
|
- [ ] Accessibility (WCAG 2.1 AA)
|
||||||
- [ ] Localization (en_US/en_GB)
|
- [ ] Localization (en_US/en_GB)
|
||||||
- [ ] Security best practices
|
- [ ] Security best practices
|
||||||
+1
-1
@@ -45,4 +45,4 @@ Are there other ways to accomplish this today? If so, why is an MCP integration
|
|||||||
- [ ] API documentation is available and accessible
|
- [ ] API documentation is available and accessible
|
||||||
- [ ] API supports the required authentication method
|
- [ ] API supports the required authentication method
|
||||||
- [ ] I have tested the API endpoints manually
|
- [ ] I have tested the API endpoints manually
|
||||||
- [ ] The integration follows the Template-MCP architecture pattern
|
- [ ] The integration follows the Template-NPM architecture pattern
|
||||||
@@ -35,7 +35,7 @@ Use this template only for:
|
|||||||
<!-- Describe how this could be addressed -->
|
<!-- Describe how this could be addressed -->
|
||||||
|
|
||||||
## Standards Reference
|
## Standards Reference
|
||||||
Does this relate to security standards in [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/MokoStandards)?
|
Does this relate to security standards in [MokoCLI](https://git.mokoconsulting.tech/MokoConsulting/mokocli)?
|
||||||
- [ ] SPDX license identifiers
|
- [ ] SPDX license identifiers
|
||||||
- [ ] Secret management
|
- [ ] Secret management
|
||||||
- [ ] Dependency security
|
- [ ] Dependency security
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
# {{REPO_NAME}}
|
||||||
|
|
||||||
|
{{REPO_DESCRIPTION}}
|
||||||
|
|
||||||
|
> AI-client instructions for **MokoAI**. Mirrors `.mokogit/CLAUDE.md` — keep CLAUDE.md, GEMINI.md, and MOKOAI.md in sync.
|
||||||
|
|
||||||
|
## First-Run Setup
|
||||||
|
|
||||||
|
> Before starting any work, complete these steps:
|
||||||
|
>
|
||||||
|
> 1. Replace all `{{REPO_NAME}}` placeholders with the actual repository name
|
||||||
|
> 2. Replace `{{REPO_DESCRIPTION}}` with a one-line project description
|
||||||
|
> 3. Replace `{{PLATFORM_TYPE}}` with the project type (e.g. `generic`, `npm`, `joomla`)
|
||||||
|
> 4. Replace `{{PRIMARY_LANGUAGE}}` with the dominant language
|
||||||
|
> 5. Set repository metadata via the MokoGIT **Metadata** field — repository **Settings → Metadata**, or the REST API `PUT /api/v1/repos/{owner}/{repo}/manifest` (identity, platform, language, package-type, entry-point). There is no metadata file in the repo.
|
||||||
|
> 6. Update the **Architecture** section for your project
|
||||||
|
> 7. Update the Commands section with actual build commands
|
||||||
|
> 8. Delete this setup block after completing all steps
|
||||||
|
> 9. Commit: `chore: initialize {{REPO_NAME}}`
|
||||||
|
|
||||||
|
## Quick Reference
|
||||||
|
|
||||||
|
| Field | Value |
|
||||||
|
|---|---|
|
||||||
|
| **Platform** | {{PLATFORM_TYPE}} |
|
||||||
|
| **Language** | {{PRIMARY_LANGUAGE}} |
|
||||||
|
| **Branch** | develop on `dev`, merge to `main` (protected) |
|
||||||
|
| **Wiki** | [Wiki](https://git.mokoconsulting.tech/MokoConsulting/{{REPO_NAME}}/wiki) |
|
||||||
|
|
||||||
|
## Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make build # Build the project
|
||||||
|
make lint # Run linters
|
||||||
|
make validate # Validate structure
|
||||||
|
make release # Full release pipeline
|
||||||
|
make clean # Clean build artifacts
|
||||||
|
```
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
<!-- Update this section for your project -->
|
||||||
|
|
||||||
|
## Rules
|
||||||
|
|
||||||
|
- **Never commit** `.mokoai/`, `.mcp.json`, `TODO.md`, `*.min.css`/`*.min.js`
|
||||||
|
- **Attribution**: `Authored-by: Moko Consulting`
|
||||||
|
- **Workflow directory**: `.mokogit/` (not `.gitea/` or `.github/`)
|
||||||
|
- **Metadata**: set via the MokoGIT **Metadata** field (API / Settings → Metadata), never a committed manifest file
|
||||||
|
- **Wiki**: documentation lives in the MokoGIT wiki, not `docs/` files
|
||||||
|
- **Standards**: [MokoCLI](https://git.mokoconsulting.tech/MokoConsulting/mokocli/wiki/Home)
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
# Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
# Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
# FILE INFORMATION
|
# FILE INFORMATION
|
||||||
# DEFGROUP: Gitea.Workflow
|
# DEFGROUP: MokoGIT.Workflow
|
||||||
# INGROUP: mokocli.Automation
|
# INGROUP: MokoCLI.Automation
|
||||||
# REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoCLI
|
# REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
||||||
# PATH: /.gitea/workflows/branch-protection.yml
|
# PATH: /.mokogit/workflows/branch-protection.yml
|
||||||
# BRIEF: Apply standardised branch protection rules to all governed repositories
|
# BRIEF: Apply standardised branch protection rules to all governed repositories
|
||||||
#
|
#
|
||||||
# +========================================================================+
|
# +========================================================================+
|
||||||
@@ -42,8 +42,8 @@ on:
|
|||||||
default: ''
|
default: ''
|
||||||
|
|
||||||
env:
|
env:
|
||||||
GITEA_URL: https://git.mokoconsulting.tech
|
GIT_URL: https://git.mokoconsulting.tech
|
||||||
GITEA_ORG: MokoConsulting
|
GIT_ORG: MokoConsulting
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
@@ -59,11 +59,11 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
GA_TOKEN: ${{ secrets.GA_TOKEN }}
|
GA_TOKEN: ${{ secrets.GA_TOKEN }}
|
||||||
run: |
|
run: |
|
||||||
API="${GITEA_URL}/api/v1"
|
API="${GIT_URL}/api/v1"
|
||||||
|
|
||||||
# Platform/standards/infra repos to exclude
|
# Platform/standards/infra repos to exclude
|
||||||
EXCLUDE="gitea-org-config org-profile gitea-private .mokogitea-private MokoStandards mokocli MokoTesting"
|
EXCLUDE="git-org-config org-profile git-private .mokogit-private mokocli MokoTesting"
|
||||||
EXCLUDE="$EXCLUDE MokoStandards-Template-Client MokoStandards-Template-Dolibarr MokoStandards-Template-Generic MokoStandards-Template-Joomla MokoDoliProjTemplate"
|
EXCLUDE="$EXCLUDE Template-Client Template-Dolibarr Template-Generic Template-Joomla MokoDoliProjTemplate"
|
||||||
|
|
||||||
if [ -n "${{ inputs.repos }}" ]; then
|
if [ -n "${{ inputs.repos }}" ]; then
|
||||||
# User-specified repos
|
# User-specified repos
|
||||||
@@ -75,7 +75,7 @@ jobs:
|
|||||||
while true; do
|
while true; do
|
||||||
BATCH=$(curl -sS \
|
BATCH=$(curl -sS \
|
||||||
-H "Authorization: token ${GA_TOKEN}" \
|
-H "Authorization: token ${GA_TOKEN}" \
|
||||||
"${API}/orgs/${GITEA_ORG}/repos?page=${PAGE}&limit=50" \
|
"${API}/orgs/${GIT_ORG}/repos?page=${PAGE}&limit=50" \
|
||||||
| jq -r '.[].name // empty')
|
| jq -r '.[].name // empty')
|
||||||
[ -z "$BATCH" ] && break
|
[ -z "$BATCH" ] && break
|
||||||
REPOS="$REPOS $BATCH"
|
REPOS="$REPOS $BATCH"
|
||||||
@@ -108,7 +108,7 @@ jobs:
|
|||||||
GA_TOKEN: ${{ secrets.GA_TOKEN }}
|
GA_TOKEN: ${{ secrets.GA_TOKEN }}
|
||||||
DRY_RUN: ${{ inputs.dry_run || 'false' }}
|
DRY_RUN: ${{ inputs.dry_run || 'false' }}
|
||||||
run: |
|
run: |
|
||||||
API="${GITEA_URL}/api/v1"
|
API="${GIT_URL}/api/v1"
|
||||||
REPOS="${{ steps.repos.outputs.repos }}"
|
REPOS="${{ steps.repos.outputs.repos }}"
|
||||||
|
|
||||||
SUCCESS=0
|
SUCCESS=0
|
||||||
@@ -215,7 +215,7 @@ jobs:
|
|||||||
curl -sS -o /dev/null -w "" \
|
curl -sS -o /dev/null -w "" \
|
||||||
-X DELETE \
|
-X DELETE \
|
||||||
-H "Authorization: token ${GA_TOKEN}" \
|
-H "Authorization: token ${GA_TOKEN}" \
|
||||||
"${API}/repos/${GITEA_ORG}/${REPO}/branch_protections/${ENCODED_NAME}" 2>/dev/null || true
|
"${API}/repos/${GIT_ORG}/${REPO}/branch_protections/${ENCODED_NAME}" 2>/dev/null || true
|
||||||
|
|
||||||
# Create rule
|
# Create rule
|
||||||
RESPONSE=$(curl -sS -w "\n%{http_code}" \
|
RESPONSE=$(curl -sS -w "\n%{http_code}" \
|
||||||
@@ -223,7 +223,7 @@ jobs:
|
|||||||
-H "Authorization: token ${GA_TOKEN}" \
|
-H "Authorization: token ${GA_TOKEN}" \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
-d "$RULE" \
|
-d "$RULE" \
|
||||||
"${API}/repos/${GITEA_ORG}/${REPO}/branch_protections")
|
"${API}/repos/${GIT_ORG}/${REPO}/branch_protections")
|
||||||
|
|
||||||
HTTP=$(echo "$RESPONSE" | tail -1)
|
HTTP=$(echo "$RESPONSE" | tail -1)
|
||||||
BODY=$(echo "$RESPONSE" | sed '$d')
|
BODY=$(echo "$RESPONSE" | sed '$d')
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
# Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
#
|
||||||
|
# FILE INFORMATION
|
||||||
|
# DEFGROUP: GitHub.Workflow
|
||||||
|
# INGROUP: MokoStandards.Workflows.Shared
|
||||||
|
# REPO: https://github.com/mokoconsulting-tech/MokoStandards
|
||||||
|
# PATH: /.mokogit/workflows/auto-assign.yml
|
||||||
|
# VERSION: 04.06.00
|
||||||
|
# BRIEF: Auto-assign jmiller to unassigned issues and PRs every 15 minutes
|
||||||
|
|
||||||
|
name: "Universal: Auto-Assign"
|
||||||
|
|
||||||
|
on:
|
||||||
|
issues:
|
||||||
|
types: [opened]
|
||||||
|
pull_request_target:
|
||||||
|
types: [opened]
|
||||||
|
schedule:
|
||||||
|
- cron: '0 */12 * * *'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
issues: write
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
auto-assign:
|
||||||
|
name: Assign unassigned issues and PRs
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Assign unassigned issues
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GH_TOKEN || github.token }}
|
||||||
|
run: |
|
||||||
|
REPO="${{ github.repository }}"
|
||||||
|
ASSIGNEE="jmiller"
|
||||||
|
|
||||||
|
echo "## 🏷️ Auto-Assign Report" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
|
ASSIGNED_ISSUES=0
|
||||||
|
ASSIGNED_PRS=0
|
||||||
|
|
||||||
|
# Assign unassigned open issues
|
||||||
|
ISSUES=$(gh api "repos/$REPO/issues?state=open&per_page=100&assignee=none" --jq '.[].number' 2>/dev/null || true)
|
||||||
|
for NUM in $ISSUES; do
|
||||||
|
# Skip PRs (the issues endpoint returns PRs too)
|
||||||
|
IS_PR=$(gh api "repos/$REPO/issues/$NUM" --jq '.pull_request // empty' 2>/dev/null || true)
|
||||||
|
if [ -z "$IS_PR" ]; then
|
||||||
|
gh api "repos/$REPO/issues/$NUM/assignees" -X POST -f "assignees[]=$ASSIGNEE" --silent 2>/dev/null && {
|
||||||
|
ASSIGNED_ISSUES=$((ASSIGNED_ISSUES + 1))
|
||||||
|
echo " Assigned issue #$NUM"
|
||||||
|
} || true
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Assign unassigned open PRs
|
||||||
|
PRS=$(gh api "repos/$REPO/pulls?state=open&per_page=100" --jq '.[] | select(.assignees | length == 0) | .number' 2>/dev/null || true)
|
||||||
|
for NUM in $PRS; do
|
||||||
|
gh api "repos/$REPO/issues/$NUM/assignees" -X POST -f "assignees[]=$ASSIGNEE" --silent 2>/dev/null && {
|
||||||
|
ASSIGNED_PRS=$((ASSIGNED_PRS + 1))
|
||||||
|
echo " Assigned PR #$NUM"
|
||||||
|
} || true
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "| Type | Assigned |" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "|------|----------|" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "| Issues | $ASSIGNED_ISSUES |" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "| Pull Requests | $ASSIGNED_PRS |" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
|
if [ "$ASSIGNED_ISSUES" -eq 0 ] && [ "$ASSIGNED_PRS" -eq 0 ]; then
|
||||||
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "✅ All issues and PRs already have assignees" >> $GITHUB_STEP_SUMMARY
|
||||||
|
fi
|
||||||
@@ -3,10 +3,10 @@
|
|||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
#
|
#
|
||||||
# FILE INFORMATION
|
# FILE INFORMATION
|
||||||
# DEFGROUP: Gitea.Workflow
|
# DEFGROUP: MokoGIT.Workflow
|
||||||
# INGROUP: mokocli.Release
|
# INGROUP: MokoCLI.Release
|
||||||
# REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoCLI
|
# REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
||||||
# PATH: /.mokogitea/workflows/auto-bump.yml
|
# PATH: /.mokogit/workflows/auto-bump.yml
|
||||||
# VERSION: 09.02.00
|
# VERSION: 09.02.00
|
||||||
# BRIEF: Auto patch-bump version on every push to dev (skips merge commits)
|
# BRIEF: Auto patch-bump version on every push to dev (skips merge commits)
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@ on:
|
|||||||
|
|
||||||
env:
|
env:
|
||||||
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
|
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
|
||||||
MOKOGITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
|
MOKOGIT_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
@@ -40,10 +40,10 @@ jobs:
|
|||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.MOKOGITEA_TOKEN }}
|
token: ${{ secrets.MOKOGIT_TOKEN }}
|
||||||
fetch-depth: 1
|
fetch-depth: 1
|
||||||
|
|
||||||
- name: Setup mokocli tools
|
- name: Setup MokoCLI tools
|
||||||
run: |
|
run: |
|
||||||
if ! command -v composer &> /dev/null; then
|
if ! command -v composer &> /dev/null; then
|
||||||
sudo apt-get update -qq && sudo apt-get install -y -qq php-cli php-mbstring php-xml php-zip php-curl composer >/dev/null 2>&1
|
sudo apt-get update -qq && sudo apt-get install -y -qq php-cli php-mbstring php-xml php-zip php-curl composer >/dev/null 2>&1
|
||||||
@@ -52,7 +52,7 @@ jobs:
|
|||||||
echo "MOKO_CLI=/opt/mokocli/cli" >> "$GITHUB_ENV"
|
echo "MOKO_CLI=/opt/mokocli/cli" >> "$GITHUB_ENV"
|
||||||
else
|
else
|
||||||
git clone --depth 1 --branch main --quiet \
|
git clone --depth 1 --branch main --quiet \
|
||||||
"https://x-access-token:${{ secrets.MOKOGITEA_TOKEN }}@git.mokoconsulting.tech/MokoConsulting/MokoCLI.git" \
|
"https://x-access-token:${{ secrets.MOKOGIT_TOKEN }}@git.mokoconsulting.tech/MokoConsulting/mokocli.git" \
|
||||||
/tmp/mokocli
|
/tmp/mokocli
|
||||||
cd /tmp/mokocli && composer install --no-dev --no-interaction --quiet
|
cd /tmp/mokocli && composer install --no-dev --no-interaction --quiet
|
||||||
echo "MOKO_CLI=/tmp/mokocli/cli" >> "$GITHUB_ENV"
|
echo "MOKO_CLI=/tmp/mokocli/cli" >> "$GITHUB_ENV"
|
||||||
@@ -62,5 +62,5 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
php ${MOKO_CLI}/version_auto_bump.php \
|
php ${MOKO_CLI}/version_auto_bump.php \
|
||||||
--path . --branch "${GITHUB_REF_NAME}" \
|
--path . --branch "${GITHUB_REF_NAME}" \
|
||||||
--token "${{ secrets.MOKOGITEA_TOKEN }}" \
|
--token "${{ secrets.MOKOGIT_TOKEN }}" \
|
||||||
--repo-url "https://x-access-token:${{ secrets.MOKOGITEA_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git"
|
--repo-url "https://x-access-token:${{ secrets.MOKOGIT_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git"
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
# PATH: /templates/workflows/shared/auto-dev-issue.yml.template
|
# PATH: /templates/workflows/shared/auto-dev-issue.yml.template
|
||||||
# VERSION: 04.06.00
|
# VERSION: 04.06.00
|
||||||
# BRIEF: Auto-create tracking issue with sub-issues for dev/rc branch workflow
|
# BRIEF: Auto-create tracking issue with sub-issues for dev/rc branch workflow
|
||||||
# NOTE: Synced via bulk-repo-sync to .mokogitea/workflows/auto-dev-issue.yml in all governed repos.
|
# NOTE: Synced via bulk-repo-sync to .mokogit/workflows/auto-dev-issue.yml in all governed repos.
|
||||||
|
|
||||||
name: "Universal: Dev/RC Branch Issue"
|
name: "Universal: Dev/RC Branch Issue"
|
||||||
|
|
||||||
@@ -3,9 +3,9 @@
|
|||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
#
|
#
|
||||||
# FILE INFORMATION
|
# FILE INFORMATION
|
||||||
# DEFGROUP: Gitea.Workflow
|
# DEFGROUP: MokoGIT.Workflow
|
||||||
# INGROUP: mokocli.Release
|
# INGROUP: MokoCLI.Release
|
||||||
# REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoCLI
|
# REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
||||||
# PATH: /templates/workflows/universal/auto-release.yml.template
|
# PATH: /templates/workflows/universal/auto-release.yml.template
|
||||||
# VERSION: 05.00.00
|
# VERSION: 05.00.00
|
||||||
# BRIEF: Universal build & release � detects platform from manifest.xml
|
# BRIEF: Universal build & release � detects platform from manifest.xml
|
||||||
@@ -31,7 +31,7 @@ on:
|
|||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- '.mokogitea/workflows/**'
|
- '.mokogit/workflows/**'
|
||||||
- '*.md'
|
- '*.md'
|
||||||
- 'wiki/**'
|
- 'wiki/**'
|
||||||
- '.editorconfig'
|
- '.editorconfig'
|
||||||
@@ -52,9 +52,9 @@ on:
|
|||||||
|
|
||||||
env:
|
env:
|
||||||
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
|
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
|
||||||
MOKOGITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
|
MOKOGIT_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
|
||||||
GITEA_ORG: ${{ vars.GITEA_ORG || github.repository_owner }}
|
GIT_ORG: ${{ vars.GITEA_ORG || github.repository_owner }}
|
||||||
GITEA_REPO: ${{ vars.GITEA_REPO || github.event.repository.name }}
|
GIT_REPO: ${{ vars.GITEA_REPO || github.event.repository.name }}
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
@@ -73,12 +73,12 @@ jobs:
|
|||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.MOKOGITEA_TOKEN }}
|
token: ${{ secrets.MOKOGIT_TOKEN }}
|
||||||
fetch-depth: 1
|
fetch-depth: 1
|
||||||
|
|
||||||
- name: Setup mokocli tools
|
- name: Setup MokoCLI tools
|
||||||
env:
|
env:
|
||||||
MOKO_CLONE_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
|
MOKO_CLONE_TOKEN: ${{ secrets.MOKOGIT_TOKEN }}
|
||||||
MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting
|
MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting
|
||||||
run: |
|
run: |
|
||||||
if [ -f /opt/mokocli/cli/version_bump.php ] && [ -f /opt/mokocli/vendor/autoload.php ]; then
|
if [ -f /opt/mokocli/cli/version_bump.php ] && [ -f /opt/mokocli/vendor/autoload.php ]; then
|
||||||
@@ -90,7 +90,7 @@ jobs:
|
|||||||
sudo apt-get update -qq && sudo apt-get install -y -qq php-cli php-mbstring php-xml php-zip php-curl composer > /dev/null 2>&1
|
sudo apt-get update -qq && sudo apt-get install -y -qq php-cli php-mbstring php-xml php-zip php-curl composer > /dev/null 2>&1
|
||||||
fi
|
fi
|
||||||
rm -rf /tmp/mokocli
|
rm -rf /tmp/mokocli
|
||||||
CLONE_URL=https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/MokoCLI.git
|
CLONE_URL=https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/mokocli.git
|
||||||
git clone --depth 1 --branch main --quiet $CLONE_URL /tmp/mokocli
|
git clone --depth 1 --branch main --quiet $CLONE_URL /tmp/mokocli
|
||||||
cd /tmp/mokocli
|
cd /tmp/mokocli
|
||||||
composer install --no-dev --no-interaction --quiet
|
composer install --no-dev --no-interaction --quiet
|
||||||
@@ -99,30 +99,55 @@ jobs:
|
|||||||
|
|
||||||
- name: Rename branch to rc
|
- name: Rename branch to rc
|
||||||
run: |
|
run: |
|
||||||
php ${MOKO_CLI}/branch_rename.php \
|
API_BASE="${MOKOGIT_URL}/api/v1/repos/${GIT_ORG}/${GIT_REPO}"
|
||||||
--from "${{ github.event.pull_request.head.ref || 'dev' }}" --to rc \
|
AUTH="Authorization: token ${{ secrets.MOKOGIT_TOKEN }}"
|
||||||
--token "${{ secrets.MOKOGITEA_TOKEN }}" \
|
FROM="${{ github.event.pull_request.head.ref || 'dev' }}"
|
||||||
--api-base "${MOKOGITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" \
|
PR="${{ github.event.pull_request.number }}"
|
||||||
--pr "${{ github.event.pull_request.number }}"
|
|
||||||
|
# Resolve the source branch HEAD commit.
|
||||||
|
SRC_JSON=$(curl -sf -H "$AUTH" "${API_BASE}/branches/${FROM}") \
|
||||||
|
|| { echo "::error::Source branch ${FROM} not found"; exit 1; }
|
||||||
|
SRC_SHA=$(printf '%s' "$SRC_JSON" | python3 -c "import sys, json; print(json.load(sys.stdin)['commit']['id'])" 2>/dev/null || true)
|
||||||
|
[ -n "$SRC_SHA" ] || { echo "::error::Could not resolve HEAD of ${FROM}"; exit 1; }
|
||||||
|
|
||||||
|
# Point rc at the source commit via git push. Git's git/refs PATCH API
|
||||||
|
# returns HTTP 405 on ANY protected branch (force or not, even for a user in
|
||||||
|
# the force-push allowlist), so it cannot move a protected rc. git push honors
|
||||||
|
# the push + force-push allowlists and creates rc if it is absent.
|
||||||
|
PUSH_URL="https://x-access-token:${{ secrets.MOKOGIT_TOKEN }}@${MOKOGIT_URL#https://}/${GIT_ORG}/${GIT_REPO}.git"
|
||||||
|
git config --global user.name "mokogit-actions[bot]"
|
||||||
|
git config --global user.email "actions@mokoconsulting.tech"
|
||||||
|
git fetch --no-tags "$PUSH_URL" "${FROM}"
|
||||||
|
git push --force "$PUSH_URL" "FETCH_HEAD:refs/heads/rc" \
|
||||||
|
|| { echo "::error::Failed to point rc at ${FROM} (${SRC_SHA}) via git push"; exit 1; }
|
||||||
|
echo "rc set to ${FROM} (${SRC_SHA})"
|
||||||
|
|
||||||
|
# Repoint the PR at rc, then delete the old source branch (non-fatal).
|
||||||
|
if [ -n "$PR" ]; then
|
||||||
|
curl -s -X PATCH -H "$AUTH" -H "Content-Type: application/json" \
|
||||||
|
"${API_BASE}/pulls/${PR}" -d '{"head":"rc"}' >/dev/null || true
|
||||||
|
fi
|
||||||
|
curl -s -X DELETE -H "$AUTH" "${API_BASE}/branches/${FROM}" >/dev/null || true
|
||||||
|
echo "Renamed ${FROM} -> rc"
|
||||||
|
|
||||||
- name: Checkout rc and configure git
|
- name: Checkout rc and configure git
|
||||||
run: |
|
run: |
|
||||||
git fetch origin rc
|
git fetch origin rc
|
||||||
git checkout rc
|
git checkout rc
|
||||||
git config --local user.email "gitea-actions[bot]@mokoconsulting.tech"
|
git config --local user.email "mokogit-actions[bot]@mokoconsulting.tech"
|
||||||
git config --local user.name "gitea-actions[bot]"
|
git config --local user.name "mokogit-actions[bot]"
|
||||||
git remote set-url origin "https://x-access-token:${{ secrets.MOKOGITEA_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git"
|
git remote set-url origin "https://x-access-token:${{ secrets.MOKOGIT_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git"
|
||||||
|
|
||||||
- name: Publish RC release
|
- name: Publish RC release
|
||||||
run: |
|
run: |
|
||||||
php ${MOKO_CLI}/release_publish.php \
|
php ${MOKO_CLI}/release_publish.php \
|
||||||
--path . --stability rc --bump minor --branch rc \
|
--path . --stability rc --bump minor --branch rc \
|
||||||
--token "${{ secrets.MOKOGITEA_TOKEN }}"
|
--token "${{ secrets.MOKOGIT_TOKEN }}"
|
||||||
|
|
||||||
- name: Update RC release notes from CHANGELOG.md
|
- name: Update RC release notes from CHANGELOG.md
|
||||||
run: |
|
run: |
|
||||||
API_BASE="${MOKOGITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
|
API_BASE="${MOKOGIT_URL}/api/v1/repos/${GIT_ORG}/${GIT_REPO}"
|
||||||
TOKEN="${{ secrets.MOKOGITEA_TOKEN }}"
|
TOKEN="${{ secrets.MOKOGIT_TOKEN }}"
|
||||||
|
|
||||||
# Extract [Unreleased] section from changelog
|
# Extract [Unreleased] section from changelog
|
||||||
NOTES=""
|
NOTES=""
|
||||||
@@ -171,14 +196,14 @@ jobs:
|
|||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.MOKOGITEA_TOKEN }}
|
token: ${{ secrets.MOKOGIT_TOKEN }}
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Configure git for bot pushes
|
- name: Configure git for bot pushes
|
||||||
run: |
|
run: |
|
||||||
git config --local user.email "gitea-actions[bot]@mokoconsulting.tech"
|
git config --local user.email "mokogit-actions[bot]@mokoconsulting.tech"
|
||||||
git config --local user.name "gitea-actions[bot]"
|
git config --local user.name "mokogit-actions[bot]"
|
||||||
git remote set-url origin "https://x-access-token:${{ secrets.MOKOGITEA_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git"
|
git remote set-url origin "https://x-access-token:${{ secrets.MOKOGIT_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git"
|
||||||
|
|
||||||
- name: Check for merge conflict markers
|
- name: Check for merge conflict markers
|
||||||
run: |
|
run: |
|
||||||
@@ -193,9 +218,9 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
echo "No conflict markers found"
|
echo "No conflict markers found"
|
||||||
|
|
||||||
- name: Setup mokocli tools
|
- name: Setup MokoCLI tools
|
||||||
env:
|
env:
|
||||||
MOKO_CLONE_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
|
MOKO_CLONE_TOKEN: ${{ secrets.MOKOGIT_TOKEN }}
|
||||||
MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting
|
MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting
|
||||||
COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GH_MIRROR_TOKEN }}"}}'
|
COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GH_MIRROR_TOKEN }}"}}'
|
||||||
run: |
|
run: |
|
||||||
@@ -208,7 +233,7 @@ jobs:
|
|||||||
sudo apt-get update -qq && sudo apt-get install -y -qq php-cli php-mbstring php-xml php-zip php-curl composer > /dev/null 2>&1
|
sudo apt-get update -qq && sudo apt-get install -y -qq php-cli php-mbstring php-xml php-zip php-curl composer > /dev/null 2>&1
|
||||||
fi
|
fi
|
||||||
rm -rf /tmp/mokocli
|
rm -rf /tmp/mokocli
|
||||||
CLONE_URL=https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/MokoCLI.git
|
CLONE_URL=https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/mokocli.git
|
||||||
git clone --depth 1 --branch main --quiet $CLONE_URL /tmp/mokocli
|
git clone --depth 1 --branch main --quiet $CLONE_URL /tmp/mokocli
|
||||||
cd /tmp/mokocli
|
cd /tmp/mokocli
|
||||||
composer install --no-dev --no-interaction --quiet
|
composer install --no-dev --no-interaction --quiet
|
||||||
@@ -242,7 +267,7 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
php ${MOKO_CLI}/release_publish.php \
|
php ${MOKO_CLI}/release_publish.php \
|
||||||
--path . --stability stable ${BUMP_FLAG} --branch main \
|
--path . --stability stable ${BUMP_FLAG} --branch main \
|
||||||
--token "${{ secrets.MOKOGITEA_TOKEN }}"
|
--token "${{ secrets.MOKOGIT_TOKEN }}"
|
||||||
|
|
||||||
- name: "Read published version"
|
- name: "Read published version"
|
||||||
id: version
|
id: version
|
||||||
@@ -269,8 +294,8 @@ jobs:
|
|||||||
!startsWith(steps.platform.outputs.platform, 'joomla')
|
!startsWith(steps.platform.outputs.platform, 'joomla')
|
||||||
run: |
|
run: |
|
||||||
VERSION="${{ steps.version.outputs.version }}"
|
VERSION="${{ steps.version.outputs.version }}"
|
||||||
API_BASE="${MOKOGITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
|
API_BASE="${MOKOGIT_URL}/api/v1/repos/${GIT_ORG}/${GIT_REPO}"
|
||||||
TOKEN="${{ secrets.MOKOGITEA_TOKEN }}"
|
TOKEN="${{ secrets.MOKOGIT_TOKEN }}"
|
||||||
SEMVER_TAG="v${VERSION}"
|
SEMVER_TAG="v${VERSION}"
|
||||||
|
|
||||||
echo "Creating semver tag: ${SEMVER_TAG}"
|
echo "Creating semver tag: ${SEMVER_TAG}"
|
||||||
@@ -294,8 +319,8 @@ jobs:
|
|||||||
|
|
||||||
- name: Update release notes and promote changelog
|
- name: Update release notes and promote changelog
|
||||||
run: |
|
run: |
|
||||||
API_BASE="${MOKOGITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
|
API_BASE="${MOKOGIT_URL}/api/v1/repos/${GIT_ORG}/${GIT_REPO}"
|
||||||
TOKEN="${{ secrets.MOKOGITEA_TOKEN }}"
|
TOKEN="${{ secrets.MOKOGIT_TOKEN }}"
|
||||||
|
|
||||||
# Get the stable release info (version and ID)
|
# Get the stable release info (version and ID)
|
||||||
RELEASE_JSON=$(curl -sf -H "Authorization: token ${TOKEN}" \
|
RELEASE_JSON=$(curl -sf -H "Authorization: token ${TOKEN}" \
|
||||||
@@ -363,10 +388,10 @@ jobs:
|
|||||||
VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}"
|
VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}"
|
||||||
RELEASE_TAG="${{ steps.version.outputs.release_tag }}"
|
RELEASE_TAG="${{ steps.version.outputs.release_tag }}"
|
||||||
GH_REPO="${{ vars.GH_MIRROR_REPO || github.repository }}"
|
GH_REPO="${{ vars.GH_MIRROR_REPO || github.repository }}"
|
||||||
API_BASE="${MOKOGITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
|
API_BASE="${MOKOGIT_URL}/api/v1/repos/${GIT_ORG}/${GIT_REPO}"
|
||||||
php ${MOKO_CLI}/release_mirror.php \
|
php ${MOKO_CLI}/release_mirror.php \
|
||||||
--version "$VERSION" --tag "$RELEASE_TAG" \
|
--version "$VERSION" --tag "$RELEASE_TAG" \
|
||||||
--token "${{ secrets.MOKOGITEA_TOKEN }}" --api-base "$API_BASE" \
|
--token "${{ secrets.MOKOGIT_TOKEN }}" --api-base "$API_BASE" \
|
||||||
--gh-token "${{ secrets.GH_MIRROR_TOKEN }}" --gh-repo "$GH_REPO" \
|
--gh-token "${{ secrets.GH_MIRROR_TOKEN }}" --gh-repo "$GH_REPO" \
|
||||||
--branch main 2>&1 || true
|
--branch main 2>&1 || true
|
||||||
echo "GitHub mirror updated" >> $GITHUB_STEP_SUMMARY
|
echo "GitHub mirror updated" >> $GITHUB_STEP_SUMMARY
|
||||||
@@ -392,8 +417,8 @@ jobs:
|
|||||||
if: steps.version.outputs.skip != 'true'
|
if: steps.version.outputs.skip != 'true'
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
run: |
|
run: |
|
||||||
API_BASE="${MOKOGITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
|
API_BASE="${MOKOGIT_URL}/api/v1/repos/${GIT_ORG}/${GIT_REPO}"
|
||||||
TOKEN="${{ secrets.MOKOGITEA_TOKEN }}"
|
TOKEN="${{ secrets.MOKOGIT_TOKEN }}"
|
||||||
|
|
||||||
# Delete rc branch (ephemeral — created by promote-rc)
|
# Delete rc branch (ephemeral — created by promote-rc)
|
||||||
curl -sf -X DELETE -H "Authorization: token ${TOKEN}" \
|
curl -sf -X DELETE -H "Authorization: token ${TOKEN}" \
|
||||||
@@ -416,8 +441,8 @@ jobs:
|
|||||||
if: steps.version.outputs.skip != 'true'
|
if: steps.version.outputs.skip != 'true'
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
run: |
|
run: |
|
||||||
API_BASE="${MOKOGITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
|
API_BASE="${MOKOGIT_URL}/api/v1/repos/${GIT_ORG}/${GIT_REPO}"
|
||||||
TOKEN="${{ secrets.MOKOGITEA_TOKEN }}"
|
TOKEN="${{ secrets.MOKOGIT_TOKEN }}"
|
||||||
VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}"
|
VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}"
|
||||||
BRANCH_NAME="version/${VERSION}"
|
BRANCH_NAME="version/${VERSION}"
|
||||||
MAIN_SHA=$(git rev-parse HEAD)
|
MAIN_SHA=$(git rev-parse HEAD)
|
||||||
@@ -437,9 +462,9 @@ jobs:
|
|||||||
if: steps.version.outputs.skip != 'true'
|
if: steps.version.outputs.skip != 'true'
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
run: |
|
run: |
|
||||||
API_BASE="${MOKOGITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
|
API_BASE="${MOKOGIT_URL}/api/v1/repos/${GIT_ORG}/${GIT_REPO}"
|
||||||
php ${MOKO_CLI}/version_reset_dev.php \
|
php ${MOKO_CLI}/version_reset_dev.php \
|
||||||
--token "${{ secrets.MOKOGITEA_TOKEN }}" --api-base "${API_BASE}" \
|
--token "${{ secrets.MOKOGIT_TOKEN }}" --api-base "${API_BASE}" \
|
||||||
--branch dev --path . 2>&1 || true
|
--branch dev --path . 2>&1 || true
|
||||||
|
|
||||||
# -- Summary --------------------------------------------------------------
|
# -- Summary --------------------------------------------------------------
|
||||||
@@ -463,5 +488,5 @@ jobs:
|
|||||||
echo "| Version | \`${VERSION}\` |" >> $GITHUB_STEP_SUMMARY
|
echo "| Version | \`${VERSION}\` |" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "| Branch | \`${{ steps.version.outputs.branch }}\` |" >> $GITHUB_STEP_SUMMARY
|
echo "| Branch | \`${{ steps.version.outputs.branch }}\` |" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "| Tag | \`${{ steps.version.outputs.tag }}\` |" >> $GITHUB_STEP_SUMMARY
|
echo "| Tag | \`${{ steps.version.outputs.tag }}\` |" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "| Release | [View](${MOKOGITEA_URL}/${GITEA_ORG}/${GITEA_REPO}/releases/tag/${{ steps.version.outputs.tag }}) |" >> $GITHUB_STEP_SUMMARY
|
echo "| Release | [View](${MOKOGIT_URL}/${GIT_ORG}/${GIT_REPO}/releases/tag/${{ steps.version.outputs.tag }}) |" >> $GITHUB_STEP_SUMMARY
|
||||||
fi
|
fi
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
# Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
#
|
||||||
|
# FILE INFORMATION
|
||||||
|
# DEFGROUP: MokoGIT.Workflow
|
||||||
|
# INGROUP: MokoCLI.Universal
|
||||||
|
# REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Generic
|
||||||
|
# PATH: /.mokogit/workflows/branch-cleanup.yml
|
||||||
|
# VERSION: 01.00.00
|
||||||
|
# BRIEF: Delete feature branches after PR merge
|
||||||
|
|
||||||
|
name: "Branch Cleanup"
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
types: [closed]
|
||||||
|
|
||||||
|
env:
|
||||||
|
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
cleanup:
|
||||||
|
name: Delete merged branch
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: >-
|
||||||
|
github.event.pull_request.merged == true &&
|
||||||
|
github.event.pull_request.head.ref != 'dev' &&
|
||||||
|
github.event.pull_request.head.ref != 'main'
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Delete source branch
|
||||||
|
# SECURITY: the PR head ref is attacker-controllable. Pass it (and the
|
||||||
|
# repo/token) through env so the Actions engine cannot splice it into the
|
||||||
|
# shell source, and validate it to a safe charset before use.
|
||||||
|
env:
|
||||||
|
MOKOGIT_TOKEN: ${{ secrets.MOKOGIT_TOKEN }}
|
||||||
|
REPO: ${{ github.repository }}
|
||||||
|
API_BASE: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
|
||||||
|
BRANCH: ${{ github.event.pull_request.head.ref }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
if ! printf '%s' "${BRANCH}" | grep -Eq '^[A-Za-z0-9._/-]+$'; then
|
||||||
|
echo "::error::unsafe branch name; refusing to proceed"; exit 1
|
||||||
|
fi
|
||||||
|
API="${API_BASE}/api/v1/repos/${REPO}/branches"
|
||||||
|
# URL-encode the branch name's slashes (no PHP dependency on the runner)
|
||||||
|
ENCODED=$(printf '%s' "${BRANCH}" | sed 's|/|%2F|g')
|
||||||
|
|
||||||
|
STATUS=$(curl -sf -o /dev/null -w "%{http_code}" -X DELETE \
|
||||||
|
-H "Authorization: token ${MOKOGIT_TOKEN}" \
|
||||||
|
"${API}/${ENCODED}" 2>/dev/null || true)
|
||||||
|
|
||||||
|
if [ "$STATUS" = "204" ]; then
|
||||||
|
echo "Deleted branch: ${BRANCH}" >> $GITHUB_STEP_SUMMARY
|
||||||
|
elif [ "$STATUS" = "404" ]; then
|
||||||
|
echo "Branch already deleted: ${BRANCH}" >> $GITHUB_STEP_SUMMARY
|
||||||
|
else
|
||||||
|
echo "::warning::Failed to delete branch ${BRANCH} (HTTP ${STATUS})"
|
||||||
|
fi
|
||||||
+1
-2
@@ -11,7 +11,7 @@
|
|||||||
# PATH: /templates/workflows/shared/changelog-validation.yml.template
|
# PATH: /templates/workflows/shared/changelog-validation.yml.template
|
||||||
# VERSION: 04.06.00
|
# VERSION: 04.06.00
|
||||||
# BRIEF: Validates CHANGELOG.md format and version consistency
|
# BRIEF: Validates CHANGELOG.md format and version consistency
|
||||||
# NOTE: Deployed to .mokogitea/workflows/changelog-validation.yml in governed repos.
|
# NOTE: Deployed to .mokogit/workflows/changelog-validation.yml in governed repos.
|
||||||
|
|
||||||
name: "Universal: Changelog Validation"
|
name: "Universal: Changelog Validation"
|
||||||
|
|
||||||
@@ -34,7 +34,6 @@ jobs:
|
|||||||
validate-changelog:
|
validate-changelog:
|
||||||
name: Validate CHANGELOG.md
|
name: Validate CHANGELOG.md
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: ${{ !startsWith(github.event.repository.name, 'Template-') }}
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
@@ -3,10 +3,10 @@
|
|||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
#
|
#
|
||||||
# FILE INFORMATION
|
# FILE INFORMATION
|
||||||
# DEFGROUP: Gitea.Workflow
|
# DEFGROUP: MokoGIT.Workflow
|
||||||
# INGROUP: MokoStandards.CI
|
# INGROUP: MokoCLI.CI
|
||||||
# REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Generic
|
# REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Generic
|
||||||
# PATH: /.gitea/workflows/ci-generic.yml
|
# PATH: /.mokogit/workflows/ci-generic.yml
|
||||||
# VERSION: 01.00.00
|
# VERSION: 01.00.00
|
||||||
# BRIEF: CI pipeline — lint, validate, and test for generic projects (PHP + Node.js)
|
# BRIEF: CI pipeline — lint, validate, and test for generic projects (PHP + Node.js)
|
||||||
|
|
||||||
+11
-11
@@ -3,12 +3,12 @@
|
|||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
#
|
#
|
||||||
# FILE INFORMATION
|
# FILE INFORMATION
|
||||||
# DEFGROUP: Gitea.Workflow
|
# DEFGROUP: MokoGIT.Workflow
|
||||||
# INGROUP: mokocli.Universal
|
# INGROUP: MokoCLI.Universal
|
||||||
# REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoCLI
|
# REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
||||||
# PATH: /.mokogitea/workflows/ci-issue-reporter.yml
|
# PATH: /.mokogit/workflows/ci-issue-reporter.yml
|
||||||
# VERSION: 01.00.00
|
# VERSION: 01.00.00
|
||||||
# BRIEF: Reusable workflow — creates/updates a Gitea issue when a CI gate fails.
|
# BRIEF: Reusable workflow — creates/updates a MokoGIT issue when a CI gate fails.
|
||||||
# Clones MokoCLI and runs cli/ci_issue_reporter.sh.
|
# Clones MokoCLI and runs cli/ci_issue_reporter.sh.
|
||||||
|
|
||||||
name: "Universal: CI Issue Reporter"
|
name: "Universal: CI Issue Reporter"
|
||||||
@@ -35,7 +35,7 @@ on:
|
|||||||
type: string
|
type: string
|
||||||
default: ""
|
default: ""
|
||||||
secrets:
|
secrets:
|
||||||
MOKOGITEA_TOKEN:
|
MOKOGIT_TOKEN:
|
||||||
required: true
|
required: true
|
||||||
|
|
||||||
env:
|
env:
|
||||||
@@ -49,16 +49,16 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Clone MokoCLI
|
- name: Clone MokoCLI
|
||||||
env:
|
env:
|
||||||
MOKOGITEA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
|
MOKOGIT_TOKEN: ${{ secrets.MOKOGIT_TOKEN }}
|
||||||
run: |
|
run: |
|
||||||
MOKOGITEA_URL="${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}"
|
MOKOGIT_URL="${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}"
|
||||||
git clone --depth 1 --filter=blob:none --sparse "${MOKOGITEA_URL}/MokoConsulting/MokoCLI.git" /tmp/mokocli
|
git clone --depth 1 --filter=blob:none --sparse "${MOKOGIT_URL}/MokoConsulting/mokocli.git" /tmp/mokocli
|
||||||
cd /tmp/mokocli && git sparse-checkout set cli/ci_issue_reporter.sh
|
cd /tmp/mokocli && git sparse-checkout set cli/ci_issue_reporter.sh
|
||||||
|
|
||||||
- name: Report CI failure
|
- name: Report CI failure
|
||||||
env:
|
env:
|
||||||
MOKOGITEA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
|
MOKOGIT_TOKEN: ${{ secrets.MOKOGIT_TOKEN }}
|
||||||
MOKOGITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
|
MOKOGIT_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
|
||||||
run: |
|
run: |
|
||||||
chmod +x /tmp/mokocli/cli/ci_issue_reporter.sh
|
chmod +x /tmp/mokocli/cli/ci_issue_reporter.sh
|
||||||
/tmp/mokocli/cli/ci_issue_reporter.sh \
|
/tmp/mokocli/cli/ci_issue_reporter.sh \
|
||||||
@@ -3,10 +3,10 @@
|
|||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
#
|
#
|
||||||
# FILE INFORMATION
|
# FILE INFORMATION
|
||||||
# DEFGROUP: Gitea.Workflow
|
# DEFGROUP: MokoGIT.Workflow
|
||||||
# INGROUP: MokoStandards.Maintenance
|
# INGROUP: MokoCLI.Maintenance
|
||||||
# REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoStandards
|
# REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
||||||
# PATH: /.gitea/workflows/cleanup.yml
|
# PATH: /.mokogit/workflows/cleanup.yml
|
||||||
# VERSION: 01.00.00
|
# VERSION: 01.00.00
|
||||||
# BRIEF: Scheduled cleanup — delete merged branches and old workflow runs
|
# BRIEF: Scheduled cleanup — delete merged branches and old workflow runs
|
||||||
|
|
||||||
@@ -21,7 +21,7 @@ permissions:
|
|||||||
contents: write
|
contents: write
|
||||||
|
|
||||||
env:
|
env:
|
||||||
MOKOGITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
|
MOKOGIT_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
cleanup:
|
cleanup:
|
||||||
@@ -33,17 +33,17 @@ jobs:
|
|||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
token: ${{ secrets.MOKOGITEA_TOKEN }}
|
token: ${{ secrets.MOKOGIT_TOKEN }}
|
||||||
|
|
||||||
- name: Delete merged branches
|
- name: Delete merged branches
|
||||||
env:
|
env:
|
||||||
MOKOGITEA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
|
MOKOGIT_TOKEN: ${{ secrets.MOKOGIT_TOKEN }}
|
||||||
run: |
|
run: |
|
||||||
echo "=== Merged Branch Cleanup ==="
|
echo "=== Merged Branch Cleanup ==="
|
||||||
API="${MOKOGITEA_URL}/api/v1/repos/${{ github.repository }}"
|
API="${MOKOGIT_URL}/api/v1/repos/${{ github.repository }}"
|
||||||
|
|
||||||
# List branches via API
|
# List branches via API
|
||||||
BRANCHES=$(curl -sS -H "Authorization: token ${MOKOGITEA_TOKEN}" \
|
BRANCHES=$(curl -sS -H "Authorization: token ${MOKOGIT_TOKEN}" \
|
||||||
"${API}/branches?limit=50" | jq -r '.[].name')
|
"${API}/branches?limit=50" | jq -r '.[].name')
|
||||||
|
|
||||||
DELETED=0
|
DELETED=0
|
||||||
@@ -56,7 +56,7 @@ jobs:
|
|||||||
# Check if branch is merged into main
|
# Check if branch is merged into main
|
||||||
if git merge-base --is-ancestor "origin/${BRANCH}" origin/main 2>/dev/null; then
|
if git merge-base --is-ancestor "origin/${BRANCH}" origin/main 2>/dev/null; then
|
||||||
echo " Deleting merged branch: ${BRANCH}"
|
echo " Deleting merged branch: ${BRANCH}"
|
||||||
curl -sS -X DELETE -H "Authorization: token ${MOKOGITEA_TOKEN}" \
|
curl -sS -X DELETE -H "Authorization: token ${MOKOGIT_TOKEN}" \
|
||||||
"${API}/branches/${BRANCH}" 2>/dev/null || true
|
"${API}/branches/${BRANCH}" 2>/dev/null || true
|
||||||
DELETED=$((DELETED + 1))
|
DELETED=$((DELETED + 1))
|
||||||
fi
|
fi
|
||||||
@@ -66,20 +66,20 @@ jobs:
|
|||||||
|
|
||||||
- name: Clean old workflow runs
|
- name: Clean old workflow runs
|
||||||
env:
|
env:
|
||||||
MOKOGITEA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
|
MOKOGIT_TOKEN: ${{ secrets.MOKOGIT_TOKEN }}
|
||||||
run: |
|
run: |
|
||||||
echo "=== Workflow Run Cleanup ==="
|
echo "=== Workflow Run Cleanup ==="
|
||||||
API="${MOKOGITEA_URL}/api/v1/repos/${{ github.repository }}"
|
API="${MOKOGIT_URL}/api/v1/repos/${{ github.repository }}"
|
||||||
CUTOFF=$(date -d "30 days ago" +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -v-30d +%Y-%m-%dT%H:%M:%SZ)
|
CUTOFF=$(date -d "30 days ago" +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -v-30d +%Y-%m-%dT%H:%M:%SZ)
|
||||||
|
|
||||||
# Get old completed runs
|
# Get old completed runs
|
||||||
RUNS=$(curl -sS -H "Authorization: token ${MOKOGITEA_TOKEN}" \
|
RUNS=$(curl -sS -H "Authorization: token ${MOKOGIT_TOKEN}" \
|
||||||
"${API}/actions/runs?status=completed&limit=50" | \
|
"${API}/actions/runs?status=completed&limit=50" | \
|
||||||
jq -r ".workflow_runs[] | select(.created_at < \"${CUTOFF}\") | .id" 2>/dev/null)
|
jq -r ".workflow_runs[] | select(.created_at < \"${CUTOFF}\") | .id" 2>/dev/null)
|
||||||
|
|
||||||
DELETED=0
|
DELETED=0
|
||||||
for RUN_ID in $RUNS; do
|
for RUN_ID in $RUNS; do
|
||||||
curl -sS -X DELETE -H "Authorization: token ${MOKOGITEA_TOKEN}" \
|
curl -sS -X DELETE -H "Authorization: token ${MOKOGIT_TOKEN}" \
|
||||||
"${API}/actions/runs/${RUN_ID}" 2>/dev/null || true
|
"${API}/actions/runs/${RUN_ID}" 2>/dev/null || true
|
||||||
DELETED=$((DELETED + 1))
|
DELETED=$((DELETED + 1))
|
||||||
done
|
done
|
||||||
+15
-13
@@ -3,10 +3,10 @@
|
|||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
#
|
#
|
||||||
# FILE INFORMATION
|
# FILE INFORMATION
|
||||||
# DEFGROUP: Gitea.Workflow
|
# DEFGROUP: MokoGIT.Workflow
|
||||||
# INGROUP: mokocli.Universal
|
# INGROUP: MokoCLI.Universal
|
||||||
# REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoCLI
|
# REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
||||||
# PATH: /.mokogitea/workflows/workflow-sync-trigger.yml
|
# PATH: /.mokogit/workflows/workflow-sync-trigger.yml
|
||||||
# VERSION: 01.01.00
|
# VERSION: 01.01.00
|
||||||
# BRIEF: Trigger workflow sync to live repos when a PR is merged to main
|
# BRIEF: Trigger workflow sync to live repos when a PR is merged to main
|
||||||
|
|
||||||
@@ -27,9 +27,10 @@ jobs:
|
|||||||
name: Sync workflows to live repos
|
name: Sync workflows to live repos
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: >-
|
if: >-
|
||||||
github.event_name == 'workflow_dispatch' ||
|
startsWith(github.event.repository.name, 'Template-') &&
|
||||||
|
(github.event_name == 'workflow_dispatch' ||
|
||||||
(github.event.pull_request.merged == true &&
|
(github.event.pull_request.merged == true &&
|
||||||
!contains(github.event.pull_request.title, '[skip sync]'))
|
!contains(github.event.pull_request.title, '[skip sync]')))
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Determine platform from repo name
|
- name: Determine platform from repo name
|
||||||
@@ -40,19 +41,19 @@ jobs:
|
|||||||
Template-Joomla) PLATFORM="joomla" ;;
|
Template-Joomla) PLATFORM="joomla" ;;
|
||||||
Template-Dolibarr) PLATFORM="dolibarr" ;;
|
Template-Dolibarr) PLATFORM="dolibarr" ;;
|
||||||
Template-Go) PLATFORM="go" ;;
|
Template-Go) PLATFORM="go" ;;
|
||||||
Template-MCP) PLATFORM="mcp" ;;
|
Template-NPM) PLATFORM="npm" ;;
|
||||||
Template-Generic) PLATFORM="" ;;
|
Template-Generic) PLATFORM="" ;;
|
||||||
*) PLATFORM="" ;;
|
*) PLATFORM="" ;;
|
||||||
esac
|
esac
|
||||||
echo "platform=$PLATFORM" >> "$GITHUB_OUTPUT"
|
echo "platform=$PLATFORM" >> "$GITHUB_OUTPUT"
|
||||||
echo "Platform: ${PLATFORM:-all}"
|
echo "Platform: ${PLATFORM:-all}"
|
||||||
|
|
||||||
- name: Clone mokocli
|
- name: Clone MokoCLI
|
||||||
env:
|
env:
|
||||||
MOKOGITEA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
|
MOKOGIT_TOKEN: ${{ secrets.MOKOGIT_TOKEN }}
|
||||||
run: |
|
run: |
|
||||||
MOKOGITEA_URL="${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}"
|
MOKOGIT_URL="${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}"
|
||||||
git clone --depth 1 "${MOKOGITEA_URL}/MokoConsulting/MokoCLI.git" /tmp/mokocli
|
git clone --depth 1 "${MOKOGIT_URL}/MokoConsulting/mokocli.git" /tmp/mokocli
|
||||||
|
|
||||||
- name: Install PHP
|
- name: Install PHP
|
||||||
run: |
|
run: |
|
||||||
@@ -67,11 +68,12 @@ jobs:
|
|||||||
|
|
||||||
- name: Run workflow sync
|
- name: Run workflow sync
|
||||||
env:
|
env:
|
||||||
MOKOGITEA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
|
MOKOGIT_TOKEN: ${{ secrets.MOKOGIT_TOKEN }}
|
||||||
run: |
|
run: |
|
||||||
ARGS="--token ${MOKOGITEA_TOKEN}"
|
ARGS="--token ${MOKOGIT_TOKEN}"
|
||||||
ARGS="${ARGS} --org ${{ vars.GITEA_ORG || github.repository_owner }}"
|
ARGS="${ARGS} --org ${{ vars.GITEA_ORG || github.repository_owner }}"
|
||||||
ARGS="${ARGS} --phase repos"
|
ARGS="${ARGS} --phase repos"
|
||||||
|
ARGS="${ARGS} --delete-orphans"
|
||||||
|
|
||||||
PLATFORM="${{ steps.platform.outputs.platform }}"
|
PLATFORM="${{ steps.platform.outputs.platform }}"
|
||||||
if [ -n "$PLATFORM" ]; then
|
if [ -n "$PLATFORM" ]; then
|
||||||
@@ -3,9 +3,9 @@
|
|||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
#
|
#
|
||||||
# FILE INFORMATION
|
# FILE INFORMATION
|
||||||
# DEFGROUP: Gitea.Workflow
|
# DEFGROUP: MokoGIT.Workflow
|
||||||
# INGROUP: MokoStandards.Security
|
# INGROUP: MokoCLI.Security
|
||||||
# REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoStandards-API
|
# REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
||||||
# PATH: /templates/workflows/gitleaks.yml.template
|
# PATH: /templates/workflows/gitleaks.yml.template
|
||||||
# VERSION: 01.00.00
|
# VERSION: 01.00.00
|
||||||
# BRIEF: Secret scanning — detect leaked credentials, API keys, and tokens
|
# BRIEF: Secret scanning — detect leaked credentials, API keys, and tokens
|
||||||
@@ -34,7 +34,7 @@ permissions:
|
|||||||
|
|
||||||
env:
|
env:
|
||||||
NTFY_URL: ${{ vars.NTFY_URL || 'https://ntfy.mokoconsulting.tech' }}
|
NTFY_URL: ${{ vars.NTFY_URL || 'https://ntfy.mokoconsulting.tech' }}
|
||||||
NTFY_TOPIC: ${{ vars.NTFY_TOPIC || 'gitea-security' }}
|
NTFY_TOPIC: ${{ vars.NTFY_TOPIC || 'git-security' }}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
gitleaks:
|
gitleaks:
|
||||||
@@ -3,8 +3,8 @@
|
|||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
#
|
#
|
||||||
# FILE INFORMATION
|
# FILE INFORMATION
|
||||||
# DEFGROUP: Gitea.Workflow
|
# DEFGROUP: MokoGIT.Workflow
|
||||||
# INGROUP: mokocli.Automation
|
# INGROUP: MokoCLI.Automation
|
||||||
# VERSION: 01.00.00
|
# VERSION: 01.00.00
|
||||||
# BRIEF: Auto-create feature branch when an issue is opened
|
# BRIEF: Auto-create feature branch when an issue is opened
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ permissions:
|
|||||||
issues: write
|
issues: write
|
||||||
|
|
||||||
env:
|
env:
|
||||||
MOKOGITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
|
MOKOGIT_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
create-branch:
|
create-branch:
|
||||||
@@ -27,14 +27,22 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Create branch and comment
|
- name: Create branch and comment
|
||||||
|
# SECURITY: never interpolate github.event.* into a run: script — the
|
||||||
|
# Actions engine splices the raw value into the shell source (command
|
||||||
|
# injection via a crafted issue title). Pass everything through env so
|
||||||
|
# the values arrive as ordinary shell variables that are not re-parsed.
|
||||||
|
env:
|
||||||
|
MOKOGIT_TOKEN: ${{ secrets.MOKOGIT_TOKEN }}
|
||||||
|
REPO: ${{ github.repository }}
|
||||||
|
ISSUE_NUM: ${{ github.event.issue.number }}
|
||||||
|
ISSUE_TITLE: ${{ github.event.issue.title }}
|
||||||
run: |
|
run: |
|
||||||
TOKEN="${{ secrets.MOKOGITEA_TOKEN }}"
|
TOKEN="${MOKOGIT_TOKEN}"
|
||||||
API="${MOKOGITEA_URL}/api/v1/repos/${{ github.repository }}"
|
API="${MOKOGIT_URL}/api/v1/repos/${REPO}"
|
||||||
ISSUE_NUM="${{ github.event.issue.number }}"
|
|
||||||
ISSUE_TITLE="${{ github.event.issue.title }}"
|
|
||||||
|
|
||||||
# Build slug from title: lowercase, replace non-alnum with dash, trim
|
# Build slug from title: lowercase, replace non-alnum with dash, trim.
|
||||||
SLUG=$(echo "${ISSUE_TITLE}" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | sed 's/--*/-/g' | sed 's/^-//;s/-$//' | cut -c1-40)
|
# printf (not echo) so a title beginning with "-" is not read as flags.
|
||||||
|
SLUG=$(printf '%s' "${ISSUE_TITLE}" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | sed 's/--*/-/g' | sed 's/^-//;s/-$//' | cut -c1-40)
|
||||||
BRANCH="feature/${ISSUE_NUM}-${SLUG}"
|
BRANCH="feature/${ISSUE_NUM}-${SLUG}"
|
||||||
|
|
||||||
# Check dev branch exists
|
# Check dev branch exists
|
||||||
@@ -58,7 +66,7 @@ jobs:
|
|||||||
echo "Created branch: ${BRANCH}"
|
echo "Created branch: ${BRANCH}"
|
||||||
|
|
||||||
# Comment on issue with branch link
|
# Comment on issue with branch link
|
||||||
REPO_URL="${MOKOGITEA_URL}/${{ github.repository }}"
|
REPO_URL="${MOKOGIT_URL}/${REPO}"
|
||||||
BODY="Branch created: [\`${BRANCH}\`](${REPO_URL}/src/branch/${BRANCH})\n\n\`\`\`bash\ngit fetch origin\ngit checkout ${BRANCH}\n\`\`\`"
|
BODY="Branch created: [\`${BRANCH}\`](${REPO_URL}/src/branch/${BRANCH})\n\n\`\`\`bash\ngit fetch origin\ngit checkout ${BRANCH}\n\`\`\`"
|
||||||
|
|
||||||
curl -sf -X POST \
|
curl -sf -X POST \
|
||||||
@@ -3,10 +3,10 @@
|
|||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
#
|
#
|
||||||
# FILE INFORMATION
|
# FILE INFORMATION
|
||||||
# DEFGROUP: Gitea.Workflow
|
# DEFGROUP: MokoGIT.Workflow
|
||||||
# INGROUP: MokoStandards.Notifications
|
# INGROUP: MokoCLI.Notifications
|
||||||
# REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoStandards
|
# REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
||||||
# PATH: /.gitea/workflows/notify.yml
|
# PATH: /.mokogit/workflows/notify.yml
|
||||||
# VERSION: 01.00.00
|
# VERSION: 01.00.00
|
||||||
# BRIEF: Push notifications via ntfy on release success or workflow failure
|
# BRIEF: Push notifications via ntfy on release success or workflow failure
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ permissions:
|
|||||||
|
|
||||||
env:
|
env:
|
||||||
NTFY_URL: ${{ vars.NTFY_URL || 'https://ntfy.mokoconsulting.tech' }}
|
NTFY_URL: ${{ vars.NTFY_URL || 'https://ntfy.mokoconsulting.tech' }}
|
||||||
NTFY_TOPIC: ${{ vars.NTFY_TOPIC || 'gitea-releases' }}
|
NTFY_TOPIC: ${{ vars.NTFY_TOPIC || 'git-releases' }}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
notify:
|
notify:
|
||||||
@@ -88,13 +88,13 @@ jobs:
|
|||||||
done
|
done
|
||||||
|
|
||||||
# ── Version ──────────────────────────────────────────────────────
|
# ── Version ──────────────────────────────────────────────────────
|
||||||
- name: Setup mokocli tools
|
- name: Setup MokoCLI tools
|
||||||
env:
|
env:
|
||||||
GH_TOKEN: ${{ secrets.GH_TOKEN || github.token }}
|
GH_TOKEN: ${{ secrets.GH_TOKEN || github.token }}
|
||||||
COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GH_TOKEN || github.token }}"}}'
|
COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GH_TOKEN || github.token }}"}}'
|
||||||
run: |
|
run: |
|
||||||
git clone --depth 1 --branch version/04 --quiet \
|
git clone --depth 1 --branch version/04 --quiet \
|
||||||
"https://x-access-token:${GH_TOKEN}@github.com/MokoConsulting/MokoCLI.git" \
|
"https://x-access-token:${GH_TOKEN}@github.com/MokoConsulting/mokocli.git" \
|
||||||
/tmp/mokostandards
|
/tmp/mokostandards
|
||||||
cd /tmp/mokostandards
|
cd /tmp/mokostandards
|
||||||
composer install --no-dev --no-interaction --quiet
|
composer install --no-dev --no-interaction --quiet
|
||||||
@@ -10,9 +10,9 @@ on:
|
|||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
env:
|
env:
|
||||||
MOKOGITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
|
MOKOGIT_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
|
||||||
GITEA_ORG: ${{ vars.GITEA_ORG || github.repository_owner }}
|
GIT_ORG: ${{ vars.GITEA_ORG || github.repository_owner }}
|
||||||
GITEA_REPO: ${{ vars.GITEA_REPO || github.event.repository.name }}
|
GIT_REPO: ${{ vars.GITEA_REPO || github.event.repository.name }}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
publish:
|
publish:
|
||||||
@@ -39,8 +39,8 @@ jobs:
|
|||||||
|
|
||||||
- name: Auto-bump patch version
|
- name: Auto-bump patch version
|
||||||
run: |
|
run: |
|
||||||
API_BASE="${MOKOGITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
|
API_BASE="${MOKOGIT_URL}/api/v1/repos/${GIT_ORG}/${GIT_REPO}"
|
||||||
TOKEN="${{ secrets.MOKOGITEA_TOKEN }}"
|
TOKEN="${{ secrets.MOKOGIT_TOKEN }}"
|
||||||
|
|
||||||
PKG_NAME=$(node -p "require('./package.json').name")
|
PKG_NAME=$(node -p "require('./package.json').name")
|
||||||
CURRENT=$(node -p "require('./package.json').version")
|
CURRENT=$(node -p "require('./package.json').version")
|
||||||
@@ -56,7 +56,7 @@ jobs:
|
|||||||
NEW_VER=$(node -p "require('./package.json').version")
|
NEW_VER=$(node -p "require('./package.json').version")
|
||||||
echo "Bumping ${CURRENT} -> ${NEW_VER}"
|
echo "Bumping ${CURRENT} -> ${NEW_VER}"
|
||||||
|
|
||||||
# Push via Gitea API: branch + PR + merge
|
# Push via MokoGIT API: branch + PR + merge
|
||||||
BRANCH="chore/npm-version-bump"
|
BRANCH="chore/npm-version-bump"
|
||||||
FILEPATH="package.json"
|
FILEPATH="package.json"
|
||||||
CONTENT=$(base64 -w 0 < package.json)
|
CONTENT=$(base64 -w 0 < package.json)
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
# Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
#
|
||||||
|
# Enforces branch merge policy:
|
||||||
|
# feature/* → dev only
|
||||||
|
# fix/* → dev only
|
||||||
|
# hotfix/* → dev or main (emergency)
|
||||||
|
# dev → main only
|
||||||
|
# alpha/* → dev only
|
||||||
|
# beta/* → dev only
|
||||||
|
# rc/* → main only
|
||||||
|
|
||||||
|
name: Branch Policy Check
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
types: [opened, synchronize, reopened, edited]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
check-target:
|
||||||
|
name: Verify merge target
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Check branch policy
|
||||||
|
run: |
|
||||||
|
HEAD="${{ github.head_ref }}"
|
||||||
|
BASE="${{ github.base_ref }}"
|
||||||
|
|
||||||
|
echo "PR: ${HEAD} → ${BASE}"
|
||||||
|
|
||||||
|
ALLOWED=true
|
||||||
|
REASON=""
|
||||||
|
|
||||||
|
case "$HEAD" in
|
||||||
|
feature/*|feat/*)
|
||||||
|
if [ "$BASE" != "dev" ]; then
|
||||||
|
ALLOWED=false
|
||||||
|
REASON="Feature branches must target 'dev', not '${BASE}'"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
fix/*|bugfix/*)
|
||||||
|
if [ "$BASE" != "dev" ]; then
|
||||||
|
ALLOWED=false
|
||||||
|
REASON="Fix branches must target 'dev', not '${BASE}'"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
hotfix/*)
|
||||||
|
if [ "$BASE" != "dev" ] && [ "$BASE" != "main" ]; then
|
||||||
|
ALLOWED=false
|
||||||
|
REASON="Hotfix branches can only target 'dev' or 'main', not '${BASE}'"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
alpha/*|beta/*)
|
||||||
|
if [ "$BASE" != "dev" ]; then
|
||||||
|
ALLOWED=false
|
||||||
|
REASON="Pre-release branches must target 'dev', not '${BASE}'"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
rc/*)
|
||||||
|
if [ "$BASE" != "main" ]; then
|
||||||
|
ALLOWED=false
|
||||||
|
REASON="Release candidate branches must target 'main', not '${BASE}'"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
dev)
|
||||||
|
if [ "$BASE" != "main" ]; then
|
||||||
|
ALLOWED=false
|
||||||
|
REASON="Dev branch can only merge into 'main', not '${BASE}'"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ "$ALLOWED" = false ]; then
|
||||||
|
echo "::error::${REASON}"
|
||||||
|
echo ""
|
||||||
|
echo "## Branch Policy Violation" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "${REASON}" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "### Allowed merge paths:" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "- \`feature/*\` → \`dev\`" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "- \`fix/*\` → \`dev\`" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "- \`hotfix/*\` → \`dev\` or \`main\`" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "- \`dev\` → \`main\`" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "- \`rc/*\` → \`main\`" >> $GITHUB_STEP_SUMMARY
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Branch policy: OK (${HEAD} → ${BASE})"
|
||||||
|
echo "## Branch Policy: Passed" >> $GITHUB_STEP_SUMMARY
|
||||||
@@ -3,9 +3,9 @@
|
|||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
#
|
#
|
||||||
# FILE INFORMATION
|
# FILE INFORMATION
|
||||||
# DEFGROUP: Gitea.Workflow
|
# DEFGROUP: MokoGIT.Workflow
|
||||||
# INGROUP: mokocli.CI
|
# INGROUP: MokoCLI.CI
|
||||||
# REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoCLI
|
# REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
||||||
# PATH: /templates/workflows/universal/pr-check.yml.template
|
# PATH: /templates/workflows/universal/pr-check.yml.template
|
||||||
# VERSION: 09.23.00
|
# VERSION: 09.23.00
|
||||||
# BRIEF: PR gate — branch policy + code validation before merge
|
# BRIEF: PR gate — branch policy + code validation before merge
|
||||||
@@ -147,11 +147,12 @@ jobs:
|
|||||||
- name: Detect platform
|
- name: Detect platform
|
||||||
id: platform
|
id: platform
|
||||||
run: |
|
run: |
|
||||||
# Read platform from XML manifest (<platform> tag) or plain text fallback
|
# Platform comes from the MokoGIT metadata API (public GET).
|
||||||
PLATFORM=$(sed -n 's/.*<platform>\([^<]*\)<\/platform>.*/\1/p' .mokogitea/manifest.xml 2>/dev/null | head -1)
|
API="${GITHUB_SERVER_URL:-https://git.mokoconsulting.tech}/api/v1/repos/${GITHUB_REPOSITORY}/metadata"
|
||||||
[ -z "$PLATFORM" ] && PLATFORM=$(cat .mokogitea/manifest.xml 2>/dev/null | tr -d '[:space:]')
|
PLATFORM="$(curl -sf "$API" 2>/dev/null | python3 -c "import sys, json; print(json.load(sys.stdin).get('platform') or '')" 2>/dev/null || true)"
|
||||||
[ -z "$PLATFORM" ] && PLATFORM="generic"
|
[ -z "$PLATFORM" ] && PLATFORM="generic"
|
||||||
echo "platform=$PLATFORM" >> "$GITHUB_OUTPUT"
|
echo "platform=$PLATFORM" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "Detected platform: $PLATFORM"
|
||||||
|
|
||||||
- name: Setup PHP
|
- name: Setup PHP
|
||||||
if: steps.platform.outputs.platform == 'joomla' || steps.platform.outputs.platform == 'dolibarr'
|
if: steps.platform.outputs.platform == 'joomla' || steps.platform.outputs.platform == 'dolibarr'
|
||||||
@@ -282,10 +283,10 @@ jobs:
|
|||||||
for ELEMENT in name version description; do
|
for ELEMENT in name version description; do
|
||||||
grep -q "<${ELEMENT}>" "$MANIFEST" || { echo "::error::Missing <${ELEMENT}> in manifest"; exit 1; }
|
grep -q "<${ELEMENT}>" "$MANIFEST" || { echo "::error::Missing <${ELEMENT}> in manifest"; exit 1; }
|
||||||
done
|
done
|
||||||
# Block legacy raw/branch update server URLs on MokoGitea
|
# Block legacy raw/branch update server URLs on MokoGIT
|
||||||
RAW_URLS=$(grep -n 'raw/branch' "$MANIFEST" | grep -i 'mokoconsulting\|mokogitea\|git\.mokoconsulting\.tech' || true)
|
RAW_URLS=$(grep -n 'raw/branch' "$MANIFEST" | grep -i 'mokoconsulting\|mokogit\|git\.mokoconsulting\.tech' || true)
|
||||||
if [ -n "$RAW_URLS" ]; then
|
if [ -n "$RAW_URLS" ]; then
|
||||||
echo "::error::Manifest contains legacy raw/branch update server URL on MokoGitea. Use the Gitea Pages URL instead (e.g. /{REPO}/updates.xml not /{REPO}/raw/branch/main/updates.xml)"
|
echo "::error::Manifest contains legacy raw/branch update server URL on MokoGIT. Use the MokoGIT Pages URL instead (e.g. /{REPO}/updates.xml not /{REPO}/raw/branch/main/updates.xml)"
|
||||||
echo "$RAW_URLS"
|
echo "$RAW_URLS"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
@@ -496,12 +497,12 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Trigger RC pre-release
|
- name: Trigger RC pre-release
|
||||||
env:
|
env:
|
||||||
MOKOGITEA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
|
MOKOGIT_TOKEN: ${{ secrets.MOKOGIT_TOKEN }}
|
||||||
REPO: ${{ github.repository }}
|
REPO: ${{ github.repository }}
|
||||||
BRANCH: ${{ github.head_ref }}
|
BRANCH: ${{ github.head_ref }}
|
||||||
MOKOGITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
|
MOKOGIT_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
|
||||||
run: |
|
run: |
|
||||||
curl -s -X POST "${MOKOGITEA_URL}/api/v1/repos/${REPO}/actions/workflows/pre-release.yml/dispatches" -H "Authorization: token ${MOKOGITEA_TOKEN}" -H "Content-Type: application/json" -d "{\"ref\":\"${BRANCH}\",\"inputs\":{\"stability\":\"release-candidate\"}}"
|
curl -s -X POST "${MOKOGIT_URL}/api/v1/repos/${REPO}/actions/workflows/pre-release.yml/dispatches" -H "Authorization: token ${MOKOGIT_TOKEN}" -H "Content-Type: application/json" -d "{\"ref\":\"${BRANCH}\",\"inputs\":{\"stability\":\"release-candidate\"}}"
|
||||||
echo "### Pre-Release" >> $GITHUB_STEP_SUMMARY
|
echo "### Pre-Release" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "Triggered RC build on branch \`${BRANCH}\`" >> $GITHUB_STEP_SUMMARY
|
echo "Triggered RC build on branch \`${BRANCH}\`" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
@@ -512,7 +513,7 @@ jobs:
|
|||||||
if: >-
|
if: >-
|
||||||
always() &&
|
always() &&
|
||||||
needs.validate.result == 'failure'
|
needs.validate.result == 'failure'
|
||||||
uses: ./.mokogitea/workflows/ci-issue-reporter.yml
|
uses: ./.mokogit/workflows/ci-issue-reporter.yml
|
||||||
with:
|
with:
|
||||||
gate: "PR Validation"
|
gate: "PR Validation"
|
||||||
workflow: "PR Check"
|
workflow: "PR Check"
|
||||||
@@ -3,9 +3,9 @@
|
|||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
#
|
#
|
||||||
# FILE INFORMATION
|
# FILE INFORMATION
|
||||||
# DEFGROUP: Gitea.Workflow
|
# DEFGROUP: MokoGIT.Workflow
|
||||||
# INGROUP: mokocli.Release
|
# INGROUP: MokoCLI.Release
|
||||||
# REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoCLI
|
# REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
||||||
# PATH: /templates/workflows/universal/pre-release.yml.template
|
# PATH: /templates/workflows/universal/pre-release.yml.template
|
||||||
# VERSION: 05.02.00
|
# VERSION: 05.02.00
|
||||||
# BRIEF: Auto pre-release on push to dev/alpha/beta/rc branches
|
# BRIEF: Auto pre-release on push to dev/alpha/beta/rc branches
|
||||||
@@ -40,9 +40,9 @@ permissions:
|
|||||||
contents: write
|
contents: write
|
||||||
|
|
||||||
env:
|
env:
|
||||||
GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
|
GIT_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
|
||||||
GITEA_ORG: ${{ vars.GITEA_ORG || github.repository_owner }}
|
GIT_ORG: ${{ vars.GITEA_ORG || github.repository_owner }}
|
||||||
GITEA_REPO: ${{ vars.GITEA_REPO || github.event.repository.name }}
|
GIT_REPO: ${{ vars.GITEA_REPO || github.event.repository.name }}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
@@ -57,7 +57,7 @@ jobs:
|
|||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
token: ${{ secrets.MOKOGITEA_TOKEN }}
|
token: ${{ secrets.MOKOGIT_TOKEN }}
|
||||||
ref: ${{ github.ref_name }}
|
ref: ${{ github.ref_name }}
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
|
||||||
@@ -65,9 +65,9 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
git submodule foreach --quiet 'git checkout main && git pull --quiet origin main' 2>/dev/null || true
|
git submodule foreach --quiet 'git checkout main && git pull --quiet origin main' 2>/dev/null || true
|
||||||
|
|
||||||
- name: Setup mokocli tools
|
- name: Setup MokoCLI tools
|
||||||
env:
|
env:
|
||||||
MOKO_CLONE_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
|
MOKO_CLONE_TOKEN: ${{ secrets.MOKOGIT_TOKEN }}
|
||||||
MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting
|
MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting
|
||||||
run: |
|
run: |
|
||||||
# Use pre-installed /opt/mokocli if available (updated by cron every 6h)
|
# Use pre-installed /opt/mokocli if available (updated by cron every 6h)
|
||||||
@@ -80,7 +80,7 @@ jobs:
|
|||||||
sudo apt-get update -qq && sudo apt-get install -y -qq php-cli php-mbstring php-xml php-zip php-curl composer > /dev/null 2>&1
|
sudo apt-get update -qq && sudo apt-get install -y -qq php-cli php-mbstring php-xml php-zip php-curl composer > /dev/null 2>&1
|
||||||
fi
|
fi
|
||||||
rm -rf /tmp/mokocli
|
rm -rf /tmp/mokocli
|
||||||
CLONE_URL=https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/MokoCLI.git
|
CLONE_URL=https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/mokocli.git
|
||||||
git clone --depth 1 --branch main --quiet $CLONE_URL /tmp/mokocli
|
git clone --depth 1 --branch main --quiet $CLONE_URL /tmp/mokocli
|
||||||
cd /tmp/mokocli && composer install --no-dev --no-interaction --quiet
|
cd /tmp/mokocli && composer install --no-dev --no-interaction --quiet
|
||||||
echo MOKO_CLI=/tmp/mokocli/cli >> $GITHUB_ENV
|
echo MOKO_CLI=/tmp/mokocli/cli >> $GITHUB_ENV
|
||||||
@@ -152,9 +152,9 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Commit version bump
|
# Commit version bump
|
||||||
git config --local user.email "gitea-actions[bot]@mokoconsulting.tech"
|
git config --local user.email "mokogit-actions[bot]@mokoconsulting.tech"
|
||||||
git config --local user.name "gitea-actions[bot]"
|
git config --local user.name "mokogit-actions[bot]"
|
||||||
git remote set-url origin "https://x-access-token:${{ secrets.MOKOGITEA_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git"
|
git remote set-url origin "https://x-access-token:${{ secrets.MOKOGIT_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git"
|
||||||
git add -A
|
git add -A
|
||||||
git diff --cached --quiet || {
|
git diff --cached --quiet || {
|
||||||
git commit -m "chore(version): pre-release bump to ${VERSION} [skip ci]"
|
git commit -m "chore(version): pre-release bump to ${VERSION} [skip ci]"
|
||||||
@@ -164,12 +164,12 @@ jobs:
|
|||||||
# Auto-detect element via manifest_element.php
|
# Auto-detect element via manifest_element.php
|
||||||
php ${MOKO_CLI}/manifest_element.php \
|
php ${MOKO_CLI}/manifest_element.php \
|
||||||
--path . --version "$VERSION" --stability "$STABILITY" \
|
--path . --version "$VERSION" --stability "$STABILITY" \
|
||||||
--repo "${GITEA_REPO}" --github-output
|
--repo "${GIT_REPO}" --github-output
|
||||||
|
|
||||||
# Read back element outputs
|
# Read back element outputs
|
||||||
EXT_ELEMENT=$(grep '^ext_element=' "$GITHUB_OUTPUT" | tail -1 | cut -d= -f2)
|
EXT_ELEMENT=$(grep '^ext_element=' "$GITHUB_OUTPUT" | tail -1 | cut -d= -f2)
|
||||||
ZIP_NAME=$(grep '^zip_name=' "$GITHUB_OUTPUT" | tail -1 | cut -d= -f2)
|
ZIP_NAME=$(grep '^zip_name=' "$GITHUB_OUTPUT" | tail -1 | cut -d= -f2)
|
||||||
[ -z "$EXT_ELEMENT" ] && EXT_ELEMENT=$(echo "${GITEA_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -')
|
[ -z "$EXT_ELEMENT" ] && EXT_ELEMENT=$(echo "${GIT_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -')
|
||||||
[ -z "$ZIP_NAME" ] && ZIP_NAME="${EXT_ELEMENT}-${VERSION}.zip"
|
[ -z "$ZIP_NAME" ] && ZIP_NAME="${EXT_ELEMENT}-${VERSION}.zip"
|
||||||
|
|
||||||
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
|
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
|
||||||
@@ -187,18 +187,18 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
TAG="${{ steps.meta.outputs.tag }}"
|
TAG="${{ steps.meta.outputs.tag }}"
|
||||||
VERSION="${{ steps.meta.outputs.version }}"
|
VERSION="${{ steps.meta.outputs.version }}"
|
||||||
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
|
API_BASE="${GIT_URL}/api/v1/repos/${GIT_ORG}/${GIT_REPO}"
|
||||||
php ${MOKO_CLI}/release_create.php \
|
php ${MOKO_CLI}/release_create.php \
|
||||||
--path . --version "$VERSION" --tag "$TAG" \
|
--path . --version "$VERSION" --tag "$TAG" \
|
||||||
--token "${{ secrets.MOKOGITEA_TOKEN }}" --api-base "$API_BASE" \
|
--token "${{ secrets.MOKOGIT_TOKEN }}" --api-base "$API_BASE" \
|
||||||
--repo "${GITEA_REPO}" --branch "${{ github.ref_name }}" --prerelease
|
--repo "${GIT_REPO}" --branch "${{ github.ref_name }}" --prerelease
|
||||||
|
|
||||||
- name: Update release notes from CHANGELOG.md
|
- name: Update release notes from CHANGELOG.md
|
||||||
if: steps.eligibility.outputs.proceed == 'true'
|
if: steps.eligibility.outputs.proceed == 'true'
|
||||||
run: |
|
run: |
|
||||||
TAG="${{ steps.meta.outputs.tag }}"
|
TAG="${{ steps.meta.outputs.tag }}"
|
||||||
VERSION="${{ steps.meta.outputs.version }}"
|
VERSION="${{ steps.meta.outputs.version }}"
|
||||||
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
|
API_BASE="${GIT_URL}/api/v1/repos/${GIT_ORG}/${GIT_REPO}"
|
||||||
|
|
||||||
# Extract [Unreleased] section from changelog (everything between [Unreleased] and next ## heading)
|
# Extract [Unreleased] section from changelog (everything between [Unreleased] and next ## heading)
|
||||||
if [ -f "CHANGELOG.md" ]; then
|
if [ -f "CHANGELOG.md" ]; then
|
||||||
@@ -209,7 +209,7 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Update release body via API
|
# Update release body via API
|
||||||
RELEASE_ID=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \
|
RELEASE_ID=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGIT_TOKEN }}" \
|
||||||
"${API_BASE}/releases/tags/${TAG}" | python3 -c "import json,sys; print(json.load(sys.stdin).get('id',''))" 2>/dev/null || true)
|
"${API_BASE}/releases/tags/${TAG}" | python3 -c "import json,sys; print(json.load(sys.stdin).get('id',''))" 2>/dev/null || true)
|
||||||
|
|
||||||
if [ -n "$RELEASE_ID" ]; then
|
if [ -n "$RELEASE_ID" ]; then
|
||||||
@@ -221,7 +221,7 @@ jobs:
|
|||||||
'${API_BASE}/releases/${RELEASE_ID}',
|
'${API_BASE}/releases/${RELEASE_ID}',
|
||||||
data=payload, method='PATCH',
|
data=payload, method='PATCH',
|
||||||
headers={
|
headers={
|
||||||
'Authorization': 'token ${{ secrets.MOKOGITEA_TOKEN }}',
|
'Authorization': 'token ${{ secrets.MOKOGIT_TOKEN }}',
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json'
|
||||||
})
|
})
|
||||||
urllib.request.urlopen(req)
|
urllib.request.urlopen(req)
|
||||||
@@ -235,21 +235,21 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
VERSION="${{ steps.meta.outputs.version }}"
|
VERSION="${{ steps.meta.outputs.version }}"
|
||||||
TAG="${{ steps.meta.outputs.tag }}"
|
TAG="${{ steps.meta.outputs.tag }}"
|
||||||
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
|
API_BASE="${GIT_URL}/api/v1/repos/${GIT_ORG}/${GIT_REPO}"
|
||||||
php ${MOKO_CLI}/release_package.php \
|
php ${MOKO_CLI}/release_package.php \
|
||||||
--path . --version "$VERSION" --tag "$TAG" \
|
--path . --version "$VERSION" --tag "$TAG" \
|
||||||
--token "${{ secrets.MOKOGITEA_TOKEN }}" --api-base "$API_BASE" \
|
--token "${{ secrets.MOKOGIT_TOKEN }}" --api-base "$API_BASE" \
|
||||||
--repo "${GITEA_REPO}" --output /tmp || true
|
--repo "${GIT_REPO}" --output /tmp || true
|
||||||
|
|
||||||
# updates.xml is generated dynamically by MokoGitea license server
|
# updates.xml is generated dynamically by MokoGIT license server
|
||||||
# No need to build, commit, or sync updates.xml from workflows
|
# No need to build, commit, or sync updates.xml from workflows
|
||||||
|
|
||||||
- name: "Delete lesser pre-release channels (cascade)"
|
- name: "Delete lesser pre-release channels (cascade)"
|
||||||
if: steps.eligibility.outputs.proceed == 'true'
|
if: steps.eligibility.outputs.proceed == 'true'
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
run: |
|
run: |
|
||||||
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
|
API_BASE="${GIT_URL}/api/v1/repos/${GIT_ORG}/${GIT_REPO}"
|
||||||
TOKEN="${{ secrets.MOKOGITEA_TOKEN }}"
|
TOKEN="${{ secrets.MOKOGIT_TOKEN }}"
|
||||||
|
|
||||||
php ${MOKO_CLI}/release_cascade.php \
|
php ${MOKO_CLI}/release_cascade.php \
|
||||||
--stability "${{ steps.meta.outputs.stability }}" \
|
--stability "${{ steps.meta.outputs.stability }}" \
|
||||||
@@ -3,10 +3,10 @@
|
|||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
#
|
#
|
||||||
# FILE INFORMATION
|
# FILE INFORMATION
|
||||||
# DEFGROUP: Gitea.Workflow
|
# DEFGROUP: MokoGIT.Workflow
|
||||||
# INGROUP: mokocli.Universal
|
# INGROUP: MokoCLI.Universal
|
||||||
# REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoCLI
|
# REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
||||||
# PATH: /.mokogitea/workflows/rc-revert.yml
|
# PATH: /.mokogit/workflows/rc-revert.yml
|
||||||
# VERSION: 09.23.00
|
# VERSION: 09.23.00
|
||||||
# BRIEF: Rename rc/ branch back to dev/ when PR is closed without merge
|
# BRIEF: Rename rc/ branch back to dev/ when PR is closed without merge
|
||||||
|
|
||||||
@@ -32,8 +32,8 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
BRANCH: ${{ github.event.pull_request.head.ref }}
|
BRANCH: ${{ github.event.pull_request.head.ref }}
|
||||||
REPO: ${{ github.repository }}
|
REPO: ${{ github.repository }}
|
||||||
GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
|
GIT_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
|
||||||
TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
|
TOKEN: ${{ secrets.MOKOGIT_TOKEN }}
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
# BRANCH is attacker-controlled (PR head ref). Strict allowlist before ANY use.
|
# BRANCH is attacker-controlled (PR head ref). Strict allowlist before ANY use.
|
||||||
@@ -42,7 +42,7 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
SUFFIX="${BRANCH#rc/}"
|
SUFFIX="${BRANCH#rc/}"
|
||||||
DEV_BRANCH="dev/${SUFFIX}"
|
DEV_BRANCH="dev/${SUFFIX}"
|
||||||
API="${GITEA_URL}/api/v1/repos/${REPO}/branches"
|
API="${GIT_URL}/api/v1/repos/${REPO}/branches"
|
||||||
|
|
||||||
# Create dev/ branch from rc/ branch
|
# Create dev/ branch from rc/ branch
|
||||||
STATUS=$(curl -sf -o /dev/null -w "%{http_code}" -X POST \
|
STATUS=$(curl -sf -o /dev/null -w "%{http_code}" -X POST \
|
||||||
@@ -6,9 +6,9 @@
|
|||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
#
|
#
|
||||||
# FILE INFORMATION
|
# FILE INFORMATION
|
||||||
# DEFGROUP: Gitea.Workflow
|
# DEFGROUP: MokoGIT.Workflow
|
||||||
# INGROUP: mokocli.Validation
|
# INGROUP: MokoCLI.Validation
|
||||||
# REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoCLI
|
# REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
||||||
# PATH: /templates/workflows/joomla/repo_health.yml.template
|
# PATH: /templates/workflows/joomla/repo_health.yml.template
|
||||||
# VERSION: 09.23.00
|
# VERSION: 09.23.00
|
||||||
# BRIEF: Enforces repository guardrails by validating scripts governance, tooling availability, and core repository health artifacts.
|
# BRIEF: Enforces repository guardrails by validating scripts governance, tooling availability, and core repository health artifacts.
|
||||||
@@ -45,7 +45,7 @@ env:
|
|||||||
SCRIPTS_ALLOWED_DIRS: scripts,scripts/fix,scripts/lib,scripts/release,scripts/run,scripts/validate
|
SCRIPTS_ALLOWED_DIRS: scripts,scripts/fix,scripts/lib,scripts/release,scripts/run,scripts/validate
|
||||||
|
|
||||||
# Repo health policy
|
# Repo health policy
|
||||||
REPO_REQUIRED_ARTIFACTS: README.md,LICENSE,CHANGELOG.md,CONTRIBUTING.md,CODE_OF_CONDUCT.md,.mokogitea/workflows/
|
REPO_REQUIRED_ARTIFACTS: README.md,LICENSE,CHANGELOG.md,CONTRIBUTING.md,CODE_OF_CONDUCT.md,.mokogit/workflows/
|
||||||
REPO_OPTIONAL_FILES: SECURITY.md,GOVERNANCE.md,.editorconfig,.gitattributes,.gitignore,README.md,docs/
|
REPO_OPTIONAL_FILES: SECURITY.md,GOVERNANCE.md,.editorconfig,.gitattributes,.gitignore,README.md,docs/
|
||||||
REPO_DISALLOWED_DIRS:
|
REPO_DISALLOWED_DIRS:
|
||||||
REPO_DISALLOWED_FILES: TODO.md,todo.md
|
REPO_DISALLOWED_FILES: TODO.md,todo.md
|
||||||
@@ -56,7 +56,7 @@ env:
|
|||||||
# File / directory variables
|
# File / directory variables
|
||||||
DOCS_INDEX: docs/docs-index.md
|
DOCS_INDEX: docs/docs-index.md
|
||||||
SCRIPT_DIR: scripts
|
SCRIPT_DIR: scripts
|
||||||
WORKFLOWS_DIR: .mokogitea/workflows
|
WORKFLOWS_DIR: .mokogit/workflows
|
||||||
SHELLCHECK_PATTERN: '*.sh'
|
SHELLCHECK_PATTERN: '*.sh'
|
||||||
SPDX_FILE_GLOBS: '*.sh,*.php,*.js,*.ts,*.css,*.xml,*.yml,*.yaml'
|
SPDX_FILE_GLOBS: '*.sh,*.php,*.js,*.ts,*.css,*.xml,*.yml,*.yaml'
|
||||||
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
|
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
|
||||||
@@ -77,7 +77,7 @@ jobs:
|
|||||||
- name: Check actor permission (admin only)
|
- name: Check actor permission (admin only)
|
||||||
id: perm
|
id: perm
|
||||||
env:
|
env:
|
||||||
TOKEN: ${{ secrets.MOKOGITEA_TOKEN || github.token }}
|
TOKEN: ${{ secrets.MOKOGIT_TOKEN || github.token }}
|
||||||
REPO: ${{ github.repository }}
|
REPO: ${{ github.repository }}
|
||||||
ACTOR: ${{ github.actor }}
|
ACTOR: ${{ github.actor }}
|
||||||
run: |
|
run: |
|
||||||
@@ -88,14 +88,14 @@ jobs:
|
|||||||
|
|
||||||
# Hardcoded authorized users — always allowed
|
# Hardcoded authorized users — always allowed
|
||||||
case "$ACTOR" in
|
case "$ACTOR" in
|
||||||
jmiller|gitea-actions[bot])
|
jmiller|mokogit-actions[bot])
|
||||||
ALLOWED=true
|
ALLOWED=true
|
||||||
PERMISSION=admin
|
PERMISSION=admin
|
||||||
METHOD="hardcoded allowlist"
|
METHOD="hardcoded allowlist"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
# Detect platform and check permissions via API
|
# Detect platform and check permissions via API
|
||||||
API_BASE="${GITHUB_API_URL:-${GITEA_API_URL:-https://api.github.com}}"
|
API_BASE="${GITHUB_API_URL:-${GIT_API_URL:-https://api.github.com}}"
|
||||||
RESP=$(curl -sf -H "Authorization: token ${TOKEN}" \
|
RESP=$(curl -sf -H "Authorization: token ${TOKEN}" \
|
||||||
"${API_BASE}/repos/${REPO}/collaborators/${ACTOR}/permission" 2>/dev/null || echo '{}')
|
"${API_BASE}/repos/${REPO}/collaborators/${ACTOR}/permission" 2>/dev/null || echo '{}')
|
||||||
PERMISSION=$(echo "$RESP" | grep -oP '"permission"\s*:\s*"\K[^"]+' || echo "unknown")
|
PERMISSION=$(echo "$RESP" | grep -oP '"permission"\s*:\s*"\K[^"]+' || echo "unknown")
|
||||||
@@ -605,7 +605,7 @@ jobs:
|
|||||||
printf '%s\n' '| Domain | Status | Notes |'
|
printf '%s\n' '| Domain | Status | Notes |'
|
||||||
printf '%s\n' '|---|---|---|'
|
printf '%s\n' '|---|---|---|'
|
||||||
printf '%s\n' '| Access control | OK | Admin-only execution gate |'
|
printf '%s\n' '| Access control | OK | Admin-only execution gate |'
|
||||||
printf '%s\n' '| Release policy | N/A | Releases handled by MokoGitea |'
|
printf '%s\n' '| Release policy | N/A | Releases handled by MokoGIT |'
|
||||||
printf '%s\n' '| Scripts governance | OK | Directory policy and advisory reporting |'
|
printf '%s\n' '| Scripts governance | OK | Directory policy and advisory reporting |'
|
||||||
printf '%s\n' '| Repo required artifacts | OK | Required, optional, disallowed enforcement |'
|
printf '%s\n' '| Repo required artifacts | OK | Required, optional, disallowed enforcement |'
|
||||||
printf '%s\n' '| Repo content heuristics | OK | Brand, license, changelog structure |'
|
printf '%s\n' '| Repo content heuristics | OK | Brand, license, changelog structure |'
|
||||||
@@ -677,7 +677,7 @@ jobs:
|
|||||||
if: >-
|
if: >-
|
||||||
always() &&
|
always() &&
|
||||||
needs.scripts_governance.result == 'failure'
|
needs.scripts_governance.result == 'failure'
|
||||||
uses: ./.mokogitea/workflows/ci-issue-reporter.yml
|
uses: ./.mokogit/workflows/ci-issue-reporter.yml
|
||||||
with:
|
with:
|
||||||
gate: "Scripts Governance"
|
gate: "Scripts Governance"
|
||||||
workflow: "Repo Health"
|
workflow: "Repo Health"
|
||||||
@@ -691,7 +691,7 @@ jobs:
|
|||||||
if: >-
|
if: >-
|
||||||
always() &&
|
always() &&
|
||||||
needs.repo_health.result == 'failure'
|
needs.repo_health.result == 'failure'
|
||||||
uses: ./.mokogitea/workflows/ci-issue-reporter.yml
|
uses: ./.mokogit/workflows/ci-issue-reporter.yml
|
||||||
with:
|
with:
|
||||||
gate: "Repository Health"
|
gate: "Repository Health"
|
||||||
workflow: "Repo Health"
|
workflow: "Repo Health"
|
||||||
@@ -0,0 +1,525 @@
|
|||||||
|
# Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||||
|
#
|
||||||
|
# This file is part of a Moko Consulting project.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
#
|
||||||
|
# FILE INFORMATION
|
||||||
|
# DEFGROUP: GitHub.Workflow
|
||||||
|
# INGROUP: MokoStandards.Maintenance
|
||||||
|
# REPO: https://github.com/mokoconsulting-tech/MokoStandards
|
||||||
|
# PATH: /templates/workflows/shared/repository-cleanup.yml.template
|
||||||
|
# VERSION: 04.06.00
|
||||||
|
# BRIEF: Recurring repository maintenance — labels, branches, workflows, logs, doc indexes
|
||||||
|
# NOTE: Synced via bulk-repo-sync to .mokogit/workflows/repository-cleanup.yml in all governed repos.
|
||||||
|
# Runs on the 1st and 15th of each month at 6:00 AM UTC, and on manual dispatch.
|
||||||
|
|
||||||
|
name: "Universal: Repository Cleanup"
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 6 1,15 * *'
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
reset_labels:
|
||||||
|
description: 'Delete ALL existing labels and recreate the standard set'
|
||||||
|
type: boolean
|
||||||
|
default: false
|
||||||
|
clean_branches:
|
||||||
|
description: 'Delete old chore/sync-mokostandards-* branches'
|
||||||
|
type: boolean
|
||||||
|
default: true
|
||||||
|
clean_workflows:
|
||||||
|
description: 'Delete orphaned workflow runs (cancelled, stale)'
|
||||||
|
type: boolean
|
||||||
|
default: true
|
||||||
|
clean_logs:
|
||||||
|
description: 'Delete workflow run logs older than 30 days'
|
||||||
|
type: boolean
|
||||||
|
default: true
|
||||||
|
fix_templates:
|
||||||
|
description: 'Strip copyright comment blocks from issue templates'
|
||||||
|
type: boolean
|
||||||
|
default: true
|
||||||
|
rebuild_indexes:
|
||||||
|
description: 'Rebuild docs/ index files'
|
||||||
|
type: boolean
|
||||||
|
default: true
|
||||||
|
delete_closed_issues:
|
||||||
|
description: 'Delete issues that have been closed for more than 30 days'
|
||||||
|
type: boolean
|
||||||
|
default: false
|
||||||
|
|
||||||
|
env:
|
||||||
|
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
issues: write
|
||||||
|
actions: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
cleanup:
|
||||||
|
name: Repository Maintenance
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.GH_TOKEN || github.token }}
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Check actor permission
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GH_TOKEN || github.token }}
|
||||||
|
run: |
|
||||||
|
ACTOR="${{ github.actor }}"
|
||||||
|
# Schedule triggers use github-actions[bot]
|
||||||
|
if [ "${{ github.event_name }}" = "schedule" ]; then
|
||||||
|
echo "✅ Scheduled run — authorized"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
AUTHORIZED_USERS="jmiller github-actions[bot]"
|
||||||
|
for user in $AUTHORIZED_USERS; do
|
||||||
|
if [ "$ACTOR" = "$user" ]; then
|
||||||
|
echo "✅ ${ACTOR} authorized"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
PERMISSION=$(gh api "repos/${{ github.repository }}/collaborators/${ACTOR}/permission" \
|
||||||
|
--jq '.permission' 2>/dev/null)
|
||||||
|
case "$PERMISSION" in
|
||||||
|
admin|maintain) echo "✅ ${ACTOR} has ${PERMISSION}" ;;
|
||||||
|
*) echo "❌ Admin or maintain required"; exit 1 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# ── Determine which tasks to run ─────────────────────────────────────
|
||||||
|
# On schedule: run all tasks with safe defaults (labels NOT reset)
|
||||||
|
# On dispatch: use input toggles
|
||||||
|
- name: Set task flags
|
||||||
|
id: tasks
|
||||||
|
run: |
|
||||||
|
if [ "${{ github.event_name }}" = "schedule" ]; then
|
||||||
|
echo "reset_labels=false" >> $GITHUB_OUTPUT
|
||||||
|
echo "clean_branches=true" >> $GITHUB_OUTPUT
|
||||||
|
echo "clean_workflows=true" >> $GITHUB_OUTPUT
|
||||||
|
echo "clean_logs=true" >> $GITHUB_OUTPUT
|
||||||
|
echo "fix_templates=true" >> $GITHUB_OUTPUT
|
||||||
|
echo "rebuild_indexes=true" >> $GITHUB_OUTPUT
|
||||||
|
echo "delete_closed_issues=false" >> $GITHUB_OUTPUT
|
||||||
|
else
|
||||||
|
echo "reset_labels=${{ inputs.reset_labels }}" >> $GITHUB_OUTPUT
|
||||||
|
echo "clean_branches=${{ inputs.clean_branches }}" >> $GITHUB_OUTPUT
|
||||||
|
echo "clean_workflows=${{ inputs.clean_workflows }}" >> $GITHUB_OUTPUT
|
||||||
|
echo "clean_logs=${{ inputs.clean_logs }}" >> $GITHUB_OUTPUT
|
||||||
|
echo "fix_templates=${{ inputs.fix_templates }}" >> $GITHUB_OUTPUT
|
||||||
|
echo "rebuild_indexes=${{ inputs.rebuild_indexes }}" >> $GITHUB_OUTPUT
|
||||||
|
echo "delete_closed_issues=${{ inputs.delete_closed_issues }}" >> $GITHUB_OUTPUT
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── DELETE RETIRED WORKFLOWS (always runs) ────────────────────────────
|
||||||
|
- name: Delete retired workflow files
|
||||||
|
run: |
|
||||||
|
echo "## 🗑️ Retired Workflow Cleanup" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
|
RETIRED=(
|
||||||
|
".github/workflows/build.yml"
|
||||||
|
".github/workflows/code-quality.yml"
|
||||||
|
".github/workflows/release-cycle.yml"
|
||||||
|
".github/workflows/release-pipeline.yml"
|
||||||
|
".github/workflows/branch-cleanup.yml"
|
||||||
|
".github/workflows/auto-update-changelog.yml"
|
||||||
|
".github/workflows/enterprise-issue-manager.yml"
|
||||||
|
".github/workflows/flush-actions-cache.yml"
|
||||||
|
".github/workflows/mokostandards-script-runner.yml"
|
||||||
|
".github/workflows/unified-ci.yml"
|
||||||
|
".github/workflows/unified-platform-testing.yml"
|
||||||
|
".github/workflows/reusable-build.yml"
|
||||||
|
".github/workflows/reusable-ci-validation.yml"
|
||||||
|
".github/workflows/reusable-deploy.yml"
|
||||||
|
".github/workflows/reusable-php-quality.yml"
|
||||||
|
".github/workflows/reusable-platform-testing.yml"
|
||||||
|
".github/workflows/reusable-project-detector.yml"
|
||||||
|
".github/workflows/reusable-release.yml"
|
||||||
|
".github/workflows/reusable-script-executor.yml"
|
||||||
|
".github/workflows/rebuild-docs-indexes.yml"
|
||||||
|
".github/workflows/setup-project-v2.yml"
|
||||||
|
".github/workflows/sync-docs-to-project.yml"
|
||||||
|
".github/workflows/release.yml"
|
||||||
|
".github/workflows/sync-changelogs.yml"
|
||||||
|
".github/workflows/version_branch.yml"
|
||||||
|
"update.json"
|
||||||
|
".github/workflows/auto-version-branch.yml"
|
||||||
|
".github/workflows/publish-to-mokodolibarr.yml"
|
||||||
|
".github/workflows/ci.yml"
|
||||||
|
".github/workflows/deploy-rs.yml"
|
||||||
|
"sftp-config.json"
|
||||||
|
"sftp-config.json.template"
|
||||||
|
"scripts/sftp-config"
|
||||||
|
)
|
||||||
|
|
||||||
|
DELETED=0
|
||||||
|
for wf in "${RETIRED[@]}"; do
|
||||||
|
if [ -f "$wf" ]; then
|
||||||
|
git rm "$wf" 2>/dev/null || rm -f "$wf"
|
||||||
|
echo " Deleted: \`$(basename $wf)\`" >> $GITHUB_STEP_SUMMARY
|
||||||
|
DELETED=$((DELETED+1))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "$DELETED" -gt 0 ]; then
|
||||||
|
git config --local user.email "github-actions[bot]@users.noreply.github.com"
|
||||||
|
git config --local user.name "github-actions[bot]"
|
||||||
|
git add -A
|
||||||
|
git commit -m "chore: delete ${DELETED} retired workflow file(s) [skip ci]" \
|
||||||
|
--author="github-actions[bot] <github-actions[bot]@users.noreply.github.com>"
|
||||||
|
git push
|
||||||
|
echo "✅ ${DELETED} retired workflow(s) deleted" >> $GITHUB_STEP_SUMMARY
|
||||||
|
else
|
||||||
|
echo "✅ No retired workflows found" >> $GITHUB_STEP_SUMMARY
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── LABEL RESET ──────────────────────────────────────────────────────
|
||||||
|
- name: Reset labels to standard set
|
||||||
|
if: steps.tasks.outputs.reset_labels == 'true'
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GH_TOKEN || github.token }}
|
||||||
|
run: |
|
||||||
|
REPO="${{ github.repository }}"
|
||||||
|
echo "## 🏷️ Label Reset" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
|
gh api "repos/${REPO}/labels?per_page=100" --paginate --jq '.[].name' | while read -r label; do
|
||||||
|
ENCODED=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$label', safe=''))")
|
||||||
|
gh api -X DELETE "repos/${REPO}/labels/${ENCODED}" --silent 2>/dev/null || true
|
||||||
|
done
|
||||||
|
|
||||||
|
while IFS='|' read -r name color description; do
|
||||||
|
[ -z "$name" ] && continue
|
||||||
|
gh api "repos/${REPO}/labels" \
|
||||||
|
-f name="$name" -f color="$color" -f description="$description" \
|
||||||
|
--silent 2>/dev/null || true
|
||||||
|
done << 'LABELS'
|
||||||
|
joomla|7F52FF|Joomla extension or component
|
||||||
|
dolibarr|FF6B6B|Dolibarr module or extension
|
||||||
|
generic|808080|Generic project or library
|
||||||
|
php|4F5D95|PHP code changes
|
||||||
|
javascript|F7DF1E|JavaScript code changes
|
||||||
|
typescript|3178C6|TypeScript code changes
|
||||||
|
python|3776AB|Python code changes
|
||||||
|
css|1572B6|CSS/styling changes
|
||||||
|
html|E34F26|HTML template changes
|
||||||
|
documentation|0075CA|Documentation changes
|
||||||
|
ci-cd|000000|CI/CD pipeline changes
|
||||||
|
docker|2496ED|Docker configuration changes
|
||||||
|
tests|00FF00|Test suite changes
|
||||||
|
security|FF0000|Security-related changes
|
||||||
|
dependencies|0366D6|Dependency updates
|
||||||
|
config|F9D0C4|Configuration file changes
|
||||||
|
build|FFA500|Build system changes
|
||||||
|
automation|8B4513|Automated processes or scripts
|
||||||
|
mokostandards|B60205|MokoStandards compliance
|
||||||
|
needs-review|FBCA04|Awaiting code review
|
||||||
|
work-in-progress|D93F0B|Work in progress, not ready for merge
|
||||||
|
breaking-change|D73A4A|Breaking API or functionality change
|
||||||
|
priority: critical|B60205|Critical priority, must be addressed immediately
|
||||||
|
priority: high|D93F0B|High priority
|
||||||
|
priority: medium|FBCA04|Medium priority
|
||||||
|
priority: low|0E8A16|Low priority
|
||||||
|
type: bug|D73A4A|Something isn't working
|
||||||
|
type: feature|A2EEEF|New feature or request
|
||||||
|
type: enhancement|84B6EB|Enhancement to existing feature
|
||||||
|
type: refactor|F9D0C4|Code refactoring
|
||||||
|
type: chore|FEF2C0|Maintenance tasks
|
||||||
|
type: version|0E8A16|Version-related change
|
||||||
|
status: pending|FBCA04|Pending action or decision
|
||||||
|
status: in-progress|0E8A16|Currently being worked on
|
||||||
|
status: blocked|B60205|Blocked by another issue or dependency
|
||||||
|
status: on-hold|D4C5F9|Temporarily on hold
|
||||||
|
status: wontfix|FFFFFF|This will not be worked on
|
||||||
|
size/xs|C5DEF5|Extra small change (1-10 lines)
|
||||||
|
size/s|6FD1E2|Small change (11-30 lines)
|
||||||
|
size/m|F9DD72|Medium change (31-100 lines)
|
||||||
|
size/l|FFA07A|Large change (101-300 lines)
|
||||||
|
size/xl|FF6B6B|Extra large change (301-1000 lines)
|
||||||
|
size/xxl|B60205|Extremely large change (1000+ lines)
|
||||||
|
health: excellent|0E8A16|Health score 90-100
|
||||||
|
health: good|FBCA04|Health score 70-89
|
||||||
|
health: fair|FFA500|Health score 50-69
|
||||||
|
health: poor|FF6B6B|Health score below 50
|
||||||
|
standards-update|B60205|MokoStandards sync update
|
||||||
|
standards-drift|FBCA04|Repository drifted from MokoStandards
|
||||||
|
sync-report|0075CA|Bulk sync run report
|
||||||
|
sync-failure|D73A4A|Bulk sync failure requiring attention
|
||||||
|
push-failure|D73A4A|File push failure requiring attention
|
||||||
|
health-check|0E8A16|Repository health check results
|
||||||
|
version-drift|FFA500|Version mismatch detected
|
||||||
|
deploy-failure|CC0000|Automated deploy failure tracking
|
||||||
|
template-validation-failure|D73A4A|Template workflow validation failure
|
||||||
|
version|0E8A16|Version bump or release
|
||||||
|
LABELS
|
||||||
|
|
||||||
|
echo "✅ Standard labels created" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
|
# ── BRANCH CLEANUP ───────────────────────────────────────────────────
|
||||||
|
- name: Delete old sync branches
|
||||||
|
if: steps.tasks.outputs.clean_branches == 'true'
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GH_TOKEN || github.token }}
|
||||||
|
run: |
|
||||||
|
REPO="${{ github.repository }}"
|
||||||
|
CURRENT="chore/sync-mokostandards-v04.05"
|
||||||
|
echo "## 🌿 Branch Cleanup" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
|
FOUND=false
|
||||||
|
gh api "repos/${REPO}/branches?per_page=100" --jq '.[].name' | \
|
||||||
|
grep "^chore/sync-mokostandards" | \
|
||||||
|
grep -v "^${CURRENT}$" | while read -r branch; do
|
||||||
|
gh pr list --repo "$REPO" --head "$branch" --state open --json number --jq '.[].number' 2>/dev/null | while read -r pr; do
|
||||||
|
gh pr close "$pr" --repo "$REPO" --comment "Superseded by \`${CURRENT}\`" 2>/dev/null || true
|
||||||
|
echo " Closed PR #${pr}" >> $GITHUB_STEP_SUMMARY
|
||||||
|
done
|
||||||
|
gh api -X DELETE "repos/${REPO}/git/refs/heads/${branch}" --silent 2>/dev/null || true
|
||||||
|
echo " Deleted: \`${branch}\`" >> $GITHUB_STEP_SUMMARY
|
||||||
|
FOUND=true
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "$FOUND" != "true" ]; then
|
||||||
|
echo "✅ No old sync branches found" >> $GITHUB_STEP_SUMMARY
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── WORKFLOW RUN CLEANUP ─────────────────────────────────────────────
|
||||||
|
- name: Clean up workflow runs
|
||||||
|
if: steps.tasks.outputs.clean_workflows == 'true'
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GH_TOKEN || github.token }}
|
||||||
|
run: |
|
||||||
|
REPO="${{ github.repository }}"
|
||||||
|
echo "## 🔄 Workflow Run Cleanup" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
|
DELETED=0
|
||||||
|
# Delete cancelled and stale workflow runs
|
||||||
|
for status in cancelled stale; do
|
||||||
|
gh api "repos/${REPO}/actions/runs?status=${status}&per_page=100" \
|
||||||
|
--jq '.workflow_runs[].id' 2>/dev/null | while read -r run_id; do
|
||||||
|
gh api -X DELETE "repos/${REPO}/actions/runs/${run_id}" --silent 2>/dev/null || true
|
||||||
|
DELETED=$((DELETED+1))
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "✅ Cleaned cancelled/stale workflow runs" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
|
# ── LOG CLEANUP ──────────────────────────────────────────────────────
|
||||||
|
- name: Delete old workflow run logs
|
||||||
|
if: steps.tasks.outputs.clean_logs == 'true'
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GH_TOKEN || github.token }}
|
||||||
|
run: |
|
||||||
|
REPO="${{ github.repository }}"
|
||||||
|
CUTOFF=$(date -u -d '30 days ago' +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -v-30d +%Y-%m-%dT%H:%M:%SZ)
|
||||||
|
echo "## 📋 Log Cleanup" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "Deleting logs older than: ${CUTOFF}" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
|
DELETED=0
|
||||||
|
gh api "repos/${REPO}/actions/runs?created=<${CUTOFF}&per_page=100" \
|
||||||
|
--jq '.workflow_runs[].id' 2>/dev/null | while read -r run_id; do
|
||||||
|
gh api -X DELETE "repos/${REPO}/actions/runs/${run_id}/logs" --silent 2>/dev/null || true
|
||||||
|
DELETED=$((DELETED+1))
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "✅ Cleaned old workflow run logs" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
|
# ── ISSUE TEMPLATE FIX ──────────────────────────────────────────────
|
||||||
|
- name: Strip copyright headers from issue templates
|
||||||
|
if: steps.tasks.outputs.fix_templates == 'true'
|
||||||
|
run: |
|
||||||
|
echo "## 📋 Issue Template Cleanup" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
|
FIXED=0
|
||||||
|
for f in .github/ISSUE_TEMPLATE/*.md; do
|
||||||
|
[ -f "$f" ] || continue
|
||||||
|
if grep -q '^<!--$' "$f"; then
|
||||||
|
sed -i '/^<!--$/,/^-->$/d' "$f"
|
||||||
|
echo " Cleaned: \`$(basename $f)\`" >> $GITHUB_STEP_SUMMARY
|
||||||
|
FIXED=$((FIXED+1))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "$FIXED" -gt 0 ]; then
|
||||||
|
git config --local user.email "github-actions[bot]@users.noreply.github.com"
|
||||||
|
git config --local user.name "github-actions[bot]"
|
||||||
|
git add .github/ISSUE_TEMPLATE/
|
||||||
|
git commit -m "fix: strip copyright comment blocks from issue templates [skip ci]" \
|
||||||
|
--author="github-actions[bot] <github-actions[bot]@users.noreply.github.com>"
|
||||||
|
git push
|
||||||
|
echo "✅ ${FIXED} template(s) cleaned and committed" >> $GITHUB_STEP_SUMMARY
|
||||||
|
else
|
||||||
|
echo "✅ No templates need cleaning" >> $GITHUB_STEP_SUMMARY
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── REBUILD DOC INDEXES ─────────────────────────────────────────────
|
||||||
|
- name: Rebuild docs/ index files
|
||||||
|
if: steps.tasks.outputs.rebuild_indexes == 'true'
|
||||||
|
run: |
|
||||||
|
echo "## 📚 Documentation Index Rebuild" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
|
if [ ! -d "docs" ]; then
|
||||||
|
echo "⏭️ No docs/ directory — skipping" >> $GITHUB_STEP_SUMMARY
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
UPDATED=0
|
||||||
|
# Generate index.md for each docs/ subdirectory
|
||||||
|
find docs -type d | while read -r dir; do
|
||||||
|
INDEX="${dir}/index.md"
|
||||||
|
FILES=$(find "$dir" -maxdepth 1 -name "*.md" ! -name "index.md" -printf "- [%f](./%f)\n" 2>/dev/null | sort)
|
||||||
|
if [ -z "$FILES" ]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat > "$INDEX" << INDEXEOF
|
||||||
|
# $(basename "$dir")
|
||||||
|
|
||||||
|
## Documents
|
||||||
|
|
||||||
|
${FILES}
|
||||||
|
|
||||||
|
---
|
||||||
|
*Auto-generated by repository-cleanup workflow*
|
||||||
|
INDEXEOF
|
||||||
|
# Dedent
|
||||||
|
sed -i 's/^ //' "$INDEX"
|
||||||
|
UPDATED=$((UPDATED+1))
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "$UPDATED" -gt 0 ]; then
|
||||||
|
git config --local user.email "github-actions[bot]@users.noreply.github.com"
|
||||||
|
git config --local user.name "github-actions[bot]"
|
||||||
|
git add docs/
|
||||||
|
if ! git diff --cached --quiet; then
|
||||||
|
git commit -m "docs: rebuild documentation indexes [skip ci]" \
|
||||||
|
--author="github-actions[bot] <github-actions[bot]@users.noreply.github.com>"
|
||||||
|
git push
|
||||||
|
echo "✅ ${UPDATED} index file(s) rebuilt and committed" >> $GITHUB_STEP_SUMMARY
|
||||||
|
else
|
||||||
|
echo "✅ All indexes already up to date" >> $GITHUB_STEP_SUMMARY
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "✅ No indexes to rebuild" >> $GITHUB_STEP_SUMMARY
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── VERSION DRIFT DETECTION ──────────────────────────────────────────
|
||||||
|
- name: Check for version drift
|
||||||
|
run: |
|
||||||
|
echo "## 📦 Version Drift Check" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
|
if [ ! -f "README.md" ]; then
|
||||||
|
echo "⏭️ No README.md — skipping" >> $GITHUB_STEP_SUMMARY
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
README_VERSION=$(grep -oP '^\s*VERSION:\s*\K[0-9]{2}\.[0-9]{2}\.[0-9]{2}' README.md 2>/dev/null | head -1)
|
||||||
|
if [ -z "$README_VERSION" ]; then
|
||||||
|
echo "⚠️ No VERSION found in README.md FILE INFORMATION block" >> $GITHUB_STEP_SUMMARY
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "**README version:** \`${README_VERSION}\`" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
|
DRIFT=0
|
||||||
|
CHECKED=0
|
||||||
|
|
||||||
|
# Check all files with FILE INFORMATION blocks
|
||||||
|
while IFS= read -r -d '' file; do
|
||||||
|
FILE_VERSION=$(grep -oP '^\s*\*?\s*VERSION:\s*\K[0-9]{2}\.[0-9]{2}\.[0-9]{2}' "$file" 2>/dev/null | head -1)
|
||||||
|
[ -z "$FILE_VERSION" ] && continue
|
||||||
|
CHECKED=$((CHECKED+1))
|
||||||
|
if [ "$FILE_VERSION" != "$README_VERSION" ]; then
|
||||||
|
echo " ⚠️ \`${file}\`: \`${FILE_VERSION}\` (expected \`${README_VERSION}\`)" >> $GITHUB_STEP_SUMMARY
|
||||||
|
DRIFT=$((DRIFT+1))
|
||||||
|
fi
|
||||||
|
done < <(find . -maxdepth 4 -type f \( -name "*.php" -o -name "*.md" -o -name "*.yml" \) ! -path "./.git/*" ! -path "./vendor/*" ! -path "./node_modules/*" -print0 2>/dev/null)
|
||||||
|
|
||||||
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
if [ "$DRIFT" -gt 0 ]; then
|
||||||
|
echo "⚠️ **${DRIFT}** file(s) out of ${CHECKED} have version drift" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "Run \`sync-version-on-merge\` workflow or update manually" >> $GITHUB_STEP_SUMMARY
|
||||||
|
else
|
||||||
|
echo "✅ All ${CHECKED} file(s) match README version \`${README_VERSION}\`" >> $GITHUB_STEP_SUMMARY
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── PROTECT CUSTOM WORKFLOWS ────────────────────────────────────────
|
||||||
|
- name: Ensure custom workflow directory exists
|
||||||
|
run: |
|
||||||
|
echo "## 🔧 Custom Workflows" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
|
if [ ! -d ".github/workflows/custom" ]; then
|
||||||
|
mkdir -p .github/workflows/custom
|
||||||
|
cat > .github/workflows/custom/README.md << 'CWEOF'
|
||||||
|
# Custom Workflows
|
||||||
|
|
||||||
|
Place repo-specific workflows here. Files in this directory are:
|
||||||
|
- **Never overwritten** by MokoStandards bulk sync
|
||||||
|
- **Never deleted** by the repository-cleanup workflow
|
||||||
|
- Safe for custom CI, notifications, or repo-specific automation
|
||||||
|
|
||||||
|
Synced workflows live in `.github/workflows/` (parent directory).
|
||||||
|
CWEOF
|
||||||
|
sed -i 's/^ //' .github/workflows/custom/README.md
|
||||||
|
git config --local user.email "github-actions[bot]@users.noreply.github.com"
|
||||||
|
git config --local user.name "github-actions[bot]"
|
||||||
|
git add .github/workflows/custom/
|
||||||
|
if ! git diff --cached --quiet; then
|
||||||
|
git commit -m "chore: create .github/workflows/custom/ for repo-specific workflows [skip ci]" \
|
||||||
|
--author="github-actions[bot] <github-actions[bot]@users.noreply.github.com>"
|
||||||
|
git push
|
||||||
|
echo "✅ Created \`.github/workflows/custom/\` directory" >> $GITHUB_STEP_SUMMARY
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
CUSTOM_COUNT=$(find .github/workflows/custom -name "*.yml" -o -name "*.yaml" 2>/dev/null | wc -l)
|
||||||
|
echo "✅ Custom workflow directory exists (${CUSTOM_COUNT} workflow(s))" >> $GITHUB_STEP_SUMMARY
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── DELETE CLOSED ISSUES ──────────────────────────────────────────────
|
||||||
|
- name: Delete old closed issues
|
||||||
|
if: steps.tasks.outputs.delete_closed_issues == 'true'
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GH_TOKEN || github.token }}
|
||||||
|
run: |
|
||||||
|
REPO="${{ github.repository }}"
|
||||||
|
CUTOFF=$(date -u -d '30 days ago' +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -v-30d +%Y-%m-%dT%H:%M:%SZ)
|
||||||
|
echo "## 🗑️ Closed Issue Cleanup" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "Deleting issues closed before: ${CUTOFF}" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
|
DELETED=0
|
||||||
|
gh api "repos/${REPO}/issues?state=closed&since=1970-01-01T00:00:00Z&per_page=100&sort=updated&direction=asc" \
|
||||||
|
--jq ".[] | select(.closed_at < \"${CUTOFF}\") | .number" 2>/dev/null | while read -r num; do
|
||||||
|
# Lock and close with "not_planned" to mark as cleaned up
|
||||||
|
gh api "repos/${REPO}/issues/${num}/lock" -X PUT -f lock_reason="resolved" --silent 2>/dev/null || true
|
||||||
|
echo " Locked issue #${num}" >> $GITHUB_STEP_SUMMARY
|
||||||
|
DELETED=$((DELETED+1))
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "$DELETED" -eq 0 ] 2>/dev/null; then
|
||||||
|
echo "✅ No old closed issues found" >> $GITHUB_STEP_SUMMARY
|
||||||
|
else
|
||||||
|
echo "✅ Locked ${DELETED} old closed issue(s)" >> $GITHUB_STEP_SUMMARY
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Summary
|
||||||
|
if: always()
|
||||||
|
run: |
|
||||||
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "---" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "*Run by @${{ github.actor }} — trigger: ${{ github.event_name }}*" >> $GITHUB_STEP_SUMMARY
|
||||||
+59
-60
@@ -2,14 +2,14 @@
|
|||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
# FILE INFORMATION
|
# FILE INFORMATION
|
||||||
# DEFGROUP: GitHub.Workflow
|
# DEFGROUP: GitHub.Workflow
|
||||||
# INGROUP: MokoStandards.Compliance
|
# INGROUP: MokoCLI.Compliance
|
||||||
# REPO: https://github.com/mokoconsulting-tech/MokoStandards
|
# REPO: https://github.com/mokoconsulting-tech/mokocli
|
||||||
# PATH: /.mokogitea/workflows/standards-compliance.yml
|
# PATH: /.mokogit/workflows/standards-compliance.yml
|
||||||
# VERSION: 04.06.00
|
# VERSION: 04.06.00
|
||||||
# BRIEF: MokoStandards compliance validation workflow
|
# BRIEF: MokoCLI compliance validation workflow
|
||||||
# NOTE: Validates repository structure, documentation, and coding standards
|
# NOTE: Validates repository structure, documentation, and coding standards
|
||||||
|
|
||||||
name: "MCP: Standards Compliance"
|
name: "Generic: Standards Compliance"
|
||||||
|
|
||||||
# ╔════════════════════════════════════════════════════════════════════════╗
|
# ╔════════════════════════════════════════════════════════════════════════╗
|
||||||
# ║ MOKOSTANDARDS COMPLIANCE WORKFLOW ║
|
# ║ MOKOSTANDARDS COMPLIANCE WORKFLOW ║
|
||||||
@@ -42,7 +42,7 @@ env:
|
|||||||
WORKFLOW_VERSION: "04.04.01"
|
WORKFLOW_VERSION: "04.04.01"
|
||||||
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
|
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
|
||||||
|
|
||||||
# MokoStandards Policy Compliance:
|
# MokoCLI Policy Compliance:
|
||||||
# - File formatting: Enforces organizational coding standards
|
# - File formatting: Enforces organizational coding standards
|
||||||
# - Reference: docs/policy/file-formatting.md
|
# - Reference: docs/policy/file-formatting.md
|
||||||
|
|
||||||
@@ -252,7 +252,7 @@ jobs:
|
|||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "### ❌ Validation Failed: LICENSE File Missing" >> $GITHUB_STEP_SUMMARY
|
echo "### ❌ Validation Failed: LICENSE File Missing" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "**Error:** LICENSE file is required for all MokoStandards-compliant repositories" >> $GITHUB_STEP_SUMMARY
|
echo "**Error:** LICENSE file is required for all MokoCLI-compliant repositories" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "**Action Required:** Add LICENSE file with appropriate open-source license (GPL-3.0-or-later recommended)" >> $GITHUB_STEP_SUMMARY
|
echo "**Action Required:** Add LICENSE file with appropriate open-source license (GPL-3.0-or-later recommended)" >> $GITHUB_STEP_SUMMARY
|
||||||
echo ""
|
echo ""
|
||||||
echo "❌ ERROR: LICENSE file not found - This is a critical requirement"
|
echo "❌ ERROR: LICENSE file not found - This is a critical requirement"
|
||||||
@@ -291,7 +291,7 @@ jobs:
|
|||||||
|
|
||||||
MISSING=0
|
MISSING=0
|
||||||
PRESENT=0
|
PRESENT=0
|
||||||
TOTAL=2
|
TOTAL=1
|
||||||
|
|
||||||
echo "### Required Directories" >> $GITHUB_STEP_SUMMARY
|
echo "### Required Directories" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
@@ -299,7 +299,7 @@ jobs:
|
|||||||
echo "|-----------|--------|-------|------|-------|" >> $GITHUB_STEP_SUMMARY
|
echo "|-----------|--------|-------|------|-------|" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
# Check required directories
|
# Check required directories
|
||||||
for dir in docs .github; do
|
for dir in .mokogit; do
|
||||||
if [ -d "$dir" ]; then
|
if [ -d "$dir" ]; then
|
||||||
FILE_COUNT=$(find "$dir" -type f 2>/dev/null | wc -l)
|
FILE_COUNT=$(find "$dir" -type f 2>/dev/null | wc -l)
|
||||||
DIR_SIZE=$(du -sh "$dir" 2>/dev/null | cut -f1)
|
DIR_SIZE=$(du -sh "$dir" 2>/dev/null | cut -f1)
|
||||||
@@ -320,14 +320,13 @@ jobs:
|
|||||||
echo "### 🔴 Critical Issues: $MISSING" >> $GITHUB_STEP_SUMMARY
|
echo "### 🔴 Critical Issues: $MISSING" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "**Remediation Steps:**" >> $GITHUB_STEP_SUMMARY
|
echo "**Remediation Steps:**" >> $GITHUB_STEP_SUMMARY
|
||||||
[ ! -d "docs" ] && echo "- Create docs directory: \`mkdir docs && echo '# Documentation' > docs/README.md\`" >> $GITHUB_STEP_SUMMARY
|
[ ! -d ".mokogit" ] && echo "- Create .mokogit directory: \`mkdir -p .mokogit/workflows\`" >> $GITHUB_STEP_SUMMARY
|
||||||
[ ! -d ".github" ] && echo "- Create .github directory: \`mkdir -p .github/workflows\`" >> $GITHUB_STEP_SUMMARY
|
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "📚 Reference: [MokoStandards Repository Structure](https://github.com/mokoconsulting-tech/MokoStandards/tree/main/docs/policy/core-structure.md)" >> $GITHUB_STEP_SUMMARY
|
echo "📚 Reference: [MokoCLI Repository Structure](https://github.com/mokoconsulting-tech/mokocli/tree/main/docs/policy/core-structure.md)" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "### ❌ Validation Failed: Required Directories Missing" >> $GITHUB_STEP_SUMMARY
|
echo "### ❌ Validation Failed: Required Directories Missing" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "**Status:** Repository structure does not meet MokoStandards requirements" >> $GITHUB_STEP_SUMMARY
|
echo "**Status:** Repository structure does not meet MokoCLI requirements" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "**Missing:** $MISSING required director(y|ies)" >> $GITHUB_STEP_SUMMARY
|
echo "**Missing:** $MISSING required director(y|ies)" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "**Compliance:** $PERCENT% ($PRESENT/$TOTAL directories present)" >> $GITHUB_STEP_SUMMARY
|
echo "**Compliance:** $PERCENT% ($PRESENT/$TOTAL directories present)" >> $GITHUB_STEP_SUMMARY
|
||||||
echo ""
|
echo ""
|
||||||
@@ -384,17 +383,17 @@ jobs:
|
|||||||
echo "### 🔴 Critical Issues: $MISSING" >> $GITHUB_STEP_SUMMARY
|
echo "### 🔴 Critical Issues: $MISSING" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "**Remediation Steps:**" >> $GITHUB_STEP_SUMMARY
|
echo "**Remediation Steps:**" >> $GITHUB_STEP_SUMMARY
|
||||||
[ ! -f "README.md" ] && echo "- Create README.md: Use [template](https://github.com/mokoconsulting-tech/MokoStandards/tree/main/templates/docs/required/README.md)" >> $GITHUB_STEP_SUMMARY
|
[ ! -f "README.md" ] && echo "- Create README.md: Use [template](https://github.com/mokoconsulting-tech/mokocli/tree/main/templates/docs/required/README.md)" >> $GITHUB_STEP_SUMMARY
|
||||||
[ ! -f "LICENSE" ] && echo "- Add LICENSE file: Choose from [OSI-approved licenses](https://opensource.org/licenses)" >> $GITHUB_STEP_SUMMARY
|
[ ! -f "LICENSE" ] && echo "- Add LICENSE file: Choose from [OSI-approved licenses](https://opensource.org/licenses)" >> $GITHUB_STEP_SUMMARY
|
||||||
[ ! -f "CONTRIBUTING.md" ] && echo "- Create CONTRIBUTING.md: Use [template](https://github.com/mokoconsulting-tech/MokoStandards/tree/main/templates/docs/required/CONTRIBUTING.md)" >> $GITHUB_STEP_SUMMARY
|
[ ! -f "CONTRIBUTING.md" ] && echo "- Create CONTRIBUTING.md: Use [template](https://github.com/mokoconsulting-tech/mokocli/tree/main/templates/docs/required/CONTRIBUTING.md)" >> $GITHUB_STEP_SUMMARY
|
||||||
[ ! -f "SECURITY.md" ] && echo "- Create SECURITY.md: Use [template](https://github.com/mokoconsulting-tech/MokoStandards/tree/main/templates/docs/required/SECURITY.md)" >> $GITHUB_STEP_SUMMARY
|
[ ! -f "SECURITY.md" ] && echo "- Create SECURITY.md: Use [template](https://github.com/mokoconsulting-tech/mokocli/tree/main/templates/docs/required/SECURITY.md)" >> $GITHUB_STEP_SUMMARY
|
||||||
[ ! -f ".editorconfig" ] && echo "- Add .editorconfig: Use [template](https://github.com/mokoconsulting-tech/MokoStandards/tree/main/templates/.editorconfig)" >> $GITHUB_STEP_SUMMARY
|
[ ! -f ".editorconfig" ] && echo "- Add .editorconfig: Use [template](https://github.com/mokoconsulting-tech/mokocli/tree/main/templates/.editorconfig)" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "📚 Reference: [MokoStandards File Requirements](https://github.com/mokoconsulting-tech/MokoStandards/tree/main/docs/policy/file-header-standards.md)" >> $GITHUB_STEP_SUMMARY
|
echo "📚 Reference: [MokoCLI File Requirements](https://github.com/mokoconsulting-tech/mokocli/tree/main/docs/policy/file-header-standards.md)" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "### ❌ Validation Failed: Required Files Missing" >> $GITHUB_STEP_SUMMARY
|
echo "### ❌ Validation Failed: Required Files Missing" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "**Status:** Repository files do not meet MokoStandards requirements" >> $GITHUB_STEP_SUMMARY
|
echo "**Status:** Repository files do not meet MokoCLI requirements" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "**Missing:** $MISSING required file(s)" >> $GITHUB_STEP_SUMMARY
|
echo "**Missing:** $MISSING required file(s)" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "**Compliance:** $PERCENT% ($PRESENT/$TOTAL files present)" >> $GITHUB_STEP_SUMMARY
|
echo "**Compliance:** $PERCENT% ($PRESENT/$TOTAL files present)" >> $GITHUB_STEP_SUMMARY
|
||||||
echo ""
|
echo ""
|
||||||
@@ -437,7 +436,7 @@ jobs:
|
|||||||
echo "$TABS_IN_SPACES_FILES" >> $GITHUB_STEP_SUMMARY
|
echo "$TABS_IN_SPACES_FILES" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "These languages require spaces (tabs will break): YAML, Python, Haskell, F#, CoffeeScript, Nim, JSON, RST" >> $GITHUB_STEP_SUMMARY
|
echo "These languages require spaces (tabs will break): YAML, Python, Haskell, F#, CoffeeScript, Nim, JSON, RST" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "All other files (including .md, .ps1, LICENSE, etc.) may use tabs per MokoStandards policy" >> $GITHUB_STEP_SUMMARY
|
echo "All other files (including .md, .ps1, LICENSE, etc.) may use tabs per MokoCLI policy" >> $GITHUB_STEP_SUMMARY
|
||||||
else
|
else
|
||||||
echo "✅ No tabs found in files requiring spaces" >> $GITHUB_STEP_SUMMARY
|
echo "✅ No tabs found in files requiring spaces" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "Note: Tabs are allowed in most files (policy default). Only checked files requiring spaces." >> $GITHUB_STEP_SUMMARY
|
echo "Note: Tabs are allowed in most files (policy default). Only checked files requiring spaces." >> $GITHUB_STEP_SUMMARY
|
||||||
@@ -454,7 +453,7 @@ jobs:
|
|||||||
! -path "./vendor/*" \
|
! -path "./vendor/*" \
|
||||||
! -path "./node_modules/*" \
|
! -path "./node_modules/*" \
|
||||||
! -path "./.git/*" \
|
! -path "./.git/*" \
|
||||||
-exec file {} \; | grep -v "UTF-8" | grep -v "ASCII" | head -5)
|
-exec file {} \; | grep -v "UTF-8" | grep -v "ASCII" | head -5 || true)
|
||||||
|
|
||||||
if [ -n "$NON_UTF8" ]; then
|
if [ -n "$NON_UTF8" ]; then
|
||||||
echo "⚠️ Non-UTF-8 files detected:" >> $GITHUB_STEP_SUMMARY
|
echo "⚠️ Non-UTF-8 files detected:" >> $GITHUB_STEP_SUMMARY
|
||||||
@@ -476,14 +475,14 @@ jobs:
|
|||||||
! -path "./vendor/*" \
|
! -path "./vendor/*" \
|
||||||
! -path "./node_modules/*" \
|
! -path "./node_modules/*" \
|
||||||
! -path "./.git/*" \
|
! -path "./.git/*" \
|
||||||
-exec file {} \; | grep "CRLF" | head -5)
|
-exec file {} \; | grep "CRLF" | head -5 || true)
|
||||||
|
|
||||||
if [ -n "$CRLF_FILES" ]; then
|
if [ -n "$CRLF_FILES" ]; then
|
||||||
echo "⚠️ Files with CRLF line endings found:" >> $GITHUB_STEP_SUMMARY
|
echo "⚠️ Files with CRLF line endings found:" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "$CRLF_FILES" >> $GITHUB_STEP_SUMMARY
|
echo "$CRLF_FILES" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "MokoStandards requires LF line endings" >> $GITHUB_STEP_SUMMARY
|
echo "MokoCLI requires LF line endings" >> $GITHUB_STEP_SUMMARY
|
||||||
else
|
else
|
||||||
echo "✅ Line endings are consistent (LF)" >> $GITHUB_STEP_SUMMARY
|
echo "✅ Line endings are consistent (LF)" >> $GITHUB_STEP_SUMMARY
|
||||||
fi
|
fi
|
||||||
@@ -504,13 +503,13 @@ jobs:
|
|||||||
tools: composer
|
tools: composer
|
||||||
coverage: none
|
coverage: none
|
||||||
|
|
||||||
- name: Setup MokoStandards tools
|
- name: Setup MokoCLI tools
|
||||||
env:
|
env:
|
||||||
GH_TOKEN: ${{ secrets.GH_TOKEN || github.token }}
|
GH_TOKEN: ${{ secrets.GH_TOKEN || github.token }}
|
||||||
COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GH_TOKEN || github.token }}"}}'
|
COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GH_TOKEN || github.token }}"}}'
|
||||||
run: |
|
run: |
|
||||||
git clone --depth 1 --branch version/04 --quiet \
|
git clone --depth 1 --branch version/04 --quiet \
|
||||||
"https://x-access-token:${GH_TOKEN}@github.com/mokoconsulting-tech/MokoStandards.git" \
|
"https://x-access-token:${GH_TOKEN}@github.com/mokoconsulting-tech/mokocli.git" \
|
||||||
/tmp/mokostandards 2>/dev/null || true
|
/tmp/mokostandards 2>/dev/null || true
|
||||||
if [ -d "/tmp/mokostandards" ] && [ -f "/tmp/mokostandards/composer.json" ]; then
|
if [ -d "/tmp/mokostandards" ] && [ -f "/tmp/mokostandards/composer.json" ]; then
|
||||||
cd /tmp/mokostandards
|
cd /tmp/mokostandards
|
||||||
@@ -524,7 +523,7 @@ jobs:
|
|||||||
echo "## 🔢 Version Consistency Validation" >> $GITHUB_STEP_SUMMARY
|
echo "## 🔢 Version Consistency Validation" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
# Use MokoStandards tools (no Composer needed on the governed repo)
|
# Use MokoCLI tools (no Composer needed on the governed repo)
|
||||||
if [ -f "/tmp/mokostandards/api/validate/check_version_consistency.php" ]; then
|
if [ -f "/tmp/mokostandards/api/validate/check_version_consistency.php" ]; then
|
||||||
php /tmp/mokostandards/api/validate/check_version_consistency.php --path . --verbose 2>&1 | tee /tmp/version-check.log
|
php /tmp/mokostandards/api/validate/check_version_consistency.php --path . --verbose 2>&1 | tee /tmp/version-check.log
|
||||||
EXIT_CODE=${PIPESTATUS[0]}
|
EXIT_CODE=${PIPESTATUS[0]}
|
||||||
@@ -532,7 +531,7 @@ jobs:
|
|||||||
php api/validate/check_version_consistency.php --path . --verbose 2>&1 | tee /tmp/version-check.log
|
php api/validate/check_version_consistency.php --path . --verbose 2>&1 | tee /tmp/version-check.log
|
||||||
EXIT_CODE=${PIPESTATUS[0]}
|
EXIT_CODE=${PIPESTATUS[0]}
|
||||||
else
|
else
|
||||||
echo "⏭️ MokoStandards tools not available — skipping version check" >> $GITHUB_STEP_SUMMARY
|
echo "⏭️ MokoCLI tools not available — skipping version check" >> $GITHUB_STEP_SUMMARY
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -564,17 +563,17 @@ jobs:
|
|||||||
set -x
|
set -x
|
||||||
echo "### GitHub Actions Workflows" >> $GITHUB_STEP_SUMMARY
|
echo "### GitHub Actions Workflows" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
WORKFLOWS_DIR=".github/workflows"
|
WORKFLOWS_DIR=".mokogit/workflows"
|
||||||
|
|
||||||
if [ ! -d "$WORKFLOWS_DIR" ]; then
|
if [ ! -d "$WORKFLOWS_DIR" ]; then
|
||||||
echo "❌ No workflows directory found" >> $GITHUB_STEP_SUMMARY
|
echo "❌ No workflows directory found" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "### ❌ Validation Failed: Workflows Directory Missing" >> $GITHUB_STEP_SUMMARY
|
echo "### ❌ Validation Failed: Workflows Directory Missing" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "**Error:** .github/workflows directory is required for CI/CD automation" >> $GITHUB_STEP_SUMMARY
|
echo "**Error:** .mokogit/workflows directory is required for CI/CD automation" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "**Action Required:** Create .github/workflows directory and add GitHub Actions workflows" >> $GITHUB_STEP_SUMMARY
|
echo "**Action Required:** Create .mokogit/workflows directory and add GitHub Actions workflows" >> $GITHUB_STEP_SUMMARY
|
||||||
echo ""
|
echo ""
|
||||||
echo "❌ ERROR: .github/workflows directory not found"
|
echo "❌ ERROR: .mokogit/workflows directory not found"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -597,12 +596,12 @@ jobs:
|
|||||||
echo "⚠️ CodeQL workflow not found" >> $GITHUB_STEP_SUMMARY
|
echo "⚠️ CodeQL workflow not found" >> $GITHUB_STEP_SUMMARY
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check for MokoStandards-synced workflows
|
# Check for MokoCLI-synced workflows
|
||||||
for wf in deploy-dev.yml deploy-demo.yml deploy-rs.yml sync-version-on-merge.yml auto-release.yml standards-compliance.yml enterprise-firewall-setup.yml; do
|
for wf in deploy-dev.yml deploy-demo.yml deploy-rs.yml sync-version-on-merge.yml auto-release.yml standards-compliance.yml enterprise-firewall-setup.yml; do
|
||||||
if [ -f "$WORKFLOWS_DIR/$wf" ]; then
|
if [ -f "$WORKFLOWS_DIR/$wf" ]; then
|
||||||
echo "✅ ${wf}" >> $GITHUB_STEP_SUMMARY
|
echo "✅ ${wf}" >> $GITHUB_STEP_SUMMARY
|
||||||
else
|
else
|
||||||
echo "⚠️ ${wf} not found (synced from MokoStandards)" >> $GITHUB_STEP_SUMMARY
|
echo "⚠️ ${wf} not found (synced from MokoCLI)" >> $GITHUB_STEP_SUMMARY
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
@@ -613,7 +612,7 @@ jobs:
|
|||||||
echo "### Workflow YAML Syntax" >> $GITHUB_STEP_SUMMARY
|
echo "### Workflow YAML Syntax" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
INVALID=0
|
INVALID=0
|
||||||
for workflow in $(find .github/workflows -maxdepth 1 -type f \( -name "*.yml" -o -name "*.yaml" \) 2>/dev/null); do
|
for workflow in $(find .mokogit/workflows -maxdepth 1 -type f \( -name "*.yml" -o -name "*.yaml" \) 2>/dev/null); do
|
||||||
if [ -f "$workflow" ]; then
|
if [ -f "$workflow" ]; then
|
||||||
if python3 -c "import yaml, sys; yaml.safe_load(open(sys.argv[1]))" "$workflow" 2>/dev/null; then
|
if python3 -c "import yaml, sys; yaml.safe_load(open(sys.argv[1]))" "$workflow" 2>/dev/null; then
|
||||||
echo "✅ $(basename $workflow)" >> $GITHUB_STEP_SUMMARY
|
echo "✅ $(basename $workflow)" >> $GITHUB_STEP_SUMMARY
|
||||||
@@ -630,7 +629,7 @@ jobs:
|
|||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "**Error:** $INVALID workflow file(s) have invalid YAML syntax" >> $GITHUB_STEP_SUMMARY
|
echo "**Error:** $INVALID workflow file(s) have invalid YAML syntax" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "**Action Required:** Fix YAML syntax errors in the marked workflow files" >> $GITHUB_STEP_SUMMARY
|
echo "**Action Required:** Fix YAML syntax errors in the marked workflow files" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "**Tool:** Run \`python3 -c \"import yaml; yaml.safe_load(open('.github/workflows/FILE.yml'))\"\` locally" >> $GITHUB_STEP_SUMMARY
|
echo "**Tool:** Run \`python3 -c \"import yaml; yaml.safe_load(open('.mokogit/workflows/FILE.yml'))\"\` locally" >> $GITHUB_STEP_SUMMARY
|
||||||
echo ""
|
echo ""
|
||||||
echo "❌ ERROR: $INVALID workflow file(s) with invalid YAML syntax"
|
echo "❌ ERROR: $INVALID workflow file(s) with invalid YAML syntax"
|
||||||
exit 1
|
exit 1
|
||||||
@@ -642,7 +641,7 @@ jobs:
|
|||||||
echo "✅ SUCCESS: All workflow files passed YAML validation"
|
echo "✅ SUCCESS: All workflow files passed YAML validation"
|
||||||
|
|
||||||
- name: Validate CodeQL Configuration
|
- name: Validate CodeQL Configuration
|
||||||
if: hashFiles('.github/workflows/codeql-analysis.yml') != ''
|
if: hashFiles('.mokogit/workflows/codeql-analysis.yml') != ''
|
||||||
run: |
|
run: |
|
||||||
set -e
|
set -e
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
@@ -650,7 +649,7 @@ jobs:
|
|||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
# Inline validation (rewritten from Python to bash for PHP-only architecture)
|
# Inline validation (rewritten from Python to bash for PHP-only architecture)
|
||||||
CODEQL_FILE=".github/workflows/codeql-analysis.yml"
|
CODEQL_FILE=".mokogit/workflows/codeql-analysis.yml"
|
||||||
|
|
||||||
if [ ! -f "$CODEQL_FILE" ]; then
|
if [ ! -f "$CODEQL_FILE" ]; then
|
||||||
echo "⚠️ CodeQL workflow file not found" >> $GITHUB_STEP_SUMMARY
|
echo "⚠️ CodeQL workflow file not found" >> $GITHUB_STEP_SUMMARY
|
||||||
@@ -809,7 +808,7 @@ jobs:
|
|||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "### ❌ Validation Failed: README.md Missing" >> $GITHUB_STEP_SUMMARY
|
echo "### ❌ Validation Failed: README.md Missing" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "**Error:** README.md is required for all MokoStandards-compliant repositories" >> $GITHUB_STEP_SUMMARY
|
echo "**Error:** README.md is required for all MokoCLI-compliant repositories" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "**Action Required:** Create README.md with project description, setup instructions, and usage examples" >> $GITHUB_STEP_SUMMARY
|
echo "**Action Required:** Create README.md with project description, setup instructions, and usage examples" >> $GITHUB_STEP_SUMMARY
|
||||||
echo ""
|
echo ""
|
||||||
echo "❌ ERROR: README.md not found - This is a critical requirement"
|
echo "❌ ERROR: README.md not found - This is a critical requirement"
|
||||||
@@ -915,7 +914,7 @@ jobs:
|
|||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "### ❌ Validation Failed: CHANGELOG.md Missing" >> $GITHUB_STEP_SUMMARY
|
echo "### ❌ Validation Failed: CHANGELOG.md Missing" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "**Error:** CHANGELOG.md is required for all MokoStandards-compliant repositories" >> $GITHUB_STEP_SUMMARY
|
echo "**Error:** CHANGELOG.md is required for all MokoCLI-compliant repositories" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "**Action Required:** Create CHANGELOG.md following [Keep a Changelog](https://keepachangelog.com/) format" >> $GITHUB_STEP_SUMMARY
|
echo "**Action Required:** Create CHANGELOG.md following [Keep a Changelog](https://keepachangelog.com/) format" >> $GITHUB_STEP_SUMMARY
|
||||||
echo ""
|
echo ""
|
||||||
echo "❌ ERROR: CHANGELOG.md not found - This is a critical requirement"
|
echo "❌ ERROR: CHANGELOG.md not found - This is a critical requirement"
|
||||||
@@ -1183,11 +1182,11 @@ jobs:
|
|||||||
# Install yamllint if not present
|
# Install yamllint if not present
|
||||||
:
|
:
|
||||||
else
|
else
|
||||||
pip install yamllint >/dev/null 2>&1
|
pip install yamllint >/dev/null 2>&1 || true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Run yamllint and count line-length warnings
|
# Run yamllint and count line-length warnings
|
||||||
YAML_OUTPUT=$(yamllint .github/workflows/*.yml 2>&1 | grep "line too long" || true)
|
YAML_OUTPUT=$(yamllint .mokogit/workflows/*.yml 2>&1 | grep "line too long" || true)
|
||||||
if [ -n "$YAML_OUTPUT" ]; then
|
if [ -n "$YAML_OUTPUT" ]; then
|
||||||
YAML_VIOLATIONS=$(echo "$YAML_OUTPUT" | wc -l)
|
YAML_VIOLATIONS=$(echo "$YAML_OUTPUT" | wc -l)
|
||||||
echo "⚠️ Found $YAML_VIOLATIONS lines exceeding 180 characters in YAML files" >> $GITHUB_STEP_SUMMARY
|
echo "⚠️ Found $YAML_VIOLATIONS lines exceeding 180 characters in YAML files" >> $GITHUB_STEP_SUMMARY
|
||||||
@@ -1214,7 +1213,7 @@ jobs:
|
|||||||
! -path "./.git/*" \
|
! -path "./.git/*" \
|
||||||
! -path "./build/*" \
|
! -path "./build/*" \
|
||||||
! -path "./dist/*" \
|
! -path "./dist/*" \
|
||||||
-exec awk 'length > 120 { print FILENAME ":" NR ": " length " chars" }' {} \; 2>/dev/null | head -20)
|
-exec awk 'length > 120 { print FILENAME ":" NR ": " length " chars" }' {} \; 2>/dev/null | head -20 || true)
|
||||||
|
|
||||||
if [ -n "$LONG_LINES" ]; then
|
if [ -n "$LONG_LINES" ]; then
|
||||||
LINE_COUNT=$(echo "$LONG_LINES" | wc -l)
|
LINE_COUNT=$(echo "$LONG_LINES" | wc -l)
|
||||||
@@ -1976,10 +1975,10 @@ jobs:
|
|||||||
if [ -f "composer.json" ]; then
|
if [ -f "composer.json" ]; then
|
||||||
composer install --no-dev --no-interaction --prefer-dist --optimize-autoloader
|
composer install --no-dev --no-interaction --prefer-dist --optimize-autoloader
|
||||||
else
|
else
|
||||||
echo "No composer.json — pulling MokoStandards tools"
|
echo "No composer.json — pulling MokoCLI tools"
|
||||||
if [ ! -d "/tmp/mokostandards" ]; then
|
if [ ! -d "/tmp/mokostandards" ]; then
|
||||||
git clone --depth 1 --branch version/04 --quiet \
|
git clone --depth 1 --branch version/04 --quiet \
|
||||||
"https://x-access-token:${GH_TOKEN}@github.com/mokoconsulting-tech/MokoStandards.git" \
|
"https://x-access-token:${GH_TOKEN}@github.com/mokoconsulting-tech/mokocli.git" \
|
||||||
/tmp/mokostandards 2>/dev/null || true
|
/tmp/mokostandards 2>/dev/null || true
|
||||||
if [ -f "/tmp/mokostandards/composer.json" ]; then
|
if [ -f "/tmp/mokostandards/composer.json" ]; then
|
||||||
cd /tmp/mokostandards && composer install --no-dev --no-interaction --quiet 2>/dev/null || true
|
cd /tmp/mokostandards && composer install --no-dev --no-interaction --quiet 2>/dev/null || true
|
||||||
@@ -2048,10 +2047,10 @@ jobs:
|
|||||||
if [ -f "composer.json" ]; then
|
if [ -f "composer.json" ]; then
|
||||||
composer install --no-dev --no-interaction --prefer-dist --optimize-autoloader
|
composer install --no-dev --no-interaction --prefer-dist --optimize-autoloader
|
||||||
else
|
else
|
||||||
echo "No composer.json — pulling MokoStandards tools"
|
echo "No composer.json — pulling MokoCLI tools"
|
||||||
if [ ! -d "/tmp/mokostandards" ]; then
|
if [ ! -d "/tmp/mokostandards" ]; then
|
||||||
git clone --depth 1 --branch version/04 --quiet \
|
git clone --depth 1 --branch version/04 --quiet \
|
||||||
"https://x-access-token:${GH_TOKEN}@github.com/mokoconsulting-tech/MokoStandards.git" \
|
"https://x-access-token:${GH_TOKEN}@github.com/mokoconsulting-tech/mokocli.git" \
|
||||||
/tmp/mokostandards 2>/dev/null || true
|
/tmp/mokostandards 2>/dev/null || true
|
||||||
if [ -f "/tmp/mokostandards/composer.json" ]; then
|
if [ -f "/tmp/mokostandards/composer.json" ]; then
|
||||||
cd /tmp/mokostandards && composer install --no-dev --no-interaction --quiet 2>/dev/null || true
|
cd /tmp/mokostandards && composer install --no-dev --no-interaction --quiet 2>/dev/null || true
|
||||||
@@ -2131,17 +2130,17 @@ jobs:
|
|||||||
WARNINGS=0
|
WARNINGS=0
|
||||||
ERRORS=0
|
ERRORS=0
|
||||||
|
|
||||||
# 1. Check .github/config.tf location (not root override files)
|
# 1. Check .mokogit/config.tf location (not root override files)
|
||||||
echo "### Override Configuration Check" >> $GITHUB_STEP_SUMMARY
|
echo "### Override Configuration Check" >> $GITHUB_STEP_SUMMARY
|
||||||
LEGACY_OVERRIDES=$(find . -maxdepth 1 -name "*override*.tf" -o -name "MokoStandards.override.tf" 2>/dev/null | wc -l || echo 0)
|
LEGACY_OVERRIDES=$(find . -maxdepth 1 -name "*override*.tf" -o -name "MokoCLI.override.tf" 2>/dev/null | wc -l || echo 0)
|
||||||
if [ "$LEGACY_OVERRIDES" -gt 0 ]; then
|
if [ "$LEGACY_OVERRIDES" -gt 0 ]; then
|
||||||
echo "⚠️ Found legacy override files in root directory" >> $GITHUB_STEP_SUMMARY
|
echo "⚠️ Found legacy override files in root directory" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "**Expected Location**: .github/config.tf" >> $GITHUB_STEP_SUMMARY
|
echo "**Expected Location**: .mokogit/config.tf" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "**Legacy files found**: $LEGACY_OVERRIDES" >> $GITHUB_STEP_SUMMARY
|
echo "**Legacy files found**: $LEGACY_OVERRIDES" >> $GITHUB_STEP_SUMMARY
|
||||||
WARNINGS=$((WARNINGS + 1))
|
WARNINGS=$((WARNINGS + 1))
|
||||||
else
|
else
|
||||||
if [ -f ".github/config.tf" ]; then
|
if [ -f ".mokogit/config.tf" ]; then
|
||||||
echo "✅ Override configuration in correct location (.github/config.tf)" >> $GITHUB_STEP_SUMMARY
|
echo "✅ Override configuration in correct location (.mokogit/config.tf)" >> $GITHUB_STEP_SUMMARY
|
||||||
else
|
else
|
||||||
echo "ℹ️ No override configuration found" >> $GITHUB_STEP_SUMMARY
|
echo "ℹ️ No override configuration found" >> $GITHUB_STEP_SUMMARY
|
||||||
fi
|
fi
|
||||||
@@ -2299,7 +2298,7 @@ jobs:
|
|||||||
- name: Generate Compliance Report
|
- name: Generate Compliance Report
|
||||||
run: |
|
run: |
|
||||||
set -x
|
set -x
|
||||||
echo "# 📊 MokoStandards Compliance Report" >> $GITHUB_STEP_SUMMARY
|
echo "# 📊 MokoCLI Compliance Report" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
# Calculate overall status
|
# Calculate overall status
|
||||||
@@ -2486,7 +2485,7 @@ jobs:
|
|||||||
else
|
else
|
||||||
echo "## 🎉 Excellent!" >> $GITHUB_STEP_SUMMARY
|
echo "## 🎉 Excellent!" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "Your repository is **fully compliant** with MokoStandards!" >> $GITHUB_STEP_SUMMARY
|
echo "Your repository is **fully compliant** with MokoCLI!" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "**Achievements:**" >> $GITHUB_STEP_SUMMARY
|
echo "**Achievements:**" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "- ✅ All required directories and files present" >> $GITHUB_STEP_SUMMARY
|
echo "- ✅ All required directories and files present" >> $GITHUB_STEP_SUMMARY
|
||||||
@@ -2501,12 +2500,12 @@ jobs:
|
|||||||
echo "---" >> $GITHUB_STEP_SUMMARY
|
echo "---" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "📚 **Resources:**" >> $GITHUB_STEP_SUMMARY
|
echo "📚 **Resources:**" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "- [MokoStandards Documentation](https://github.com/mokoconsulting-tech/MokoStandards)" >> $GITHUB_STEP_SUMMARY
|
echo "- [MokoCLI Documentation](https://github.com/mokoconsulting-tech/mokocli)" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "- [Repository Structure Guide](https://github.com/mokoconsulting-tech/MokoStandards/tree/main/docs/policy/core-structure.md)" >> $GITHUB_STEP_SUMMARY
|
echo "- [Repository Structure Guide](https://github.com/mokoconsulting-tech/mokocli/tree/main/docs/policy/core-structure.md)" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "- [Documentation Standards](https://github.com/mokoconsulting-tech/MokoStandards/tree/main/docs/policy/document-formatting.md)" >> $GITHUB_STEP_SUMMARY
|
echo "- [Documentation Standards](https://github.com/mokoconsulting-tech/mokocli/tree/main/docs/policy/document-formatting.md)" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "- [Coding Standards](https://github.com/mokoconsulting-tech/MokoStandards/tree/main/docs/policy/coding-style-guide.md)" >> $GITHUB_STEP_SUMMARY
|
echo "- [Coding Standards](https://github.com/mokoconsulting-tech/mokocli/tree/main/docs/policy/coding-style-guide.md)" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "_Generated by MokoStandards Compliance Workflow v${WORKFLOW_VERSION}_" >> $GITHUB_STEP_SUMMARY
|
echo "_Generated by MokoCLI Compliance Workflow v${WORKFLOW_VERSION}_" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
# Create tracking issue for non-compliance if on push
|
# Create tracking issue for non-compliance if on push
|
||||||
if [ "$COMPLIANCE_PERCENT" -lt 100 ] && [ "${{ github.event_name }}" = "push" ]; then
|
if [ "$COMPLIANCE_PERCENT" -lt 100 ] && [ "${{ github.event_name }}" = "push" ]; then
|
||||||
@@ -2530,9 +2529,9 @@ jobs:
|
|||||||
echo "### ✅ Full Standards Compliance Achieved" >> $GITHUB_STEP_SUMMARY
|
echo "### ✅ Full Standards Compliance Achieved" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "**Overall Compliance:** 100%" >> $GITHUB_STEP_SUMMARY
|
echo "**Overall Compliance:** 100%" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "**Status:** Repository meets all MokoStandards requirements" >> $GITHUB_STEP_SUMMARY
|
echo "**Status:** Repository meets all MokoCLI requirements" >> $GITHUB_STEP_SUMMARY
|
||||||
echo ""
|
echo ""
|
||||||
echo "✅ SUCCESS: Repository is fully MokoStandards compliant"
|
echo "✅ SUCCESS: Repository is fully MokoCLI compliant"
|
||||||
|
|
||||||
- name: Create or reopen tracking issue for standards violations
|
- name: Create or reopen tracking issue for standards violations
|
||||||
if: failure()
|
if: failure()
|
||||||
+14
-18
@@ -11,7 +11,7 @@
|
|||||||
# PATH: /templates/workflows/shared/sync-version-on-merge.yml.template
|
# PATH: /templates/workflows/shared/sync-version-on-merge.yml.template
|
||||||
# VERSION: 04.06.00
|
# VERSION: 04.06.00
|
||||||
# BRIEF: Auto-bump patch version on every push to main and propagate to all file headers
|
# BRIEF: Auto-bump patch version on every push to main and propagate to all file headers
|
||||||
# NOTE: Synced via bulk-repo-sync to .mokogitea/workflows/sync-version-on-merge.yml in all governed repos.
|
# NOTE: Synced via bulk-repo-sync to .mokogit/workflows/sync-version-on-merge.yml in all governed repos.
|
||||||
# README.md is the single source of truth for the repository version.
|
# README.md is the single source of truth for the repository version.
|
||||||
|
|
||||||
name: "Universal: Sync Version on Merge"
|
name: "Universal: Sync Version on Merge"
|
||||||
@@ -39,31 +39,27 @@ jobs:
|
|||||||
sync-version:
|
sync-version:
|
||||||
name: Propagate README version
|
name: Propagate README version
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: ${{ !startsWith(github.event.repository.name, 'Template-') }}
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.GH_MIRROR_TOKEN || github.token }}
|
token: ${{ secrets.GH_TOKEN || github.token }}
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Set up PHP
|
|
||||||
uses: shivammathur/setup-php@fcafdd6392932010c2bd5094439b8e33be2a8a09 # v2.37.0
|
|
||||||
with:
|
|
||||||
php-version: '8.1'
|
|
||||||
tools: composer
|
|
||||||
|
|
||||||
- name: Setup MokoStandards tools
|
- name: Setup MokoStandards tools
|
||||||
env:
|
|
||||||
GH_TOKEN: ${{ secrets.GH_MIRROR_TOKEN || github.token }}
|
|
||||||
COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GH_MIRROR_TOKEN || github.token }}"}}'
|
|
||||||
run: |
|
run: |
|
||||||
git clone --depth 1 --branch version/04 --quiet \
|
# Use pre-installed mokoplatform on runner host (symlink /opt/mokoplatform -> /opt/moko-platform)
|
||||||
"https://x-access-token:${GH_TOKEN}@github.com/mokoconsulting-tech/MokoStandards.git" \
|
if [ -d /opt/mokoplatform/api/cli ] && [ -f /opt/mokoplatform/vendor/autoload.php ]; then
|
||||||
/tmp/mokostandards
|
ln -sf /opt/mokoplatform /tmp/mokostandards
|
||||||
cd /tmp/mokostandards
|
echo "Using pre-installed /opt/mokoplatform"
|
||||||
composer install --no-dev --no-interaction --quiet
|
elif [ -d /opt/moko-platform/api/cli ]; then
|
||||||
|
ln -sf /opt/moko-platform /tmp/mokostandards
|
||||||
|
echo "Using pre-installed /opt/moko-platform"
|
||||||
|
else
|
||||||
|
echo "::warning::MokoStandards tools not found on runner - skipping"
|
||||||
|
echo "MOKO_SKIP=true" >> "$GITHUB_ENV"
|
||||||
|
fi
|
||||||
|
|
||||||
- name: Auto-bump patch version
|
- name: Auto-bump patch version
|
||||||
if: ${{ github.event_name == 'push' && github.actor != 'github-actions[bot]' }}
|
if: ${{ github.event_name == 'push' && github.actor != 'github-actions[bot]' }}
|
||||||
@@ -107,7 +103,7 @@ jobs:
|
|||||||
--create-issue \
|
--create-issue \
|
||||||
--repo "${{ github.repository }}"
|
--repo "${{ github.repository }}"
|
||||||
env:
|
env:
|
||||||
GH_TOKEN: ${{ secrets.GH_MIRROR_TOKEN || github.token }}
|
GH_TOKEN: ${{ secrets.GH_TOKEN || github.token }}
|
||||||
|
|
||||||
- name: Commit updated files
|
- name: Commit updated files
|
||||||
if: ${{ steps.readme_version.outputs.skip != 'true' && inputs.dry_run != true }}
|
if: ${{ steps.readme_version.outputs.skip != 'true' && inputs.dry_run != true }}
|
||||||
@@ -3,10 +3,10 @@
|
|||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
#
|
#
|
||||||
# FILE INFORMATION
|
# FILE INFORMATION
|
||||||
# DEFGROUP: Gitea.Workflow.Template
|
# DEFGROUP: MokoGIT.Workflow.Template
|
||||||
# INGROUP: MokoStandards.CI
|
# INGROUP: MokoCLI.CI
|
||||||
# REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Joomla
|
# REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Joomla
|
||||||
# PATH: /.mokogitea/workflows/version-set.yml
|
# PATH: /.mokogit/workflows/version-set.yml
|
||||||
# VERSION: 01.00.00
|
# VERSION: 01.00.00
|
||||||
# BRIEF: Set or reset the extension version across all version-bearing files
|
# BRIEF: Set or reset the extension version across all version-bearing files
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ jobs:
|
|||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.MOKOGITEA_TOKEN || github.token }}
|
token: ${{ secrets.MOKOGIT_TOKEN || github.token }}
|
||||||
ref: ${{ inputs.branch || github.ref }}
|
ref: ${{ inputs.branch || github.ref }}
|
||||||
fetch-depth: 1
|
fetch-depth: 1
|
||||||
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
# Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
#
|
|
||||||
# FILE INFORMATION
|
|
||||||
# DEFGROUP: Gitea.Workflow
|
|
||||||
# INGROUP: MokoStandards.Universal
|
|
||||||
# REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoCLI
|
|
||||||
# PATH: /.mokogitea/workflows/branch-cleanup.yml
|
|
||||||
# VERSION: 01.00.00
|
|
||||||
# BRIEF: Delete feature branches after PR merge
|
|
||||||
|
|
||||||
name: "Branch Cleanup"
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
types: [closed]
|
|
||||||
|
|
||||||
env:
|
|
||||||
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
cleanup:
|
|
||||||
name: Delete merged branch
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
if: >-
|
|
||||||
github.event.pull_request.merged == true &&
|
|
||||||
github.event.pull_request.head.ref != 'dev' &&
|
|
||||||
github.event.pull_request.head.ref != 'main'
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Delete source branch
|
|
||||||
run: |
|
|
||||||
BRANCH="${{ github.event.pull_request.head.ref }}"
|
|
||||||
API="${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}/api/v1/repos/${{ github.repository }}/branches"
|
|
||||||
ENCODED=$(php -r "echo rawurlencode('${BRANCH}');")
|
|
||||||
|
|
||||||
STATUS=$(curl -sf -o /dev/null -w "%{http_code}" -X DELETE \
|
|
||||||
-H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \
|
|
||||||
"${API}/${ENCODED}" 2>/dev/null || true)
|
|
||||||
|
|
||||||
if [ "$STATUS" = "204" ]; then
|
|
||||||
echo "Deleted branch: ${BRANCH}" >> $GITHUB_STEP_SUMMARY
|
|
||||||
elif [ "$STATUS" = "404" ]; then
|
|
||||||
echo "Branch already deleted: ${BRANCH}" >> $GITHUB_STEP_SUMMARY
|
|
||||||
else
|
|
||||||
echo "::warning::Failed to delete branch ${BRANCH} (HTTP ${STATUS})"
|
|
||||||
fi
|
|
||||||
+8
-2
@@ -3,8 +3,14 @@
|
|||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- Migrated all workflow and template paths from `.github/` to `.mokogitea/`
|
- Branding: Git -> MokoGIT in workflow DEFGROUP tags, committer identity (git-actions[bot] -> mokogit-actions[bot]), and platform prose. Functional tokens (GIT_TOKEN/GITHUB_TOKEN, GIT_ACTIONS_*, vars.GITEA_*, git.mokoconsulting.tech) preserved.
|
||||||
- Template source paths updated: `templates/gitea/` to `templates/mokogitea/`
|
|
||||||
|
### Removed
|
||||||
|
- CI: stripped GitHub-only workflows (DEFGROUP GitHub.Workflow), which do not run on MokoGIT Actions: auto-dev-issue.yml changelog-validation.yml standards-compliance.yml sync-version-on-merge.yml.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Migrated all workflow and template paths from `.github/` to `.mokogit/`
|
||||||
|
- Template source paths updated: `templates/git/` to `templates/mokogit/`
|
||||||
- HCL definition files removed -- Template repos are now the canonical source
|
- HCL definition files removed -- Template repos are now the canonical source
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ This file provides guidance to Claude Code when working with this repository.
|
|||||||
|
|
||||||
## Project Overview
|
## Project Overview
|
||||||
|
|
||||||
**Template-MCP** -- Template repository for creating MokoStandards-compliant MCP API servers
|
**Template-NPM** -- Template repository for creating MokoCLI-compliant MCP API servers
|
||||||
|
|
||||||
| Field | Value |
|
| Field | Value |
|
||||||
|---|---|
|
|---|---|
|
||||||
@@ -12,8 +12,8 @@ This file provides guidance to Claude Code when working with this repository.
|
|||||||
| **Language** | TypeScript |
|
| **Language** | TypeScript |
|
||||||
| **Default branch** | main |
|
| **Default branch** | main |
|
||||||
| **License** | GPL-3.0-or-later |
|
| **License** | GPL-3.0-or-later |
|
||||||
| **Wiki** | [Template-MCP Wiki](https://git.mokoconsulting.tech/MokoConsulting/Template-MCP/wiki) |
|
| **Wiki** | [Template-NPM Wiki](https://git.mokoconsulting.tech/MokoConsulting/Template-NPM/wiki) |
|
||||||
| **Standards** | [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/MokoCLI/wiki/Home) |
|
| **Standards** | [MokoCLI](https://git.mokoconsulting.tech/MokoConsulting/mokocli/wiki/Home) |
|
||||||
|
|
||||||
## Common Commands
|
## Common Commands
|
||||||
|
|
||||||
@@ -42,11 +42,11 @@ This is an MCP (Model Context Protocol) server. Key files:
|
|||||||
|
|
||||||
## Rules
|
## Rules
|
||||||
|
|
||||||
- **Workflow directory**: `.mokogitea/` (not `.gitea/` or `.github/`)
|
- **Workflow directory**: `.mokogit/` (not `.gitea/` or `.github/`)
|
||||||
|
|
||||||
- **Never commit** `.claude/`, `.mcp.json`, `TODO.md`, or `*.min.css`/`*.min.js`
|
- **Never commit** `.claude/`, `.mcp.json`, `TODO.md`, or `*.min.css`/`*.min.js`
|
||||||
- **Attribution**: use `Authored-by: Moko Consulting` in commits
|
- **Attribution**: use `Authored-by: Moko Consulting` in commits
|
||||||
- **Branch strategy**: develop on `dev`, merge to `main` for release
|
- **Branch strategy**: develop on `dev`, merge to `main` for release
|
||||||
- **Minification**: handled at build time (CI) and runtime (MokoMinifyHelper for Joomla templates)
|
- **Minification**: handled at build time (CI) and runtime (MokoMinifyHelper for Joomla templates)
|
||||||
- **Wiki**: documentation lives in the Gitea wiki, not in `docs/` files
|
- **Wiki**: documentation lives in the MokoGIT wiki, not in `docs/` files
|
||||||
- **Standards**: this repo follows [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/MokoCLI/wiki/Home)
|
- **Standards**: this repo follows [MokoCLI](https://git.mokoconsulting.tech/MokoConsulting/mokocli/wiki/Home)
|
||||||
|
|||||||
+1
-1
@@ -13,7 +13,7 @@
|
|||||||
# FILE INFORMATION
|
# FILE INFORMATION
|
||||||
DEFGROUP:
|
DEFGROUP:
|
||||||
INGROUP: Project.Documentation
|
INGROUP: Project.Documentation
|
||||||
REPO: MokoConsulting/Template-MCP
|
REPO: MokoConsulting/Template-NPM
|
||||||
VERSION: 00.00.01
|
VERSION: 00.00.01
|
||||||
PATH: ./CODE_OF_CONDUCT.md
|
PATH: ./CODE_OF_CONDUCT.md
|
||||||
BRIEF: Contributor Covenant Code of Conduct version 1.3.0
|
BRIEF: Contributor Covenant Code of Conduct version 1.3.0
|
||||||
|
|||||||
+5
-5
@@ -13,13 +13,13 @@
|
|||||||
# FILE INFORMATION
|
# FILE INFORMATION
|
||||||
DEFGROUP:
|
DEFGROUP:
|
||||||
INGROUP: Project.Documentation
|
INGROUP: Project.Documentation
|
||||||
REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-MCP
|
REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-NPM
|
||||||
VERSION: 00.00.01
|
VERSION: 00.00.01
|
||||||
PATH: ./CONTRIBUTING.md
|
PATH: ./CONTRIBUTING.md
|
||||||
BRIEF: Contribution guidelines for the project
|
BRIEF: Contribution guidelines for the project
|
||||||
-->
|
-->
|
||||||
|
|
||||||
# Contributing to Template-MCP
|
# Contributing to Template-NPM
|
||||||
|
|
||||||
We appreciate your interest in contributing to this project! This document provides guidelines for contributing.
|
We appreciate your interest in contributing to this project! This document provides guidelines for contributing.
|
||||||
|
|
||||||
@@ -148,13 +148,13 @@ Every repo maintains 5 standard release channel tags:
|
|||||||
|
|
||||||
### CI/CD
|
### CI/CD
|
||||||
|
|
||||||
- Gitea Actions runs all CI workflows
|
- MokoGIT Actions runs all CI workflows
|
||||||
- GitHub Actions are disabled on mirrored repos
|
- GitHub Actions are disabled on mirrored repos
|
||||||
- Workflows live in both `.github/workflows/` and `.gitea/workflows/`
|
- Workflows live in both `.github/workflows/` and `.mokogit/workflows/`
|
||||||
|
|
||||||
### Update Servers (Joomla)
|
### Update Servers (Joomla)
|
||||||
|
|
||||||
In manifest `<updateservers>`, Gitea must be priority 1, GitHub priority 2.
|
In manifest `<updateservers>`, MokoGIT must be priority 1, GitHub priority 2.
|
||||||
|
|
||||||
### Secrets
|
### Secrets
|
||||||
|
|
||||||
|
|||||||
@@ -11,9 +11,9 @@
|
|||||||
You should have received a copy of the GNU General Public License (./LICENSE).
|
You should have received a copy of the GNU General Public License (./LICENSE).
|
||||||
|
|
||||||
# FILE INFORMATION
|
# FILE INFORMATION
|
||||||
DEFGROUP: MokoStandards
|
DEFGROUP: MokoCLI
|
||||||
INGROUP: MokoStandards.Documentation
|
INGROUP: MokoCLI.Documentation
|
||||||
REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoStandards/
|
REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli/
|
||||||
VERSION: 05.00.00
|
VERSION: 05.00.00
|
||||||
PATH: ./LICENSE
|
PATH: ./LICENSE
|
||||||
BRIEF: Project license (GPL-3.0-or-later)
|
BRIEF: Project license (GPL-3.0-or-later)
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
# Template-MCP
|
# Template-NPM
|
||||||
|
|
||||||
   
|
   
|
||||||
|
|
||||||
Template repository for creating MokoStandards-compliant Model Context Protocol (MCP) API servers. Provides the scaffolding, configuration patterns, and architecture conventions used by all Moko Consulting MCP servers, enabling AI assistants like Claude to interact with REST APIs through a standardized tool interface.
|
Template repository for creating MokoCLI-compliant Model Context Protocol (MCP) API servers. Provides the scaffolding, configuration patterns, and architecture conventions used by all Moko Consulting MCP servers, enabling AI assistants like Claude to interact with REST APIs through a standardized tool interface.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@ Template repository for creating MokoStandards-compliant Model Context Protocol
|
|||||||
- **REST API bridge architecture** -- standardized pattern for bridging any REST API as MCP tools, with typed request/response handling
|
- **REST API bridge architecture** -- standardized pattern for bridging any REST API as MCP tools, with typed request/response handling
|
||||||
- **TypeScript-first** -- full TypeScript setup with `tsconfig.json`, strict mode, and ES module output
|
- **TypeScript-first** -- full TypeScript setup with `tsconfig.json`, strict mode, and ES module output
|
||||||
- **Build tooling** -- Makefile with `build`, `dev`, `clean`, and `lint` targets; npm scripts for compilation and development
|
- **Build tooling** -- Makefile with `build`, `dev`, `clean`, and `lint` targets; npm scripts for compilation and development
|
||||||
- **MokoStandards compliant** -- follows all Moko Consulting governance conventions: file headers, commit messages, `.gitattributes`, `.gitmessage`, PR/issue templates
|
- **MokoCLI compliant** -- follows all Moko Consulting governance conventions: file headers, commit messages, `.gitattributes`, `.gitmessage`, PR/issue templates
|
||||||
- **Example configuration** -- `config.example.json` demonstrates the connection configuration schema
|
- **Example configuration** -- `config.example.json` demonstrates the connection configuration schema
|
||||||
- **Documentation templates** -- wiki pages for API reference, architecture overview, and installation pre-generated
|
- **Documentation templates** -- wiki pages for API reference, architecture overview, and installation pre-generated
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ Template repository for creating MokoStandards-compliant Model Context Protocol
|
|||||||
|
|
||||||
1. Create a new repository from this template (or clone directly):
|
1. Create a new repository from this template (or clone directly):
|
||||||
```bash
|
```bash
|
||||||
git clone https://git.mokoconsulting.tech/MokoConsulting/Template-MCP.git my-mcp-server
|
git clone https://git.mokoconsulting.tech/MokoConsulting/Template-NPM.git my-mcp-server
|
||||||
cd my-mcp-server
|
cd my-mcp-server
|
||||||
```
|
```
|
||||||
2. Install dependencies:
|
2. Install dependencies:
|
||||||
@@ -61,11 +61,11 @@ Template repository for creating MokoStandards-compliant Model Context Protocol
|
|||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
Full documentation is available on the [Wiki](https://git.mokoconsulting.tech/MokoConsulting/Template-MCP/wiki), including:
|
Full documentation is available on the [Wiki](https://git.mokoconsulting.tech/MokoConsulting/Template-NPM/wiki), including:
|
||||||
|
|
||||||
- [API](https://git.mokoconsulting.tech/MokoConsulting/Template-MCP/wiki/API) -- tool reference and connection parameter documentation
|
- [API](https://git.mokoconsulting.tech/MokoConsulting/Template-NPM/wiki/API) -- tool reference and connection parameter documentation
|
||||||
- [ARCHITECTURE](https://git.mokoconsulting.tech/MokoConsulting/Template-MCP/wiki/ARCHITECTURE) -- MCP server design and REST API bridge pattern
|
- [ARCHITECTURE](https://git.mokoconsulting.tech/MokoConsulting/Template-NPM/wiki/ARCHITECTURE) -- MCP server design and REST API bridge pattern
|
||||||
- [INSTALLATION](https://git.mokoconsulting.tech/MokoConsulting/Template-MCP/wiki/INSTALLATION) -- setup prerequisites and configuration guide
|
- [INSTALLATION](https://git.mokoconsulting.tech/MokoConsulting/Template-NPM/wiki/INSTALLATION) -- setup prerequisites and configuration guide
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@ This project is licensed under the GNU General Public License v3.0 or later -- s
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
*[Moko Consulting](https://mokoconsulting.tech) -- [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/MokoCLI/wiki/Home)*
|
*[Moko Consulting](https://mokoconsulting.tech) -- [MokoCLI](https://git.mokoconsulting.tech/MokoConsulting/mokocli/wiki/Home)*
|
||||||
|
|
||||||
## Template CI Notes
|
## Template CI Notes
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user