chore(rebrand): gitea -> git (MokoGitea -> MokoGit, .mokogitea -> .mokogit) #346

Merged
jmiller merged 1 commits from chore/rebrand-gitea-to-git into main 2026-07-14 20:56:58 +00:00
296 changed files with 1347 additions and 1347 deletions
+4 -4
View File
@@ -38,7 +38,7 @@ composer check # Run all checks
| `lib/Enterprise/Plugins/` | 11 platform plugins (Joomla, Dolibarr, Node.js, Python, etc.) |
| `deploy/` | SFTP deployment scripts (Joomla, Dolibarr, health checks) |
| `templates/` | Universal templates, configs, governance schema |
| `.mokogitea/workflows/` | CI/CD workflows (MokoGitea Actions) |
| `.mokogit/workflows/` | CI/CD workflows (MokoGit Actions) |
| `bin/moko` | Unified CLI dispatcher — `php bin/moko <command>` |
| `monitoring/sites.json` | Sites list for mcp_mokomonitor |
@@ -50,7 +50,7 @@ After adding a CLI tool, register it in `bin/moko` COMMAND_MAP.
### Platform Adapters
- `MokoGiteaAdapter` — git.mokoconsulting.tech (primary)
- `MokoGitAdapter` — git.mokoconsulting.tech (primary)
- `GitHubAdapter` — github.com mirrors
### Plugin System
@@ -70,7 +70,7 @@ PHPStan runs with `--memory-limit=512M`. CI enforces PHPCS errors; PHPStan is `c
- **Never commit** `.claude/`, `.mcp.json`, `TODO.md`, `*.min.css`/`*.min.js`
- **Attribution**: `Authored-by: Moko Consulting`
- **Workflow directory**: `.mokogitea/` (not `.gitea/` or `.github/`)
- **Wiki**: documentation lives in the MokoGitea wiki, not `docs/` files
- **Workflow directory**: `.mokogit/` (not `.gitea/` or `.github/`)
- **Wiki**: documentation lives in the MokoGit wiki, not `docs/` files
- **New CLI tools**: extend `CliFramework`, not `CLIApp` (legacy)
- **Standards**: [MokoCli](https://git.mokoconsulting.tech/MokoConsulting/mokocli/wiki/Home)
@@ -1,7 +1,7 @@
# Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
# SPDX-License-Identifier: GPL-3.0-or-later
# FILE INFORMATION
# DEFGROUP: Gitea.Workflow
# DEFGROUP: Git.Workflow
# INGROUP: mokocli.Automation
# REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
# PATH: /.gitea/workflows/branch-protection.yml
@@ -42,8 +42,8 @@ on:
default: ''
env:
GITEA_URL: https://git.mokoconsulting.tech
GITEA_ORG: MokoConsulting
GIT_URL: https://git.mokoconsulting.tech
GIT_ORG: MokoConsulting
permissions:
contents: read
@@ -57,12 +57,12 @@ jobs:
- name: Determine target repos
id: repos
env:
GA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
GA_TOKEN: ${{ secrets.MOKOGIT_TOKEN }}
run: |
API="${GITEA_URL}/api/v1"
API="${GIT_URL}/api/v1"
# Platform/standards/infra repos to exclude
EXCLUDE="gitea-org-config org-profile gitea-private .mokogitea-private mokocli MokoTesting"
EXCLUDE="git-org-config org-profile git-private .mokogit-private mokocli MokoTesting"
EXCLUDE="$EXCLUDE MokoCli-Template-Client MokoCli-Template-Dolibarr MokoCli-Template-Generic MokoCli-Template-Joomla MokoDoliProjTemplate"
if [ -n "${{ inputs.repos }}" ]; then
@@ -75,7 +75,7 @@ jobs:
while true; do
BATCH=$(curl -sS \
-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')
[ -z "$BATCH" ] && break
REPOS="$REPOS $BATCH"
@@ -105,10 +105,10 @@ jobs:
- name: Apply protection rules
env:
GA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
GA_TOKEN: ${{ secrets.MOKOGIT_TOKEN }}
DRY_RUN: ${{ inputs.dry_run || 'false' }}
run: |
API="${GITEA_URL}/api/v1"
API="${GIT_URL}/api/v1"
REPOS="${{ steps.repos.outputs.repos }}"
SUCCESS=0
@@ -222,7 +222,7 @@ jobs:
curl -sS -o /dev/null -w "" \
-X DELETE \
-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
RESPONSE=$(curl -sS -w "\n%{http_code}" \
@@ -230,7 +230,7 @@ jobs:
-H "Authorization: token ${GA_TOKEN}" \
-H "Content-Type: application/json" \
-d "$RULE" \
"${API}/repos/${GITEA_ORG}/${REPO}/branch_protections")
"${API}/repos/${GIT_ORG}/${REPO}/branch_protections")
HTTP=$(echo "$RESPONSE" | tail -1)
BODY=$(echo "$RESPONSE" | sed '$d')
@@ -1,7 +1,7 @@
# Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
# SPDX-License-Identifier: GPL-3.0-or-later
# FILE INFORMATION
# DEFGROUP: Gitea.Workflow
# DEFGROUP: Git.Workflow
# INGROUP: mokocli.Automation
# REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
# PATH: /.gitea/workflows/bulk-repo-sync.yml
@@ -64,7 +64,7 @@ jobs:
id: args
run: |
ARGS="--org MokoConsulting"
if [ "${{ inputs.dry_run }}" = "true" ] || [ "${{ gitea.event_name }}" = "schedule" ]; then
if [ "${{ inputs.dry_run }}" = "true" ] || [ "${{ git.event_name }}" = "schedule" ]; then
ARGS="$ARGS --dry-run"
fi
if [ -n "${{ inputs.repos }}" ]; then
@@ -84,18 +84,18 @@ jobs:
echo "Running: php automation/bulk_sync.php ${{ steps.args.outputs.args }}"
php automation/bulk_sync.php ${{ steps.args.outputs.args }} 2>&1 | tee /tmp/bulk_sync.log
env:
GA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
GA_TOKEN: ${{ secrets.MOKOGIT_TOKEN }}
GH_TOKEN: ${{ secrets.GH_PAT }}
GIT_PLATFORM: gitea
GITEA_URL: https://git.mokoconsulting.tech
GITEA_ORG: MokoConsulting
GIT_PLATFORM: git
GIT_URL: https://git.mokoconsulting.tech
GIT_ORG: MokoConsulting
- name: Commit Updated Definitions
if: success() && inputs.dry_run != 'true'
run: |
if [ -n "$(git status --porcelain definitions/sync/)" ]; then
git config user.name "gitea-actions[bot]"
git config user.email "gitea-actions[bot]@git.mokoconsulting.tech"
git config user.name "git-actions[bot]"
git config user.email "git-actions[bot]@git.mokoconsulting.tech"
git add definitions/sync/*.def.tf
git commit -m "chore: update synced repository definitions" || true
git push || true
@@ -112,9 +112,9 @@ jobs:
bash automation/enforce_tags.sh || echo "Tag enforcement had errors (non-fatal)"
fi
env:
GA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
GITEA_URL: https://git.mokoconsulting.tech
GITEA_ORG: MokoConsulting
GA_TOKEN: ${{ secrets.MOKOGIT_TOKEN }}
GIT_URL: https://git.mokoconsulting.tech
GIT_ORG: MokoConsulting
- name: Upload Sync Log
if: always() && github.server_url == 'https://github.com'
@@ -124,7 +124,7 @@ jobs:
path: /tmp/bulk_sync.log
retention-days: 30
- name: Log Summary (Gitea)
- name: Log Summary (Git)
if: always() && github.server_url != 'https://github.com'
run: |
if [ -f /tmp/bulk_sync.log ]; then
@@ -3,7 +3,7 @@
# SPDX-License-Identifier: GPL-3.0-or-later
#
# FILE INFORMATION
# DEFGROUP: Gitea.Workflow
# DEFGROUP: Git.Workflow
# INGROUP: mokocli.Automation
# REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
# PATH: /.gitea/workflows/renovate.yml
@@ -41,8 +41,8 @@ on:
default: false
env:
GITEA_URL: https://git.mokoconsulting.tech
GITEA_ORG: MokoConsulting
GIT_URL: https://git.mokoconsulting.tech
GIT_ORG: MokoConsulting
RENOVATE_VERSION: '39'
permissions:
@@ -57,11 +57,11 @@ jobs:
- name: Determine target repos
id: repos
env:
GA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
GA_TOKEN: ${{ secrets.MOKOGIT_TOKEN }}
run: |
API="${GITEA_URL}/api/v1"
API="${GIT_URL}/api/v1"
EXCLUDE="gitea-org-config org-profile gitea-private .mokogitea-private mokocli MokoTesting"
EXCLUDE="git-org-config org-profile git-private .mokogit-private mokocli MokoTesting"
EXCLUDE="$EXCLUDE MokoCli-Template-Client MokoCli-Template-Dolibarr MokoCli-Template-Generic MokoCli-Template-Joomla MokoDoliProjTemplate"
if [ -n "${{ inputs.repos }}" ]; then
@@ -72,7 +72,7 @@ jobs:
while true; do
BATCH=$(curl -sS \
-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')
[ -z "$BATCH" ] && break
REPOS="$REPOS $BATCH"
@@ -94,9 +94,9 @@ jobs:
REPO_LIST=""
for REPO in $REPOS; do
if [ -n "$REPO_LIST" ]; then
REPO_LIST="${REPO_LIST},${GITEA_ORG}/${REPO}"
REPO_LIST="${REPO_LIST},${GIT_ORG}/${REPO}"
else
REPO_LIST="${GITEA_ORG}/${REPO}"
REPO_LIST="${GIT_ORG}/${REPO}"
fi
done
@@ -107,8 +107,8 @@ jobs:
- name: Run Renovate
if: steps.repos.outputs.repo_list != ''
env:
RENOVATE_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
RENOVATE_PLATFORM: gitea
RENOVATE_TOKEN: ${{ secrets.MOKOGIT_TOKEN }}
RENOVATE_PLATFORM: git
RENOVATE_ENDPOINT: ${{ env.GITEA_URL }}/api/v1
RENOVATE_GIT_AUTHOR: 'Renovate Bot <renovate@mokoconsulting.tech>'
RENOVATE_REPOSITORIES: ${{ steps.repos.outputs.repo_list }}
@@ -116,8 +116,8 @@ jobs:
LOG_LEVEL: info
run: |
npx --yes renovate@${RENOVATE_VERSION} \
--platform=gitea \
--endpoint="${GITEA_URL}/api/v1" \
--platform=git \
--endpoint="${GIT_URL}/api/v1" \
--token="${RENOVATE_TOKEN}" \
--git-author="Renovate Bot <renovate@mokoconsulting.tech>" \
--autodiscover=false \
@@ -3,11 +3,11 @@
# SPDX-License-Identifier: GPL-3.0-or-later
#
# FILE INFORMATION
# DEFGROUP: Gitea.Workflow
# DEFGROUP: Git.Workflow
# INGROUP: mokocli.Maintenance
# REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
# PATH: /.gitea/workflows/sync-wikis.yml
# BRIEF: Daily sync of all Gitea wikis to consolidated GitHub wiki repo
# BRIEF: Daily sync of all Git wikis to consolidated GitHub wiki repo
name: Sync Wikis to GitHub
@@ -32,7 +32,7 @@ jobs:
- name: Sync all wikis
env:
GH_TOKEN: ${{ secrets.GH_PAT }}
GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
GIT_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
run: |
if [ -z "$GH_TOKEN" ]; then
echo "::error::GH_TOKEN secret not set"
@@ -3,10 +3,10 @@
# SPDX-License-Identifier: GPL-3.0-or-later
#
# FILE INFORMATION
# DEFGROUP: MokoGitea.Workflow
# DEFGROUP: MokoGit.Workflow
# INGROUP: MokoCLI.Release
# REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Generic
# PATH: /.mokogitea/workflows/auto-bump.yml
# PATH: /.mokogit/workflows/auto-bump.yml
# VERSION: 09.02.00
# BRIEF: Auto patch-bump version on every push to dev (skips merge commits)
@@ -22,7 +22,7 @@ on:
env:
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:
contents: write
@@ -41,7 +41,7 @@ jobs:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
token: ${{ secrets.MOKOGITEA_TOKEN }}
token: ${{ secrets.MOKOGIT_TOKEN }}
fetch-depth: 1
- name: Setup MokoCLI tools
@@ -53,7 +53,7 @@ jobs:
echo "MOKO_CLI=/opt/mokocli/cli" >> "$GITHUB_ENV"
else
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
cd /tmp/mokocli && composer install --no-dev --no-interaction --quiet
echo "MOKO_CLI=/tmp/mokocli/cli" >> "$GITHUB_ENV"
@@ -63,5 +63,5 @@ jobs:
run: |
php ${MOKO_CLI}/version_auto_bump.php \
--path . --branch "${GITHUB_REF_NAME}" \
--token "${{ secrets.MOKOGITEA_TOKEN }}" \
--repo-url "https://x-access-token:${{ secrets.MOKOGITEA_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git"
--token "${{ secrets.MOKOGIT_TOKEN }}" \
--repo-url "https://x-access-token:${{ secrets.MOKOGIT_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git"
@@ -3,10 +3,10 @@
# SPDX-License-Identifier: GPL-3.0-or-later
#
# FILE INFORMATION
# DEFGROUP: MokoGitea.Workflow
# DEFGROUP: MokoGit.Workflow
# INGROUP: MokoCLI.Release
# REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Generic
# PATH: /.mokogitea/workflows/auto-release.yml
# PATH: /.mokogit/workflows/auto-release.yml
# VERSION: 05.01.00
# BRIEF: Universal build & release detects platform from metadata API
#
@@ -31,7 +31,7 @@ on:
branches:
- main
paths-ignore:
- '.mokogitea/workflows/**'
- '.mokogit/workflows/**'
- '*.md'
- 'wiki/**'
- '.editorconfig'
@@ -52,9 +52,9 @@ on:
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
MOKOGITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
GITEA_ORG: ${{ vars.GITEA_ORG || github.repository_owner }}
GITEA_REPO: ${{ vars.GITEA_REPO || github.event.repository.name }}
MOKOGIT_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
GIT_ORG: ${{ vars.GITEA_ORG || github.repository_owner }}
GIT_REPO: ${{ vars.GITEA_REPO || github.event.repository.name }}
permissions:
contents: write
@@ -77,13 +77,13 @@ jobs:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
token: ${{ secrets.MOKOGITEA_TOKEN }}
token: ${{ secrets.MOKOGIT_TOKEN }}
fetch-depth: 1
submodules: recursive
- name: Setup MokoCLI tools
env:
MOKO_CLONE_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
MOKO_CLONE_TOKEN: ${{ secrets.MOKOGIT_TOKEN }}
MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting
run: |
if [ -f /opt/mokocli/cli/version_bump.php ] && [ -f /opt/mokocli/vendor/autoload.php ]; then
@@ -104,8 +104,8 @@ jobs:
- name: Rename branch to rc
run: |
API_BASE="${MOKOGITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
AUTH="Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}"
API_BASE="${MOKOGIT_URL}/api/v1/repos/${GIT_ORG}/${GIT_REPO}"
AUTH="Authorization: token ${{ secrets.MOKOGIT_TOKEN }}"
FROM="${{ github.event.pull_request.head.ref || 'dev' }}"
PR="${{ github.event.pull_request.number }}"
@@ -115,12 +115,12 @@ jobs:
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. Gitea's git/refs PATCH API
# 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.MOKOGITEA_TOKEN }}@${MOKOGITEA_URL#https://}/${GITEA_ORG}/${GITEA_REPO}.git"
git config --global user.name "mokogitea-actions[bot]"
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" \
@@ -144,28 +144,28 @@ jobs:
- name: Trigger RC deploy
run: |
# Workflow-token pushes do NOT wake downstream workflows; dispatch deploy-rc explicitly.
curl -sf -X POST -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \n -H "Content-Type: application/json" \n "${MOKOGITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}/actions/workflows/deploy-rc.yml/dispatches" \n -d '{"ref":"rc"}' \n && echo "Dispatched deploy-rc on rc" \n || echo "::warning::deploy-rc dispatch failed (no deploy-rc.yml on rc? non-go platform)"
curl -sf -X POST -H "Authorization: token ${{ secrets.MOKOGIT_TOKEN }}" \n -H "Content-Type: application/json" \n "${MOKOGIT_URL}/api/v1/repos/${GIT_ORG}/${GIT_REPO}/actions/workflows/deploy-rc.yml/dispatches" \n -d '{"ref":"rc"}' \n && echo "Dispatched deploy-rc on rc" \n || echo "::warning::deploy-rc dispatch failed (no deploy-rc.yml on rc? non-go platform)"
- name: Checkout rc and configure git
run: |
git fetch origin rc
git checkout rc
git config --local user.email "mokogitea-actions[bot]@mokoconsulting.tech"
git config --local user.name "mokogitea-actions[bot]"
git remote set-url origin "https://x-access-token:${{ secrets.MOKOGITEA_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git"
git config --local user.email "mokogit-actions[bot]@mokoconsulting.tech"
git config --local user.name "mokogit-actions[bot]"
git remote set-url origin "https://x-access-token:${{ secrets.MOKOGIT_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git"
- name: Publish RC release
continue-on-error: true
run: |
php ${MOKO_CLI}/release_publish.php \
--path . --stability rc --bump minor --branch rc \
--token "${{ secrets.MOKOGITEA_TOKEN }}"
--token "${{ secrets.MOKOGIT_TOKEN }}"
- name: Update RC release notes from CHANGELOG.md
continue-on-error: true
run: |
API_BASE="${MOKOGITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
TOKEN="${{ secrets.MOKOGITEA_TOKEN }}"
API_BASE="${MOKOGIT_URL}/api/v1/repos/${GIT_ORG}/${GIT_REPO}"
TOKEN="${{ secrets.MOKOGIT_TOKEN }}"
# Extract [Unreleased] section from changelog
NOTES=""
@@ -218,15 +218,15 @@ jobs:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
token: ${{ secrets.MOKOGITEA_TOKEN }}
token: ${{ secrets.MOKOGIT_TOKEN }}
fetch-depth: 0
submodules: recursive
- name: Configure git for bot pushes
run: |
git config --local user.email "mokogitea-actions[bot]@mokoconsulting.tech"
git config --local user.name "mokogitea-actions[bot]"
git remote set-url origin "https://x-access-token:${{ secrets.MOKOGITEA_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git"
git config --local user.email "mokogit-actions[bot]@mokoconsulting.tech"
git config --local user.name "mokogit-actions[bot]"
git remote set-url origin "https://x-access-token:${{ secrets.MOKOGIT_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git"
- name: Check for merge conflict markers
run: |
@@ -243,7 +243,7 @@ jobs:
- name: Setup MokoCLI tools
env:
MOKO_CLONE_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
MOKO_CLONE_TOKEN: ${{ secrets.MOKOGIT_TOKEN }}
MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting
COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GH_MIRROR_TOKEN }}"}}'
run: |
@@ -290,7 +290,7 @@ jobs:
fi
php ${MOKO_CLI}/release_publish.php \
--path . --stability stable ${BUMP_FLAG} --branch main \
--token "${{ secrets.MOKOGITEA_TOKEN }}"
--token "${{ secrets.MOKOGIT_TOKEN }}"
- name: "Read published version"
id: version
@@ -317,8 +317,8 @@ jobs:
!startsWith(steps.platform.outputs.platform, 'joomla')
run: |
VERSION="${{ steps.version.outputs.version }}"
API_BASE="${MOKOGITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
TOKEN="${{ secrets.MOKOGITEA_TOKEN }}"
API_BASE="${MOKOGIT_URL}/api/v1/repos/${GIT_ORG}/${GIT_REPO}"
TOKEN="${{ secrets.MOKOGIT_TOKEN }}"
SEMVER_TAG="v${VERSION}"
echo "Creating semver tag: ${SEMVER_TAG}"
@@ -342,8 +342,8 @@ jobs:
- name: Update release notes and promote changelog
run: |
API_BASE="${MOKOGITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
TOKEN="${{ secrets.MOKOGITEA_TOKEN }}"
API_BASE="${MOKOGIT_URL}/api/v1/repos/${GIT_ORG}/${GIT_REPO}"
TOKEN="${{ secrets.MOKOGIT_TOKEN }}"
# Get the stable release info (version and ID)
RELEASE_JSON=$(curl -sf -H "Authorization: token ${TOKEN}" \
@@ -445,10 +445,10 @@ jobs:
VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}"
RELEASE_TAG="${{ steps.version.outputs.release_tag }}"
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 \
--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" \
--branch main 2>&1 || true
echo "GitHub mirror updated" >> $GITHUB_STEP_SUMMARY
@@ -474,8 +474,8 @@ jobs:
if: steps.version.outputs.skip != 'true'
continue-on-error: true
run: |
API_BASE="${MOKOGITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
TOKEN="${{ secrets.MOKOGITEA_TOKEN }}"
API_BASE="${MOKOGIT_URL}/api/v1/repos/${GIT_ORG}/${GIT_REPO}"
TOKEN="${{ secrets.MOKOGIT_TOKEN }}"
# Delete rc branch (ephemeral — created by promote-rc)
curl -sf -X DELETE -H "Authorization: token ${TOKEN}" \
@@ -490,8 +490,8 @@ jobs:
if: steps.version.outputs.skip != 'true'
continue-on-error: true
run: |
API_BASE="${MOKOGITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
TOKEN="${{ secrets.MOKOGITEA_TOKEN }}"
API_BASE="${MOKOGIT_URL}/api/v1/repos/${GIT_ORG}/${GIT_REPO}"
TOKEN="${{ secrets.MOKOGIT_TOKEN }}"
VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}"
BRANCH_NAME="version/${VERSION}"
MAIN_SHA=$(git rev-parse HEAD)
@@ -511,9 +511,9 @@ jobs:
if: steps.version.outputs.skip != 'true'
continue-on-error: true
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 \
--token "${{ secrets.MOKOGITEA_TOKEN }}" --api-base "${API_BASE}" \
--token "${{ secrets.MOKOGIT_TOKEN }}" --api-base "${API_BASE}" \
--branch dev --path . 2>&1 || true
# -- Summary --------------------------------------------------------------
@@ -537,5 +537,5 @@ jobs:
echo "| Version | \`${VERSION}\` |" >> $GITHUB_STEP_SUMMARY
echo "| Branch | \`${{ steps.version.outputs.branch }}\` |" >> $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
@@ -3,10 +3,10 @@
# SPDX-License-Identifier: GPL-3.0-or-later
#
# FILE INFORMATION
# DEFGROUP: MokoGitea.Workflow
# DEFGROUP: MokoGit.Workflow
# INGROUP: MokoCLI.Universal
# REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Generic
# PATH: /.mokogitea/workflows/branch-cleanup.yml
# PATH: /.mokogit/workflows/branch-cleanup.yml
# VERSION: 01.00.00
# BRIEF: Delete feature branches after PR merge
@@ -37,7 +37,7 @@ jobs:
ENCODED=$(printf '%s' "${BRANCH}" | sed 's|/|%2F|g')
STATUS=$(curl -sf -o /dev/null -w "%{http_code}" -X DELETE \
-H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \
-H "Authorization: token ${{ secrets.MOKOGIT_TOKEN }}" \
"${API}/${ENCODED}" 2>/dev/null || true)
if [ "$STATUS" = "204" ]; then
@@ -3,10 +3,10 @@
# SPDX-License-Identifier: GPL-3.0-or-later
#
# FILE INFORMATION
# DEFGROUP: MokoGitea.Workflow
# DEFGROUP: MokoGit.Workflow
# INGROUP: MokoCLI.Cascade
# REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Generic
# PATH: /.mokogitea/workflows/cascade-dev.yml
# PATH: /.mokogit/workflows/cascade-dev.yml
# VERSION: 02.01.00
# BRIEF: Cascade main -> dev; auto-merge clean, auto-resolve VERSION-stamp-only conflicts, else notify
@@ -27,10 +27,10 @@ permissions:
pull-requests: write
env:
MOKOGITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
MOKOGIT_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
# ntfy destination is configured via repo or org variables (org vars are inherited).
NTFY_URL: ${{ vars.NTFY_URL || 'https://ntfy.mokoconsulting.tech' }}
NTFY_TOPIC: ${{ vars.CASCADE_NTFY_TOPIC || vars.NTFY_TOPIC || 'gitea-releases' }}
NTFY_TOPIC: ${{ vars.CASCADE_NTFY_TOPIC || vars.NTFY_TOPIC || 'git-releases' }}
jobs:
cascade:
@@ -41,15 +41,15 @@ jobs:
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.MOKOGITEA_TOKEN }}
token: ${{ secrets.MOKOGIT_TOKEN }}
- name: Cascade main -> dev (auto-resolve version stamps, else notify)
env:
TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
TOKEN: ${{ secrets.MOKOGIT_TOKEN }}
REPO: ${{ github.repository }}
run: |
set -uo pipefail
API="${MOKOGITEA_URL}/api/v1/repos/${REPO}"
API="${MOKOGIT_URL}/api/v1/repos/${REPO}"
AUTH="Authorization: token ${TOKEN}"
jqget() { python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('$1',''))" 2>/dev/null; }
@@ -86,12 +86,12 @@ jobs:
-H "Title: ${REPO}: dev cascade needs manual merge" \
-H "Tags: warning,twisted_rightwards_arrows" \
-H "Priority: high" \
-H "Click: ${MOKOGITEA_URL}/${REPO}/pulls/${PR}" \
-H "Click: ${MOKOGIT_URL}/${REPO}/pulls/${PR}" \
-d "main -> dev cascade PR #${PR} $1 It was NOT auto-merged; resolve it manually." \
"${NTFY_URL}/${NTFY_TOPIC}" || true
}
# 3. wait for MokoGitea to compute mergeability (conflict detection)
# 3. wait for MokoGit to compute mergeability (conflict detection)
MERGEABLE=""
for _ in 1 2 3 4 5 6; do
MERGEABLE=$(curl -sf -H "$AUTH" "${API}/pulls/${PR}" | jqget mergeable)
@@ -115,7 +115,7 @@ jobs:
# 4b. conflicts -> try to auto-resolve if they are ONLY VERSION-stamp lines.
echo "PR not cleanly mergeable; checking whether conflicts are VERSION-stamp-only..."
git config user.name "MokoGitea Cascade"
git config user.name "MokoGit Cascade"
git config user.email "actions@mokoconsulting.tech"
git fetch --quiet origin main dev
git checkout -B dev origin/dev
@@ -3,10 +3,10 @@
# SPDX-License-Identifier: GPL-3.0-or-later
#
# FILE INFORMATION
# DEFGROUP: MokoGitea.Workflow
# DEFGROUP: MokoGit.Workflow
# INGROUP: MokoCLI.CI
# REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Generic
# PATH: /.mokogitea/workflows/ci-generic.yml
# PATH: /.mokogit/workflows/ci-generic.yml
# VERSION: 01.00.00
# BRIEF: CI pipeline — lint, validate, and test for generic projects (PHP + Node.js)
@@ -131,7 +131,7 @@ jobs:
test:
name: Tests
runs-on: ubuntu-latest
# Independent job (no `needs: lint`): the MokoGitea Actions scheduler does not
# Independent job (no `needs: lint`): the MokoGit Actions scheduler does not
# offer the dependent 2nd job of a needs-chain to runners, so it stalls in
# "waiting" and is reaped by ABANDONED_JOB_TIMEOUT. Guard template repos
# directly (same condition lint uses) instead of gating on lint's result.
@@ -3,12 +3,12 @@
# SPDX-License-Identifier: GPL-3.0-or-later
#
# FILE INFORMATION
# DEFGROUP: MokoGitea.Workflow
# DEFGROUP: MokoGit.Workflow
# INGROUP: MokoCLI.Universal
# REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Generic
# PATH: /.mokogitea/workflows/ci-issue-reporter.yml
# PATH: /.mokogit/workflows/ci-issue-reporter.yml
# VERSION: 01.00.00
# BRIEF: Reusable workflow — creates/updates a MokoGitea 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.
name: "Universal: CI Issue Reporter"
@@ -35,7 +35,7 @@ on:
type: string
default: ""
secrets:
MOKOGITEA_TOKEN:
MOKOGIT_TOKEN:
required: true
env:
@@ -49,16 +49,16 @@ jobs:
steps:
- name: Clone MokoCLI
env:
MOKOGITEA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
MOKOGIT_TOKEN: ${{ secrets.MOKOGIT_TOKEN }}
run: |
MOKOGITEA_URL="${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}"
git clone --depth 1 --filter=blob:none --sparse "${MOKOGITEA_URL}/MokoConsulting/mokocli.git" /tmp/mokocli
MOKOGIT_URL="${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}"
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
- name: Report CI failure
env:
MOKOGITEA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
MOKOGITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
MOKOGIT_TOKEN: ${{ secrets.MOKOGIT_TOKEN }}
MOKOGIT_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
run: |
chmod +x /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
#
# FILE INFORMATION
# DEFGROUP: MokoGitea.Workflow
# DEFGROUP: MokoGit.Workflow
# INGROUP: MokoCLI.Maintenance
# REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
# PATH: /.mokogitea/workflows/cleanup.yml
# PATH: /.mokogit/workflows/cleanup.yml
# VERSION: 01.00.00
# BRIEF: Scheduled cleanup — delete merged branches and old workflow runs
@@ -21,7 +21,7 @@ permissions:
contents: write
env:
MOKOGITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
MOKOGIT_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
jobs:
cleanup:
@@ -33,17 +33,17 @@ jobs:
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.MOKOGITEA_TOKEN }}
token: ${{ secrets.MOKOGIT_TOKEN }}
- name: Delete merged branches
env:
MOKOGITEA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
MOKOGIT_TOKEN: ${{ secrets.MOKOGIT_TOKEN }}
run: |
echo "=== Merged Branch Cleanup ==="
API="${MOKOGITEA_URL}/api/v1/repos/${{ github.repository }}"
API="${MOKOGIT_URL}/api/v1/repos/${{ github.repository }}"
# 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')
DELETED=0
@@ -56,7 +56,7 @@ jobs:
# Check if branch is merged into main
if git merge-base --is-ancestor "origin/${BRANCH}" origin/main 2>/dev/null; then
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
DELETED=$((DELETED + 1))
fi
@@ -66,20 +66,20 @@ jobs:
- name: Clean old workflow runs
env:
MOKOGITEA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
MOKOGIT_TOKEN: ${{ secrets.MOKOGIT_TOKEN }}
run: |
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)
# 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" | \
jq -r ".workflow_runs[] | select(.created_at < \"${CUTOFF}\") | .id" 2>/dev/null)
DELETED=0
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
DELETED=$((DELETED + 1))
done
@@ -27,7 +27,7 @@ jobs:
- name: Checkout MokoCLI
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
token: ${{ secrets.MOKOGITEA_TOKEN }}
token: ${{ secrets.MOKOGIT_TOKEN }}
- name: Setup PHP
run: |
@@ -42,7 +42,7 @@ jobs:
DRY_RUN="--dry-run"
fi
php cli/branch_protect_org.php \
--token "${{ secrets.MOKOGITEA_TOKEN }}" \
--token "${{ secrets.MOKOGIT_TOKEN }}" \
--org "MokoConsulting" \
$DRY_RUN
@@ -3,10 +3,10 @@
# SPDX-License-Identifier: GPL-3.0-or-later
#
# FILE INFORMATION
# DEFGROUP: Gitea.Workflow
# DEFGROUP: Git.Workflow
# INGROUP: mokocli.CI
# REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
# PATH: /.mokogitea/workflows/ci-platform.yml
# PATH: /.mokogit/workflows/ci-platform.yml
# VERSION: 09.23.00
# BRIEF: mokocli CI — the standards engine validates itself
#
@@ -41,7 +41,7 @@ on:
paths-ignore:
- '**.md'
- 'wiki/**'
- '.mokogitea/ISSUE_TEMPLATE/**'
- '.mokogit/ISSUE_TEMPLATE/**'
pull_request:
branches:
- main
@@ -356,7 +356,7 @@ jobs:
echo "::error file=${file}::Invalid YAML"
ERRORS=$((ERRORS + 1))
fi
done < <(find .mokogitea/workflows/ -name "*.yml" -o -name "*.yaml" 2>/dev/null | tr '\n' '\0')
done < <(find .mokogit/workflows/ -name "*.yml" -o -name "*.yaml" 2>/dev/null | tr '\n' '\0')
{
echo "### Template Integrity"
@@ -453,8 +453,8 @@ jobs:
needs.governance.result == 'failure' ||
needs.templates.result == 'failure')
env:
MOKOGITEA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
MOKOGITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
MOKOGIT_TOKEN: ${{ secrets.MOKOGIT_TOKEN }}
MOKOGIT_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
run: |
chmod +x automation/ci-issue-reporter.sh
REPORTER="./automation/ci-issue-reporter.sh"
@@ -13,7 +13,7 @@ on:
workflow_dispatch:
env:
MOKOGITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
MOKOGIT_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
jobs:
publish:
@@ -43,13 +43,13 @@ jobs:
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
echo "Package version: ${VERSION}"
# Gitea Composer Registry — auto-publishes from tags
# Git Composer Registry — auto-publishes from tags
# The tag push itself registers the package at:
# https://git.mokoconsulting.tech/api/packages/MokoConsulting/composer
- name: Verify Gitea registry
- name: Verify Git registry
run: |
echo "Gitea Composer registry auto-publishes from tags."
echo "Package available at: ${MOKOGITEA_URL}/api/packages/MokoConsulting/composer"
echo "Git Composer registry auto-publishes from tags."
echo "Package available at: ${MOKOGIT_URL}/api/packages/MokoConsulting/composer"
echo "Install: composer require mokoconsulting/mokocli"
# Packagist — notify of new version (points to GitHub mirror which Packagist can access)
@@ -72,5 +72,5 @@ jobs:
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Registry | Status |" >> $GITHUB_STEP_SUMMARY
echo "|----------|--------|" >> $GITHUB_STEP_SUMMARY
echo "| Gitea | \`composer require mokoconsulting/mokocli:${VERSION}\` |" >> $GITHUB_STEP_SUMMARY
echo "| Git | \`composer require mokoconsulting/mokocli:${VERSION}\` |" >> $GITHUB_STEP_SUMMARY
echo "| Packagist | \`composer require mokoconsulting/mokocli\` |" >> $GITHUB_STEP_SUMMARY
@@ -3,10 +3,10 @@
# SPDX-License-Identifier: GPL-3.0-or-later
#
# FILE INFORMATION
# DEFGROUP: Gitea.Workflow
# DEFGROUP: Git.Workflow
# INGROUP: mokocli.Automation
# REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
# PATH: /.mokogitea/workflows/sync-feature-versions.yml
# PATH: /.mokogit/workflows/sync-feature-versions.yml
# VERSION: 01.00.00
# BRIEF: Merge dev into open feature branches after version bumps
@@ -22,7 +22,7 @@ permissions:
contents: write
env:
MOKOGITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
MOKOGIT_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
jobs:
sync:
@@ -38,13 +38,13 @@ jobs:
with:
fetch-depth: 0
ref: dev
token: ${{ secrets.MOKOGITEA_TOKEN }}
token: ${{ secrets.MOKOGIT_TOKEN }}
- name: Configure git
run: |
git config --local user.email "gitea-actions[bot]@mokoconsulting.tech"
git config --local user.name "gitea-actions[bot]"
git remote set-url origin "https://x-access-token:${{ secrets.MOKOGITEA_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git"
git config --local user.email "git-actions[bot]@mokoconsulting.tech"
git config --local user.name "git-actions[bot]"
git remote set-url origin "https://x-access-token:${{ secrets.MOKOGIT_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git"
- name: Merge dev into feature branches
run: |
@@ -3,10 +3,10 @@
# SPDX-License-Identifier: GPL-3.0-or-later
#
# FILE INFORMATION
# DEFGROUP: MokoGitea.Workflow
# DEFGROUP: MokoGit.Workflow
# INGROUP: MokoCLI.Security
# REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
# PATH: /.mokogitea/workflows/gitleaks.yml
# PATH: /.mokogit/workflows/gitleaks.yml
# VERSION: 01.00.00
# BRIEF: Secret scanning — detect leaked credentials, API keys, and tokens
#
@@ -34,7 +34,7 @@ permissions:
env:
NTFY_URL: ${{ vars.NTFY_URL || 'https://ntfy.mokoconsulting.tech' }}
NTFY_TOPIC: ${{ vars.NTFY_TOPIC || 'gitea-security' }}
NTFY_TOPIC: ${{ vars.NTFY_TOPIC || 'git-security' }}
jobs:
gitleaks:
@@ -3,7 +3,7 @@
# SPDX-License-Identifier: GPL-3.0-or-later
#
# FILE INFORMATION
# DEFGROUP: MokoGitea.Workflow
# DEFGROUP: MokoGit.Workflow
# INGROUP: MokoCLI.Automation
# VERSION: 01.00.00
# BRIEF: Auto-create feature branch when an issue is opened
@@ -19,7 +19,7 @@ permissions:
issues: write
env:
MOKOGITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
MOKOGIT_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
jobs:
create-branch:
@@ -28,8 +28,8 @@ jobs:
steps:
- name: Create branch and comment
run: |
TOKEN="${{ secrets.MOKOGITEA_TOKEN }}"
API="${MOKOGITEA_URL}/api/v1/repos/${{ github.repository }}"
TOKEN="${{ secrets.MOKOGIT_TOKEN }}"
API="${MOKOGIT_URL}/api/v1/repos/${{ github.repository }}"
ISSUE_NUM="${{ github.event.issue.number }}"
ISSUE_TITLE="${{ github.event.issue.title }}"
@@ -58,7 +58,7 @@ jobs:
echo "Created branch: ${BRANCH}"
# Comment on issue with branch link
REPO_URL="${MOKOGITEA_URL}/${{ github.repository }}"
REPO_URL="${MOKOGIT_URL}/${{ github.repository }}"
BODY="Branch created: [\`${BRANCH}\`](${REPO_URL}/src/branch/${BRANCH})\n\n\`\`\`bash\ngit fetch origin\ngit checkout ${BRANCH}\n\`\`\`"
curl -sf -X POST \
@@ -3,10 +3,10 @@
# SPDX-License-Identifier: GPL-3.0-or-later
#
# FILE INFORMATION
# DEFGROUP: MokoGitea.Workflow
# DEFGROUP: MokoGit.Workflow
# INGROUP: MokoCLI.Notifications
# REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
# PATH: /.mokogitea/workflows/notify.yml
# PATH: /.mokogit/workflows/notify.yml
# VERSION: 01.00.00
# BRIEF: Push notifications via ntfy on release success or workflow failure
@@ -26,7 +26,7 @@ permissions:
env:
NTFY_URL: ${{ vars.NTFY_URL || 'https://ntfy.mokoconsulting.tech' }}
NTFY_TOPIC: ${{ vars.NTFY_TOPIC || 'gitea-releases' }}
NTFY_TOPIC: ${{ vars.NTFY_TOPIC || 'git-releases' }}
jobs:
notify:
@@ -3,10 +3,10 @@
# SPDX-License-Identifier: GPL-3.0-or-later
#
# FILE INFORMATION
# DEFGROUP: MokoGitea.Workflow
# DEFGROUP: MokoGit.Workflow
# INGROUP: MokoCLI.CI
# REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Generic
# PATH: /.mokogitea/workflows/pr-check.yml
# PATH: /.mokogit/workflows/pr-check.yml
# VERSION: 09.23.00
# BRIEF: PR gate — branch policy + code validation before merge
@@ -145,7 +145,7 @@ jobs:
steps:
- name: Remind to update the wiki
env:
TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
TOKEN: ${{ secrets.MOKOGIT_TOKEN }}
SERVER: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
REPO: ${{ github.repository }}
PR: ${{ github.event.pull_request.number }}
@@ -210,7 +210,7 @@ jobs:
- name: Check for merge conflict markers
run: |
CONFLICTS=$(grep -rn '<<<<<<< \|>>>>>>> \|^=======$' --exclude-dir='.git' --exclude-dir='.mokogitea' --include='*.php' --include='*.xml' --include='*.css' --include='*.js' --include='*.json' --include='*.md' --include='*.yml' --include='*.yaml' --include='*.ini' --include='*.txt' . 2>/dev/null | grep -v '.git/' || true)
CONFLICTS=$(grep -rn '<<<<<<< \|>>>>>>> \|^=======$' --exclude-dir='.git' --exclude-dir='.mokogit' --include='*.php' --include='*.xml' --include='*.css' --include='*.js' --include='*.json' --include='*.md' --include='*.yml' --include='*.yaml' --include='*.ini' --include='*.txt' . 2>/dev/null | grep -v '.git/' || true)
if [ -n "$CONFLICTS" ]; then
echo "::error::Merge conflict markers found in source files"
echo "## Conflict Markers Found" >> $GITHUB_STEP_SUMMARY
@@ -224,7 +224,7 @@ jobs:
- name: Detect platform
id: platform
run: |
# Platform comes from the MokoGitea metadata API (public GET).
# Platform comes from the MokoGit metadata API (public GET).
API="${GITHUB_SERVER_URL:-https://git.mokoconsulting.tech}/api/v1/repos/${GITHUB_REPOSITORY}/metadata"
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"
@@ -361,10 +361,10 @@ jobs:
for ELEMENT in name version description; do
grep -q "<${ELEMENT}>" "$MANIFEST" || { echo "::error::Missing <${ELEMENT}> in manifest"; exit 1; }
done
# Block legacy raw/branch update server URLs on MokoGitea
RAW_URLS=$(grep -n 'raw/branch' "$MANIFEST" | grep -i 'mokoconsulting\|mokogitea\|git\.mokoconsulting\.tech' || true)
# Block legacy raw/branch update server URLs on MokoGit
RAW_URLS=$(grep -n 'raw/branch' "$MANIFEST" | grep -i 'mokoconsulting\|mokogit\|git\.mokoconsulting\.tech' || true)
if [ -n "$RAW_URLS" ]; then
echo "::error::Manifest contains legacy raw/branch update server URL on MokoGitea. Use the MokoGitea 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"
exit 1
fi
@@ -578,12 +578,12 @@ jobs:
steps:
- name: Trigger RC pre-release
env:
MOKOGITEA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
MOKOGIT_TOKEN: ${{ secrets.MOKOGIT_TOKEN }}
REPO: ${{ github.repository }}
BRANCH: ${{ github.head_ref }}
MOKOGITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
MOKOGIT_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
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 "Triggered RC build on branch \`${BRANCH}\`" >> $GITHUB_STEP_SUMMARY
@@ -594,7 +594,7 @@ jobs:
if: >-
always() &&
needs.validate.result == 'failure'
uses: ./.mokogitea/workflows/ci-issue-reporter.yml
uses: ./.mokogit/workflows/ci-issue-reporter.yml
with:
gate: "PR Validation"
workflow: "PR Check"
@@ -3,10 +3,10 @@
# SPDX-License-Identifier: GPL-3.0-or-later
#
# FILE INFORMATION
# DEFGROUP: MokoGitea.Workflow
# DEFGROUP: MokoGit.Workflow
# INGROUP: MokoCLI.Release
# REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Generic
# PATH: /.mokogitea/workflows/pre-release.yml
# PATH: /.mokogit/workflows/pre-release.yml
# VERSION: 05.02.01
# BRIEF: Auto pre-release on push to dev/alpha/beta/rc branches
@@ -40,9 +40,9 @@ permissions:
contents: write
env:
GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
GITEA_ORG: ${{ vars.GITEA_ORG || github.repository_owner }}
GITEA_REPO: ${{ vars.GITEA_REPO || github.event.repository.name }}
GIT_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
GIT_ORG: ${{ vars.GITEA_ORG || github.repository_owner }}
GIT_REPO: ${{ vars.GITEA_REPO || github.event.repository.name }}
jobs:
build:
@@ -61,7 +61,7 @@ jobs:
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.MOKOGITEA_TOKEN }}
token: ${{ secrets.MOKOGIT_TOKEN }}
ref: ${{ github.ref_name }}
submodules: recursive
@@ -71,7 +71,7 @@ jobs:
- name: Setup MokoCLI tools
env:
MOKO_CLONE_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
MOKO_CLONE_TOKEN: ${{ secrets.MOKOGIT_TOKEN }}
MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting
run: |
# Use pre-installed /opt/mokocli if available (updated by cron every 6h)
@@ -156,9 +156,9 @@ jobs:
fi
# Commit version bump
git config --local user.email "mokogitea-actions[bot]@mokoconsulting.tech"
git config --local user.name "mokogitea-actions[bot]"
git remote set-url origin "https://x-access-token:${{ secrets.MOKOGITEA_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git"
git config --local user.email "mokogit-actions[bot]@mokoconsulting.tech"
git config --local user.name "mokogit-actions[bot]"
git remote set-url origin "https://x-access-token:${{ secrets.MOKOGIT_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git"
git add -A
git diff --cached --quiet || {
git commit -m "chore(version): pre-release bump to ${VERSION} [skip ci]"
@@ -174,12 +174,12 @@ jobs:
# Auto-detect element via manifest_element.php
php ${MOKO_CLI}/manifest_element.php \
--path . --version "$VERSION" --stability "$STABILITY" \
--repo "${GITEA_REPO}" --github-output
--repo "${GIT_REPO}" --github-output
# Read back element outputs
EXT_ELEMENT=$(grep '^ext_element=' "$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"
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
@@ -197,18 +197,18 @@ jobs:
run: |
TAG="${{ steps.meta.outputs.tag }}"
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 \
--path . --version "$VERSION" --tag "$TAG" \
--token "${{ secrets.MOKOGITEA_TOKEN }}" --api-base "$API_BASE" \
--repo "${GITEA_REPO}" --branch "${{ github.ref_name }}" --prerelease
--token "${{ secrets.MOKOGIT_TOKEN }}" --api-base "$API_BASE" \
--repo "${GIT_REPO}" --branch "${{ github.ref_name }}" --prerelease
- name: Update release notes from CHANGELOG.md
if: steps.eligibility.outputs.proceed == 'true'
run: |
TAG="${{ steps.meta.outputs.tag }}"
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)
if [ -f "CHANGELOG.md" ]; then
@@ -219,7 +219,7 @@ jobs:
fi
# 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)
if [ -n "$RELEASE_ID" ]; then
@@ -231,7 +231,7 @@ jobs:
'${API_BASE}/releases/${RELEASE_ID}',
data=payload, method='PATCH',
headers={
'Authorization': 'token ${{ secrets.MOKOGITEA_TOKEN }}',
'Authorization': 'token ${{ secrets.MOKOGIT_TOKEN }}',
'Content-Type': 'application/json'
})
urllib.request.urlopen(req)
@@ -245,21 +245,21 @@ jobs:
run: |
VERSION="${{ steps.meta.outputs.version }}"
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 \
--path . --version "$VERSION" --tag "$TAG" \
--token "${{ secrets.MOKOGITEA_TOKEN }}" --api-base "$API_BASE" \
--repo "${GITEA_REPO}" --output /tmp || true
--token "${{ secrets.MOKOGIT_TOKEN }}" --api-base "$API_BASE" \
--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
- name: "Delete lesser pre-release channels (cascade)"
if: steps.eligibility.outputs.proceed == 'true'
continue-on-error: true
run: |
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
TOKEN="${{ secrets.MOKOGITEA_TOKEN }}"
API_BASE="${GIT_URL}/api/v1/repos/${GIT_ORG}/${GIT_REPO}"
TOKEN="${{ secrets.MOKOGIT_TOKEN }}"
php ${MOKO_CLI}/release_cascade.php \
--stability "${{ steps.meta.outputs.stability }}" \
@@ -3,10 +3,10 @@
# SPDX-License-Identifier: GPL-3.0-or-later
#
# FILE INFORMATION
# DEFGROUP: MokoGitea.Workflow
# DEFGROUP: MokoGit.Workflow
# INGROUP: MokoCLI.Universal
# REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Generic
# PATH: /.mokogitea/workflows/rc-revert.yml
# PATH: /.mokogit/workflows/rc-revert.yml
# VERSION: 09.23.00
# BRIEF: Rename rc/ branch back to dev/ when PR is closed without merge
@@ -33,8 +33,8 @@ jobs:
env:
BRANCH: ${{ github.event.pull_request.head.ref }}
REPO: ${{ github.repository }}
GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
GIT_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
TOKEN: ${{ secrets.MOKOGIT_TOKEN }}
run: |
set -euo pipefail
# BRANCH is attacker-controlled (PR head ref). Strict allowlist before ANY use.
@@ -43,7 +43,7 @@ jobs:
fi
SUFFIX="${BRANCH#rc/}"
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
STATUS=$(curl -sf -o /dev/null -w "%{http_code}" -X POST \
@@ -6,10 +6,10 @@
# SPDX-License-Identifier: GPL-3.0-or-later
#
# FILE INFORMATION
# DEFGROUP: MokoGitea.Workflow
# DEFGROUP: MokoGit.Workflow
# INGROUP: MokoCLI.Validation
# REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Generic
# PATH: /.mokogitea/workflows/repo-health.yml
# PATH: /.mokogit/workflows/repo-health.yml
# VERSION: 09.23.00
# 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
# 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_DISALLOWED_DIRS:
REPO_DISALLOWED_FILES: TODO.md,todo.md
@@ -56,7 +56,7 @@ env:
# File / directory variables
DOCS_INDEX: docs/docs-index.md
SCRIPT_DIR: scripts
WORKFLOWS_DIR: .mokogitea/workflows
WORKFLOWS_DIR: .mokogit/workflows
SHELLCHECK_PATTERN: '*.sh'
SPDX_FILE_GLOBS: '*.sh,*.php,*.js,*.ts,*.css,*.xml,*.yml,*.yaml'
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
@@ -77,7 +77,7 @@ jobs:
- name: Check actor permission (admin only)
id: perm
env:
TOKEN: ${{ secrets.MOKOGITEA_TOKEN || github.token }}
TOKEN: ${{ secrets.MOKOGIT_TOKEN || github.token }}
REPO: ${{ github.repository }}
ACTOR: ${{ github.actor }}
run: |
@@ -88,14 +88,14 @@ jobs:
# Hardcoded authorized users — always allowed
case "$ACTOR" in
jmiller|mokogitea-actions[bot])
jmiller|mokogit-actions[bot])
ALLOWED=true
PERMISSION=admin
METHOD="hardcoded allowlist"
;;
*)
# 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}" \
"${API_BASE}/repos/${REPO}/collaborators/${ACTOR}/permission" 2>/dev/null || echo '{}')
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' '|---|---|---|'
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' '| Repo required artifacts | OK | Required, optional, disallowed enforcement |'
printf '%s\n' '| Repo content heuristics | OK | Brand, license, changelog structure |'
@@ -677,7 +677,7 @@ jobs:
if: >-
always() &&
needs.scripts_governance.result == 'failure'
uses: ./.mokogitea/workflows/ci-issue-reporter.yml
uses: ./.mokogit/workflows/ci-issue-reporter.yml
with:
gate: "Scripts Governance"
workflow: "Repo Health"
@@ -691,7 +691,7 @@ jobs:
if: >-
always() &&
needs.repo_health.result == 'failure'
uses: ./.mokogitea/workflows/ci-issue-reporter.yml
uses: ./.mokogit/workflows/ci-issue-reporter.yml
with:
gate: "Repository Health"
workflow: "Repo Health"
@@ -4,7 +4,7 @@
# DEFGROUP: GitHub.Workflow
# INGROUP: MokoCLI.Compliance
# REPO: https://github.com/mokoconsulting-tech/mokocli
# PATH: /.mokogitea/workflows/standards-compliance.yml
# PATH: /.mokogit/workflows/standards-compliance.yml
# VERSION: 04.06.00
# BRIEF: MokoCLI compliance validation workflow
# NOTE: Validates repository structure, documentation, and coding standards
@@ -299,7 +299,7 @@ jobs:
echo "|-----------|--------|-------|------|-------|" >> $GITHUB_STEP_SUMMARY
# Check required directories
for dir in .mokogitea; do
for dir in .mokogit; do
if [ -d "$dir" ]; then
FILE_COUNT=$(find "$dir" -type f 2>/dev/null | wc -l)
DIR_SIZE=$(du -sh "$dir" 2>/dev/null | cut -f1)
@@ -320,7 +320,7 @@ jobs:
echo "### 🔴 Critical Issues: $MISSING" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Remediation Steps:**" >> $GITHUB_STEP_SUMMARY
[ ! -d ".mokogitea" ] && echo "- Create .mokogitea directory: \`mkdir -p .mokogitea/workflows\`" >> $GITHUB_STEP_SUMMARY
[ ! -d ".mokogit" ] && echo "- Create .mokogit directory: \`mkdir -p .mokogit/workflows\`" >> $GITHUB_STEP_SUMMARY
echo "" >> $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
@@ -563,17 +563,17 @@ jobs:
set -x
echo "### GitHub Actions Workflows" >> $GITHUB_STEP_SUMMARY
WORKFLOWS_DIR=".mokogitea/workflows"
WORKFLOWS_DIR=".mokogit/workflows"
if [ ! -d "$WORKFLOWS_DIR" ]; then
echo "❌ No workflows directory found" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### ❌ Validation Failed: Workflows Directory Missing" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Error:** .mokogitea/workflows directory is required for CI/CD automation" >> $GITHUB_STEP_SUMMARY
echo "**Action Required:** Create .mokogitea/workflows directory and add GitHub Actions workflows" >> $GITHUB_STEP_SUMMARY
echo "**Error:** .mokogit/workflows directory is required for CI/CD automation" >> $GITHUB_STEP_SUMMARY
echo "**Action Required:** Create .mokogit/workflows directory and add GitHub Actions workflows" >> $GITHUB_STEP_SUMMARY
echo ""
echo "❌ ERROR: .mokogitea/workflows directory not found"
echo "❌ ERROR: .mokogit/workflows directory not found"
exit 1
fi
@@ -612,7 +612,7 @@ jobs:
echo "### Workflow YAML Syntax" >> $GITHUB_STEP_SUMMARY
INVALID=0
for workflow in $(find .mokogitea/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 python3 -c "import yaml, sys; yaml.safe_load(open(sys.argv[1]))" "$workflow" 2>/dev/null; then
echo "✅ $(basename $workflow)" >> $GITHUB_STEP_SUMMARY
@@ -629,7 +629,7 @@ jobs:
echo "" >> $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 "**Tool:** Run \`python3 -c \"import yaml; yaml.safe_load(open('.mokogitea/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 "❌ ERROR: $INVALID workflow file(s) with invalid YAML syntax"
exit 1
@@ -641,7 +641,7 @@ jobs:
echo "✅ SUCCESS: All workflow files passed YAML validation"
- name: Validate CodeQL Configuration
if: hashFiles('.mokogitea/workflows/codeql-analysis.yml') != ''
if: hashFiles('.mokogit/workflows/codeql-analysis.yml') != ''
run: |
set -e
echo "" >> $GITHUB_STEP_SUMMARY
@@ -649,7 +649,7 @@ jobs:
echo "" >> $GITHUB_STEP_SUMMARY
# Inline validation (rewritten from Python to bash for PHP-only architecture)
CODEQL_FILE=".mokogitea/workflows/codeql-analysis.yml"
CODEQL_FILE=".mokogit/workflows/codeql-analysis.yml"
if [ ! -f "$CODEQL_FILE" ]; then
echo "⚠️ CodeQL workflow file not found" >> $GITHUB_STEP_SUMMARY
@@ -1186,7 +1186,7 @@ jobs:
fi
# Run yamllint and count line-length warnings
YAML_OUTPUT=$(yamllint .mokogitea/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
YAML_VIOLATIONS=$(echo "$YAML_OUTPUT" | wc -l)
echo "⚠️ Found $YAML_VIOLATIONS lines exceeding 180 characters in YAML files" >> $GITHUB_STEP_SUMMARY
@@ -2130,17 +2130,17 @@ jobs:
WARNINGS=0
ERRORS=0
# 1. Check .mokogitea/config.tf location (not root override files)
# 1. Check .mokogit/config.tf location (not root override files)
echo "### Override Configuration Check" >> $GITHUB_STEP_SUMMARY
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
echo "⚠️ Found legacy override files in root directory" >> $GITHUB_STEP_SUMMARY
echo "**Expected Location**: .mokogitea/config.tf" >> $GITHUB_STEP_SUMMARY
echo "**Expected Location**: .mokogit/config.tf" >> $GITHUB_STEP_SUMMARY
echo "**Legacy files found**: $LEGACY_OVERRIDES" >> $GITHUB_STEP_SUMMARY
WARNINGS=$((WARNINGS + 1))
else
if [ -f ".mokogitea/config.tf" ]; then
echo "✅ Override configuration in correct location (.mokogitea/config.tf)" >> $GITHUB_STEP_SUMMARY
if [ -f ".mokogit/config.tf" ]; then
echo "✅ Override configuration in correct location (.mokogit/config.tf)" >> $GITHUB_STEP_SUMMARY
else
echo "️ No override configuration found" >> $GITHUB_STEP_SUMMARY
fi
@@ -3,10 +3,10 @@
# SPDX-License-Identifier: GPL-3.0-or-later
#
# FILE INFORMATION
# DEFGROUP: MokoGitea.Workflow.Template
# DEFGROUP: MokoGit.Workflow.Template
# INGROUP: MokoCLI.CI
# REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Joomla
# PATH: /.mokogitea/workflows/version-set.yml
# PATH: /.mokogit/workflows/version-set.yml
# VERSION: 01.00.00
# BRIEF: Set or reset the extension version across all version-bearing files
@@ -49,7 +49,7 @@ jobs:
- name: Checkout
uses: actions/checkout@v4
with:
token: ${{ secrets.MOKOGITEA_TOKEN || github.token }}
token: ${{ secrets.MOKOGIT_TOKEN || github.token }}
ref: ${{ inputs.branch || github.ref }}
fetch-depth: 1
+2 -2
View File
@@ -34,7 +34,7 @@ feature/* ──PR──> dev ──draft PR──> (renamed to rc) ──merge
7. **Merging to main** triggers the stable release pipeline:
- Minor version bump (e.g., `02.09.xx` → `02.10.00`)
- Stability suffix stripped (clean version)
- MokoGitea release created with ZIP/tar.gz packages
- MokoGit release created with ZIP/tar.gz packages
- `updates.xml` updated (Joomla extensions)
- `dev` branch recreated from `main`
@@ -119,7 +119,7 @@ This ensures Joomla sites on ANY stability channel see the update (Joomla only s
The version tools update all files containing version stamps:
- `.mokogitea/manifest.xml` (canonical source)
- `.mokogit/manifest.xml` (canonical source)
- Joomla XML manifests (`<version>` tag)
- `README.md`, `CHANGELOG.md` (`VERSION:` pattern)
- `package.json`, `pyproject.toml`
+7 -7
View File
@@ -16,7 +16,7 @@ BRIEF: Project overview and documentation
PHP implementation of mokocli — enterprise standards, automation framework, workflow templates, and bulk sync tooling.
> **Primary platform**: [MokoGitea — git.mokoconsulting.tech](https://git.mokoconsulting.tech/MokoConsulting/MokoCli-API)
> **Primary platform**: [MokoGit — git.mokoconsulting.tech](https://git.mokoconsulting.tech/MokoConsulting/MokoCli-API)
> **Backup mirror**: [GitHub](https://github.com/MokoConsulting/MokoCli-API) *(read-only mirror)*
## What Lives Here
@@ -25,7 +25,7 @@ PHP implementation of mokocli — enterprise standards, automation framework, wo
|-----------|---------|
| `lib/Enterprise/` | 38 PHP enterprise library classes (platform adapters, sync, validation, plugins) |
| `cli/` | CLI scripts (archive, create, release, sync rulesets, version management) |
| `automation/` | Bulk sync, push files, repo cleanup, MokoGitea migration |
| `automation/` | Bulk sync, push files, repo cleanup, MokoGit migration |
| `validate/` | 18 validation scripts (health, structure, secrets, syntax, drift) |
| `templates/` | **Workflow templates** and config templates synced to governed repos |
| `definitions/` | Repository structure definitions (`.tf` format) |
@@ -42,7 +42,7 @@ composer require mokoconsulting-tech/enterprise
### Composer Registry
This package is served from MokoGitea package registry. Add this to your `composer.json`:
This package is served from MokoGit package registry. Add this to your `composer.json`:
```json
{
@@ -72,11 +72,11 @@ vendor/bin/moko inventory -- --path .
| Variable | Purpose |
|----------|---------|
| `GIT_PLATFORM` | `gitea` (default) or `github` |
| `GA_TOKEN` | MokoGitea API / MokoGitea Actions token |
| `GIT_PLATFORM` | `git` (default) or `github` |
| `GA_TOKEN` | MokoGit API / MokoGit Actions token |
| `GH_TOKEN` | GitHub API token (for mirror sync) |
| `GITEA_URL` | MokoGitea instance URL (default: `https://git.mokoconsulting.tech`) |
| `GITEA_ORG` | MokoGitea organization (default: `MokoConsulting`) |
| `GIT_URL` | MokoGit instance URL (default: `https://git.mokoconsulting.tech`) |
| `GIT_ORG` | MokoGit organization (default: `MokoConsulting`) |
## License
+2 -2
View File
@@ -21,7 +21,7 @@
*
* COMMANDS (run `php bin/moko list` for the full list — 97 commands)
*
* Automation sync, automation:cleanup, automation:migrate-gitea
* Automation sync, automation:cleanup, automation:migrate-git
* Validation health, detect, drift, check:syntax, check:version, ...
* Release release, release:joomla, release:create, release:publish, ...
* Version version:read, version:bump, version:auto-bump, ...
@@ -91,7 +91,7 @@ const COMMAND_MAP = [
'sync' => 'automation/bulk_sync.php',
'deps:update' => 'automation/update_dependencies.php',
'automation:cleanup' => 'automation/repo_cleanup.php',
'automation:migrate-gitea' => 'automation/migrate_to_gitea.php',
'automation:migrate-git' => 'automation/migrate_to_git.php',
// Maintenance
'inventory' => 'maintenance/update_repo_inventory.php',
+1 -1
View File
@@ -25,7 +25,7 @@ if (isset($options['help']) || empty($options['token'])) {
echo "Usage: php cli/branch_protect_org.php --token TOKEN [--org ORG] [--api-base URL] [--dry-run]\n";
echo "\n";
echo "Options:\n";
echo " --token Gitea API token (required)\n";
echo " --token Git API token (required)\n";
echo " --org Organization name (default: MokoConsulting)\n";
echo " --api-base API base URL (default: https://git.mokoconsulting.tech/api/v1)\n";
echo " --dry-run Show what would be changed without making changes\n";
+2 -2
View File
@@ -11,7 +11,7 @@
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /cli/branch_rename.php
* VERSION: 09.43.00
* BRIEF: Rename a git branch via Gitea API (create new, update PR, delete old)
* BRIEF: Rename a git branch via Git API (create new, update PR, delete old)
*/
declare(strict_types=1);
@@ -24,7 +24,7 @@ class BranchRenameCli extends CliFramework
{
protected function configure(): void
{
$this->setDescription('Rename a git branch via Gitea API (create new, update PR, delete old)');
$this->setDescription('Rename a git branch via Git API (create new, update PR, delete old)');
$this->addArgument('--from', 'Source branch name', '');
$this->addArgument('--to', 'Target branch name', '');
$this->addArgument('--token', 'API token', '');
+18 -18
View File
@@ -13,7 +13,7 @@
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /cli/bulk_workflow_push.php
* VERSION: 09.43.00
* BRIEF: Push a workflow file to all governed repos via the Gitea Contents API
* BRIEF: Push a workflow file to all governed repos via the Git Contents API
*/
declare(strict_types=1);
@@ -31,18 +31,18 @@ class BulkWorkflowPushCli extends CliFramework
protected function configure(): void
{
$this->setDescription('Push a workflow file to all governed repos via the Gitea Contents API');
$this->addArgument('--gitea-url', 'Gitea URL (default: https://git.mokoconsulting.tech)', 'https://git.mokoconsulting.tech');
$this->addArgument('--token', 'Gitea API token', '');
$this->setDescription('Push a workflow file to all governed repos via the Git Contents API');
$this->addArgument('--git-url', 'Git URL (default: https://git.mokoconsulting.tech)', 'https://git.mokoconsulting.tech');
$this->addArgument('--token', 'Git API token', '');
$this->addArgument('--org', 'Target organization', '');
$this->addArgument('--file', 'Local workflow file to push', '');
$this->addArgument('--dest', 'Destination path in repos (default: .mokogitea/workflows/<filename>)', '');
$this->addArgument('--dest', 'Destination path in repos (default: .mokogit/workflows/<filename>)', '');
$this->addArgument('--branch', 'Target branch (default: main)', 'main');
}
protected function run(): int
{
$giteaUrl = rtrim($this->getArgument('--gitea-url'), '/');
$gitUrl = rtrim($this->getArgument('--git-url'), '/');
$token = $this->getArgument('--token');
$org = $this->getArgument('--org');
$workflowFile = $this->getArgument('--file');
@@ -70,7 +70,7 @@ class BulkWorkflowPushCli extends CliFramework
}
if ($destPath === '') {
$destPath = '.mokogitea/workflows/' . basename($workflowFile);
$destPath = '.mokogit/workflows/' . basename($workflowFile);
}
$localContent = file_get_contents($workflowFile);
@@ -82,7 +82,7 @@ class BulkWorkflowPushCli extends CliFramework
$this->log('INFO', "Pushing: {$workflowFile}");
$this->log('INFO', " -> {$destPath} (branch: {$branch})");
$this->log('INFO', " -> Org: {$org} @ {$giteaUrl}");
$this->log('INFO', " -> Org: {$org} @ {$gitUrl}");
if ($this->dryRun) {
$this->log('INFO', '[DRY RUN] No changes will be made.');
@@ -90,7 +90,7 @@ class BulkWorkflowPushCli extends CliFramework
echo "\n";
$repos = $this->fetchOrgRepos($giteaUrl, $token, $org);
$repos = $this->fetchOrgRepos($gitUrl, $token, $org);
if ($repos === null) {
return 1;
@@ -104,7 +104,7 @@ class BulkWorkflowPushCli extends CliFramework
$encodedContent = base64_encode($localContent);
foreach ($repos as $repo) {
$this->pushToRepo($giteaUrl, $token, $repo, $encodedContent, $localContent, $destPath, $branch);
$this->pushToRepo($gitUrl, $token, $repo, $encodedContent, $localContent, $destPath, $branch);
}
echo "\n";
@@ -115,7 +115,7 @@ class BulkWorkflowPushCli extends CliFramework
}
private function pushToRepo(
string $giteaUrl,
string $gitUrl,
string $token,
string $repoFullName,
string $encodedContent,
@@ -126,7 +126,7 @@ class BulkWorkflowPushCli extends CliFramework
[$owner, $repoName] = explode('/', $repoFullName, 2);
$existing = $this->apiRequest(
$giteaUrl,
$gitUrl,
$token,
'GET',
"/api/v1/repos/{$owner}/{$repoName}/contents/"
@@ -159,7 +159,7 @@ class BulkWorkflowPushCli extends CliFramework
]);
$response = $this->apiRequest(
$giteaUrl,
$gitUrl,
$token,
'PUT',
"/api/v1/repos/{$owner}/{$repoName}/contents/"
@@ -189,7 +189,7 @@ class BulkWorkflowPushCli extends CliFramework
]);
$response = $this->apiRequest(
$giteaUrl,
$gitUrl,
$token,
'POST',
"/api/v1/repos/{$owner}/{$repoName}/contents/"
@@ -210,7 +210,7 @@ class BulkWorkflowPushCli extends CliFramework
}
}
private function fetchOrgRepos(string $giteaUrl, string $token, string $org): ?array
private function fetchOrgRepos(string $gitUrl, string $token, string $org): ?array
{
$this->log('INFO', "Fetching repos from org: {$org}");
@@ -219,7 +219,7 @@ class BulkWorkflowPushCli extends CliFramework
while (true) {
$response = $this->apiRequest(
$giteaUrl,
$gitUrl,
$token,
'GET',
"/api/v1/orgs/{$org}/repos?"
@@ -261,13 +261,13 @@ class BulkWorkflowPushCli extends CliFramework
}
private function apiRequest(
string $giteaUrl,
string $gitUrl,
string $token,
string $method,
string $endpoint,
?string $body = null
): array {
$url = $giteaUrl . $endpoint;
$url = $gitUrl . $endpoint;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
+6 -6
View File
@@ -24,7 +24,7 @@ use MokoCli\CliFramework;
class BulkWorkflowTriggerCli extends CliFramework
{
private string $giteaUrl = 'https://git.mokoconsulting.tech';
private string $gitUrl = 'https://git.mokoconsulting.tech';
private string $token = '';
private string $reposFile = '';
private string $org = '';
@@ -35,8 +35,8 @@ class BulkWorkflowTriggerCli extends CliFramework
protected function configure(): void
{
$this->setDescription('Trigger a workflow across multiple repos at once');
$this->addArgument('--gitea-url', 'Gitea URL (default: https://git.mokoconsulting.tech)', 'https://git.mokoconsulting.tech');
$this->addArgument('--token', 'Gitea API token', '');
$this->addArgument('--git-url', 'Git URL (default: https://git.mokoconsulting.tech)', 'https://git.mokoconsulting.tech');
$this->addArgument('--token', 'Git API token', '');
$this->addArgument('--repos', 'File with newline-separated owner/repo list', '');
$this->addArgument('--org', 'Trigger on all repos in an org', '');
$this->addArgument('--workflow', 'Workflow file (e.g., "sync-servers.yml")', '');
@@ -46,7 +46,7 @@ class BulkWorkflowTriggerCli extends CliFramework
protected function run(): int
{
$this->giteaUrl = rtrim($this->getArgument('--gitea-url'), '/');
$this->gitUrl = rtrim($this->getArgument('--git-url'), '/');
$this->token = $this->getArgument('--token');
$this->reposFile = $this->getArgument('--repos');
$this->org = $this->getArgument('--org');
@@ -78,7 +78,7 @@ class BulkWorkflowTriggerCli extends CliFramework
}
$this->log('INFO', "Triggering workflow \"{$this->workflow}\" on ref \"{$this->ref}\" across " . count($repos) . " repo(s).");
$this->log('INFO', "Gitea URL: {$this->giteaUrl}");
$this->log('INFO', "Git URL: {$this->gitUrl}");
if ($this->dryRun) {
$this->log('INFO', '[DRY RUN] No requests will be sent.');
@@ -209,7 +209,7 @@ class BulkWorkflowTriggerCli extends CliFramework
private function apiRequest(string $method, string $endpoint, ?string $body = null): array
{
$url = $this->giteaUrl . $endpoint;
$url = $this->gitUrl . $endpoint;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
+19 -19
View File
@@ -10,7 +10,7 @@
# REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoCLI
# PATH: /cli/ci_issue_reporter.sh
# VERSION: 10.00.00
# BRIEF: Creates or updates a Gitea issue when a CI gate fails.
# BRIEF: Creates or updates a Git issue when a CI gate fails.
# Deduplicates by searching open issues with the "ci-auto" label
# whose title matches the gate. If a matching issue exists, a comment
# is appended instead of opening a duplicate.
@@ -19,10 +19,10 @@
set -euo pipefail
# ── Defaults ────────────────────────────────────────────────────────────────
MOKOGITEA_URL="${MOKOGITEA_URL:-https://git.mokoconsulting.tech}"
MOKOGITEA_TOKEN="${MOKOGITEA_TOKEN:-}"
MOKOGIT_URL="${MOKOGIT_URL:-https://git.mokoconsulting.tech}"
MOKOGIT_TOKEN="${MOKOGIT_TOKEN:-}"
REPO="${GITHUB_REPOSITORY:-}"
RUN_URL="${GITHUB_SERVER_URL:-${MOKOGITEA_URL}}/${REPO}/actions/runs/${GITHUB_RUN_ID:-0}"
RUN_URL="${GITHUB_SERVER_URL:-${MOKOGIT_URL}}/${REPO}/actions/runs/${GITHUB_RUN_ID:-0}"
LABEL_NAME="ci-auto"
LABEL_COLOR="#e11d48"
@@ -45,8 +45,8 @@ Optional:
--workflow Workflow name for the issue title
--repo owner/repo (default: \$GITHUB_REPOSITORY)
--run-url URL to the CI run (auto-detected from env)
--token Gitea API token (default: \$MOKOGITEA_TOKEN)
--url Gitea base URL (default: \$MOKOGITEA_URL)
--token Git API token (default: \$MOKOGIT_TOKEN)
--url Git base URL (default: \$MOKOGIT_URL)
EOF
exit 1
}
@@ -59,8 +59,8 @@ while [[ $# -gt 0 ]]; do
--workflow) WORKFLOW="$2"; shift 2 ;;
--repo) REPO="$2"; shift 2 ;;
--run-url) RUN_URL="$2"; shift 2 ;;
--token) MOKOGITEA_TOKEN="$2"; shift 2 ;;
--url) MOKOGITEA_URL="$2"; shift 2 ;;
--token) MOKOGIT_TOKEN="$2"; shift 2 ;;
--url) MOKOGIT_URL="$2"; shift 2 ;;
-h|--help) usage ;;
*) echo "Unknown option: $1"; usage ;;
esac
@@ -68,10 +68,10 @@ done
[[ -z "$GATE" ]] && { echo "ERROR: --gate is required"; usage; }
[[ -z "$DETAILS" ]] && { echo "ERROR: --details is required"; usage; }
[[ -z "$MOKOGITEA_TOKEN" ]] && { echo "ERROR: MOKOGITEA_TOKEN not set"; exit 1; }
[[ -z "$MOKOGIT_TOKEN" ]] && { echo "ERROR: MOKOGIT_TOKEN not set"; exit 1; }
[[ -z "$REPO" ]] && { echo "ERROR: GITHUB_REPOSITORY not set"; exit 1; }
API="${MOKOGITEA_URL}/api/v1/repos/${REPO}"
API="${MOKOGIT_URL}/api/v1/repos/${REPO}"
# ── Build title ─────────────────────────────────────────────────────────────
if [[ -n "$WORKFLOW" ]]; then
@@ -84,19 +84,19 @@ fi
ensure_label() {
local exists
exists=$(curl -sf -o /dev/null -w '%{http_code}' \
-H "Authorization: token ${MOKOGITEA_TOKEN}" \
-H "Authorization: token ${MOKOGIT_TOKEN}" \
"${API}/labels" 2>/dev/null || echo "000")
if [[ "$exists" == "200" ]]; then
local found
found=$(curl -sf \
-H "Authorization: token ${MOKOGITEA_TOKEN}" \
-H "Authorization: token ${MOKOGIT_TOKEN}" \
"${API}/labels" 2>/dev/null \
| grep -o "\"name\":\"${LABEL_NAME}\"" || true)
if [[ -z "$found" ]]; then
curl -sf -X POST \
-H "Authorization: token ${MOKOGITEA_TOKEN}" \
-H "Authorization: token ${MOKOGIT_TOKEN}" \
-H "Content-Type: application/json" \
"${API}/labels" \
-d "{\"name\":\"${LABEL_NAME}\",\"color\":\"${LABEL_COLOR}\",\"description\":\"Auto-created by CI issue reporter\"}" \
@@ -112,7 +112,7 @@ find_existing_issue() {
local response
response=$(curl -sf \
-H "Authorization: token ${MOKOGITEA_TOKEN}" \
-H "Authorization: token ${MOKOGIT_TOKEN}" \
"${API}/issues?type=issues&state=open&labels=${LABEL_NAME}&q=${query}&limit=5" \
2>/dev/null || echo "[]")
@@ -148,7 +148,7 @@ ${DETAILS}
Fix the issue described above and push a new commit. This issue will be closed automatically when the gate passes, or can be closed manually.
---
*Auto-created by [ci-issue-reporter](${MOKOGITEA_URL}/MokoConsulting/MokoCLI/src/branch/main/cli/ci_issue_reporter.sh)*
*Auto-created by [ci-issue-reporter](${MOKOGIT_URL}/MokoConsulting/MokoCLI/src/branch/main/cli/ci_issue_reporter.sh)*
BODY
}
@@ -177,7 +177,7 @@ import sys, json
print(json.dumps({'body': sys.stdin.read()}))" 2>/dev/null)
HTTP=$(curl -sf -o /dev/null -w '%{http_code}' -X POST \
-H "Authorization: token ${MOKOGITEA_TOKEN}" \
-H "Authorization: token ${MOKOGIT_TOKEN}" \
-H "Content-Type: application/json" \
"${API}/issues/${EXISTING}/comments" \
-d "${COMMENT_JSON}" 2>/dev/null || echo "000")
@@ -199,7 +199,7 @@ print(json.dumps({
}))" "$TITLE" <<< "$ISSUE_BODY" 2>/dev/null)
RESPONSE=$(curl -sf -X POST \
-H "Authorization: token ${MOKOGITEA_TOKEN}" \
-H "Authorization: token ${MOKOGIT_TOKEN}" \
-H "Content-Type: application/json" \
"${API}/issues" \
-d "${ISSUE_JSON}" 2>/dev/null || echo "{}")
@@ -208,14 +208,14 @@ print(json.dumps({
if [[ -n "$ISSUE_NUM" ]]; then
LABEL_ID=$(curl -sf \
-H "Authorization: token ${MOKOGITEA_TOKEN}" \
-H "Authorization: token ${MOKOGIT_TOKEN}" \
"${API}/labels" 2>/dev/null \
| grep -oP "\"id\":\s*\K[0-9]+(?=[^}]*\"name\":\s*\"${LABEL_NAME}\")" \
| head -1 || true)
if [[ -n "$LABEL_ID" ]]; then
curl -sf -X POST \
-H "Authorization: token ${MOKOGITEA_TOKEN}" \
-H "Authorization: token ${MOKOGIT_TOKEN}" \
-H "Content-Type: application/json" \
"${API}/issues/${ISSUE_NUM}/labels" \
-d "{\"labels\":[${LABEL_ID}]}" \
+7 -7
View File
@@ -24,7 +24,7 @@ use MokoCli\CliFramework;
class ClientDashboardCli extends CliFramework
{
private string $giteaUrl = 'https://git.mokoconsulting.tech';
private string $gitUrl = 'https://git.mokoconsulting.tech';
private string $token = '';
private string $org = 'MokoConsulting';
private string $outputFile = '';
@@ -36,8 +36,8 @@ class ClientDashboardCli extends CliFramework
protected function configure(): void
{
$this->setDescription('Generate unified client dashboard HTML');
$this->addArgument('--token', 'Gitea token (or MOKOGITEA_TOKEN)', '');
$this->addArgument('--gitea-url', 'Gitea URL', 'https://git.mokoconsulting.tech');
$this->addArgument('--token', 'Git token (or MOKOGIT_TOKEN)', '');
$this->addArgument('--git-url', 'Git URL', 'https://git.mokoconsulting.tech');
$this->addArgument('--org', 'Primary org (default: MokoConsulting)', 'MokoConsulting');
$this->addArgument('--output', 'Output HTML file (default: stdout)', '');
$this->addArgument('-o', 'Output HTML file (alias)', '');
@@ -48,7 +48,7 @@ class ClientDashboardCli extends CliFramework
protected function run(): int
{
$this->giteaUrl = rtrim($this->getArgument('--gitea-url'), '/');
$this->gitUrl = rtrim($this->getArgument('--git-url'), '/');
$this->token = $this->getArgument('--token');
$this->org = $this->getArgument('--org');
$this->outputFile = $this->getArgument('--output') ?: $this->getArgument('-o');
@@ -57,11 +57,11 @@ class ClientDashboardCli extends CliFramework
$this->sslWarnDays = (int) $this->getArgument('--ssl-warn-days');
if ($this->token === '') {
$this->token = getenv('MOKOGITEA_TOKEN') ?: '';
$this->token = getenv('MOKOGIT_TOKEN') ?: '';
}
if ($this->token === '') {
$this->log('ERROR', '--token or MOKOGITEA_TOKEN required.');
$this->log('ERROR', '--token or MOKOGIT_TOKEN required.');
return 1;
}
@@ -460,7 +460,7 @@ CARD;
/** @return array{code: int, body: string} */
private function api(string $method, string $endpoint): array
{
$url = $this->giteaUrl . $endpoint;
$url = $this->gitUrl . $endpoint;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+6 -6
View File
@@ -24,21 +24,21 @@ use MokoCli\CliFramework;
class ClientInventoryCli extends CliFramework
{
private string $giteaUrl = 'https://git.mokoconsulting.tech';
private string $gitUrl = 'https://git.mokoconsulting.tech';
private string $token = '';
private bool $jsonOutput = false;
protected function configure(): void
{
$this->setDescription('Discover and list all client-waas repos with their server configuration status');
$this->addArgument('--gitea-url', 'Gitea URL (default: https://git.mokoconsulting.tech)', 'https://git.mokoconsulting.tech');
$this->addArgument('--token', 'Gitea API token', '');
$this->addArgument('--git-url', 'Git URL (default: https://git.mokoconsulting.tech)', 'https://git.mokoconsulting.tech');
$this->addArgument('--token', 'Git API token', '');
$this->addArgument('--json', 'Output results as JSON', false);
}
protected function run(): int
{
$this->giteaUrl = rtrim($this->getArgument('--gitea-url'), '/');
$this->gitUrl = rtrim($this->getArgument('--git-url'), '/');
$this->token = $this->getArgument('--token');
$this->jsonOutput = (bool) $this->getArgument('--json');
@@ -47,7 +47,7 @@ class ClientInventoryCli extends CliFramework
return 1;
}
$this->log('INFO', "Scanning Gitea instance: {$this->giteaUrl}");
$this->log('INFO', "Scanning Git instance: {$this->gitUrl}");
// Step 1: List all orgs
$orgs = $this->fetchOrgs();
@@ -241,7 +241,7 @@ class ClientInventoryCli extends CliFramework
private function apiRequest(string $method, string $endpoint, ?string $body = null): array
{
$url = $this->giteaUrl . $endpoint;
$url = $this->gitUrl . $endpoint;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
+18 -18
View File
@@ -24,8 +24,8 @@ use MokoCli\CliFramework;
class ClientProvisionCli extends CliFramework
{
private string $giteaUrl = 'https://git.mokoconsulting.tech';
private string $giteaToken = '';
private string $gitUrl = 'https://git.mokoconsulting.tech';
private string $gitToken = '';
private string $grafanaUrl = '';
private string $grafanaToken = '';
private string $configFile = '';
@@ -65,17 +65,17 @@ class ClientProvisionCli extends CliFramework
return 1;
}
$this->giteaToken = $this->config['gitea_token']
?? getenv('MOKOGITEA_TOKEN') ?: '';
$this->gitToken = $this->config['git_token']
?? getenv('MOKOGIT_TOKEN') ?: '';
$this->grafanaUrl = $this->config['grafana_url']
?? getenv('GRAFANA_URL') ?: '';
$this->grafanaToken = $this->config['grafana_token']
?? getenv('GRAFANA_TOKEN') ?: '';
$this->giteaUrl = $this->config['gitea_url']
?? $this->giteaUrl;
$this->gitUrl = $this->config['git_url']
?? $this->gitUrl;
if ($this->giteaToken === '') {
$this->log('ERROR', 'gitea_token or MOKOGITEA_TOKEN required.');
if ($this->gitToken === '') {
$this->log('ERROR', 'git_token or MOKOGIT_TOKEN required.');
return 1;
}
@@ -128,7 +128,7 @@ class ClientProvisionCli extends CliFramework
{
$this->log('INFO', '[1/5] Creating repository...');
$check = $this->giteaApi(
$check = $this->gitApi(
'GET',
"/api/v1/repos/{$this->org}/{$this->repoName}"
);
@@ -153,7 +153,7 @@ class ClientProvisionCli extends CliFramework
'labels' => true,
]);
$resp = $this->giteaApi(
$resp = $this->gitApi(
'POST',
'/api/v1/repos/MokoConsulting/'
. 'Template-Client/generate',
@@ -167,7 +167,7 @@ class ClientProvisionCli extends CliFramework
$this->log('INFO', ' OK: Repo created');
$this->giteaApi(
$this->gitApi(
'POST',
"/api/v1/repos/{$this->org}/{$this->repoName}/branches",
json_encode([
@@ -250,7 +250,7 @@ class ClientProvisionCli extends CliFramework
continue;
}
$resp = $this->giteaApi(
$resp = $this->gitApi(
'PUT',
"{$api}/{$name}",
json_encode(['data' => $value])
@@ -391,7 +391,7 @@ class ClientProvisionCli extends CliFramework
echo "\n";
$this->log('INFO', '[5/5] Provisioning summary');
echo str_repeat('=', 60) . "\n";
echo " Repo: {$this->giteaUrl}/{$this->org}/{$this->repoName}\n";
echo " Repo: {$this->gitUrl}/{$this->org}/{$this->repoName}\n";
echo ' Variables: ' . count($vars) . " set\n";
echo ' Secrets: ' . count($secrets) . " set\n";
echo "\n";
@@ -409,14 +409,14 @@ class ClientProvisionCli extends CliFramework
string $name,
string $value
): bool {
$resp = $this->giteaApi(
$resp = $this->gitApi(
'PUT',
"{$api}/{$name}",
json_encode(['value' => $value])
);
if ($resp['code'] === 404) {
$resp = $this->giteaApi(
$resp = $this->gitApi(
'POST',
$api,
json_encode(['name' => $name, 'value' => $value])
@@ -426,15 +426,15 @@ class ClientProvisionCli extends CliFramework
return $resp['code'] >= 200 && $resp['code'] < 300;
}
private function giteaApi(
private function gitApi(
string $method,
string $endpoint,
?string $body = null
): array {
return $this->httpRequest(
$this->giteaUrl . $endpoint,
$this->gitUrl . $endpoint,
$method,
"token {$this->giteaToken}",
"token {$this->gitToken}",
$body
);
}
+5 -5
View File
@@ -81,7 +81,7 @@ class CreateProjectCli extends CliFramework
}
$config = \MokoCli\Config::load();
$platformName = $config->getString('platform', 'gitea');
$platformName = $config->getString('platform', 'git');
try {
$adapter = \MokoCli\PlatformAdapterFactory::create($config);
$api = $adapter->getApiClient();
@@ -89,8 +89,8 @@ class CreateProjectCli extends CliFramework
$this->log('ERROR', "Platform initialization failed: " . $e->getMessage());
return 1;
}
$token = $platformName === 'gitea'
? $config->getString('gitea.token', '')
$token = $platformName === 'git'
? $config->getString('git.token', '')
: $config->getString('github.token', '');
$repoRoot = dirname(__DIR__, 2);
@@ -173,7 +173,7 @@ class CreateProjectCli extends CliFramework
return $failed > 0 ? 1 : 0;
}
private function graphql(string $query, array $variables, string $token, string $platformName = 'gitea'): array
private function graphql(string $query, array $variables, string $token, string $platformName = 'git'): array
{
if ($platformName !== 'github') {
return [];
@@ -223,7 +223,7 @@ class CreateProjectCli extends CliFramework
private function detectRepoPlatform(string $org, string $repo, string $token, ?\MokoCli\ApiClient $apiClient = null): string
{
foreach (['.github/.mokostandards', '.mokogitea/.mokostandards', '.mokostandards'] as $path) {
foreach (['.github/.mokostandards', '.mokogit/.mokostandards', '.mokostandards'] as $path) {
$data = $this->restGet("repos/{$org}/{$repo}/contents/{$path}", $token, $apiClient);
if (!empty($data['content'])) {
$content = base64_decode($data['content']);
+4 -4
View File
@@ -116,14 +116,14 @@ class CreateRepoCli extends CliFramework
echo " (dry-run) would set topics: " . implode(', ', $topics) . "\n";
}
echo "Step 3: Creating .mokogitea/manifest.xml...\n";
echo "Step 3: Creating .mokogit/manifest.xml...\n";
$mokoContent = "platform: {$platform}\nversion: 04.02.30\nmanaged: true\n";
if (!$this->dryRun) {
try {
$adapter->createOrUpdateFile(
$org,
$name,
'.mokogitea/manifest.xml',
'.mokogit/manifest.xml',
$mokoContent,
'chore: add manifest.xml platform config [skip ci]'
);
@@ -132,11 +132,11 @@ class CreateRepoCli extends CliFramework
echo " Warning: " . $e->getMessage() . "\n";
}
} else {
echo " (dry-run) would create .mokogitea/manifest.xml\n";
echo " (dry-run) would create .mokogit/manifest.xml\n";
}
echo "Step 4: Creating README.md...\n";
$baseUrl = $platformName === 'gitea' ? $config->getString('gitea.url', 'https://git.mokoconsulting.tech') : 'https://github.com';
$baseUrl = $platformName === 'git' ? $config->getString('git.url', 'https://git.mokoconsulting.tech') : 'https://github.com';
$repoUrl = "{$baseUrl}/{$org}/{$name}";
$standardsUrl = "{$baseUrl}/{$org}/MokoCli";
$readmeContent = "<!--\n"
+3 -3
View File
@@ -833,7 +833,7 @@ class DeployJoomla extends CliFramework
/**
* Resolve source directory with smart fallback chain:
* 1. --src-dir flag (explicit)
* 2. .mokogitea/manifest.xml <deploy><source-dir>
* 2. .mokogit/manifest.xml <deploy><source-dir>
* 3. src/ directory
* 4. htdocs/ directory
* 5. Repo root (for flat-layout extensions)
@@ -851,8 +851,8 @@ class DeployJoomla extends CliFramework
exit(1);
}
// 2. Read from .mokogitea/manifest.xml
$mokoManifest = "{$repoPath}/.mokogitea/manifest.xml";
// 2. Read from .mokogit/manifest.xml
$mokoManifest = "{$repoPath}/.mokogit/manifest.xml";
if (file_exists($mokoManifest)) {
$xml = @simplexml_load_file($mokoManifest);
if ($xml !== false) {
+5 -5
View File
@@ -10,7 +10,7 @@
* INGROUP: mokocli
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /cli/dev_branch_reset.php
* BRIEF: Delete and recreate dev branch from main via Gitea API
* BRIEF: Delete and recreate dev branch from main via Git API
*/
declare(strict_types=1);
@@ -23,9 +23,9 @@ class DevBranchResetCli extends CliFramework
{
protected function configure(): void
{
$this->setDescription('Delete and recreate dev branch from main via Gitea API');
$this->addArgument('--token', 'Gitea API token', '');
$this->addArgument('--api-base', 'Gitea API base URL', '');
$this->setDescription('Delete and recreate dev branch from main via Git API');
$this->addArgument('--token', 'Git API token', '');
$this->addArgument('--api-base', 'Git API base URL', '');
$this->addArgument('--branch', 'Branch to reset', 'dev');
$this->addArgument('--from', 'Source branch', 'main');
$this->addArgument('--output-summary', 'Write to $GITHUB_STEP_SUMMARY', false);
@@ -33,7 +33,7 @@ class DevBranchResetCli extends CliFramework
protected function run(): int
{
$token = $this->getArgument('--token') ?: getenv('MOKOGITEA_TOKEN') ?: getenv('GITEA_TOKEN') ?: '';
$token = $this->getArgument('--token') ?: getenv('MOKOGIT_TOKEN') ?: getenv('GIT_TOKEN') ?: '';
$apiBase = $this->getArgument('--api-base');
$branch = $this->getArgument('--branch');
$from = $this->getArgument('--from');
+13 -13
View File
@@ -11,7 +11,7 @@
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /cli/joomla_metadata_validate.php
* VERSION: 09.43.00
* BRIEF: Validate MokoGitea repo metadata against Joomla extension manifest XML
* BRIEF: Validate MokoGit repo metadata against Joomla extension manifest XML
*/
declare(strict_types=1);
@@ -22,7 +22,7 @@ use MokoCli\CliFramework;
class JoomlaMetadataValidateCli extends CliFramework
{
/** Joomla element prefix map — must match MokoGitea's cleanJoomlaElement() */
/** Joomla element prefix map — must match MokoGit's cleanJoomlaElement() */
private const JOOMLA_PREFIX = [
'package' => 'pkg_',
'component' => 'com_',
@@ -34,12 +34,12 @@ class JoomlaMetadataValidateCli extends CliFramework
protected function configure(): void
{
$this->setDescription('Validate MokoGitea repo metadata against Joomla extension manifest XML');
$this->setDescription('Validate MokoGit repo metadata against Joomla extension manifest XML');
$this->addArgument('--path', 'Repo root path (default: current directory)', '.');
$this->addArgument('--token', 'Gitea API token (or GITEA_TOKEN env)', '');
$this->addArgument('--org', 'Gitea org', 'MokoConsulting');
$this->addArgument('--token', 'Git API token (or GIT_TOKEN env)', '');
$this->addArgument('--org', 'Git org', 'MokoConsulting');
$this->addArgument('--repo', 'Repo name (auto-detected from git if empty)', '');
$this->addArgument('--api-base', 'Gitea API base URL', 'https://git.mokoconsulting.tech/api/v1');
$this->addArgument('--api-base', 'Git API base URL', 'https://git.mokoconsulting.tech/api/v1');
$this->addArgument('--ci', 'CI mode: exit 1 on any error', false);
$this->addArgument('--json', 'Output as JSON', false);
}
@@ -47,7 +47,7 @@ class JoomlaMetadataValidateCli extends CliFramework
protected function run(): int
{
$path = realpath($this->getArgument('--path')) ?: $this->getArgument('--path');
$token = $this->getArgument('--token') ?: getenv('GITEA_TOKEN') ?: '';
$token = $this->getArgument('--token') ?: getenv('GIT_TOKEN') ?: '';
$org = $this->getArgument('--org');
$repoName = $this->getArgument('--repo');
$apiBase = rtrim($this->getArgument('--api-base'), '/');
@@ -73,11 +73,11 @@ class JoomlaMetadataValidateCli extends CliFramework
$this->log('INFO', "Joomla manifest: {$joomlaXml['path']}");
// ── Step 2: Load MokoGitea metadata ─────────────────────────
// ── Step 2: Load MokoGit metadata ─────────────────────────
$metadata = $this->loadMetadata($path, $org, $repoName, $token, $apiBase);
if ($metadata === null) {
$this->log('ERROR', 'Could not load MokoGitea metadata');
$this->log('ERROR', 'Could not load MokoGit metadata');
return 1;
}
@@ -174,7 +174,7 @@ class JoomlaMetadataValidateCli extends CliFramework
private function loadMetadata(string $root, string $org, string $repoName, string $token, string $apiBase): ?array
{
if ($token === '') {
$this->log('ERROR', 'No API token provided (use --token or set GITEA_TOKEN env var)');
$this->log('ERROR', 'No API token provided (use --token or set GIT_TOKEN env var)');
return null;
}
@@ -202,7 +202,7 @@ class JoomlaMetadataValidateCli extends CliFramework
if ($httpCode === 404) {
$this->log('ERROR', "API endpoint not found: {$url}");
$this->log('ERROR', 'Server may need MokoGitea-Fork >= #650 (metadata endpoint rename)');
$this->log('ERROR', 'Server may need MokoGit-Fork >= #650 (metadata endpoint rename)');
return null;
}
@@ -328,7 +328,7 @@ class JoomlaMetadataValidateCli extends CliFramework
// =================================================================
/**
* Normalize extension_type — map MokoGitea types to Joomla types.
* Normalize extension_type — map MokoGit types to Joomla types.
*/
private function normalizeExtensionType(string $type): string
{
@@ -340,7 +340,7 @@ class JoomlaMetadataValidateCli extends CliFramework
/**
* Derive the Joomla element name from type + name.
* Replicates MokoGitea's cleanJoomlaElement() + prefix logic.
* Replicates MokoGit's cleanJoomlaElement() + prefix logic.
*/
private function deriveElement(string $type, string $name): string
{
+9 -9
View File
@@ -30,7 +30,7 @@ use MokoCli\{ApiClient, AuditLogger, CliFramework, Config, PlatformAdapterFactor
/**
* Joomla Release Manager
*
* Creates and manages Joomla extension releases on Gitea, including
* Creates and manages Joomla extension releases on Git, including
* package building, asset upload, and update stream management.
*
* @since 04.06.00
@@ -425,9 +425,9 @@ class JoomlaRelease extends CliFramework
}
$releaseConfig = Config::load();
$releasePlatform = $releaseConfig->getString('platform', 'gitea');
$releaseToken = $releasePlatform === 'gitea'
? $releaseConfig->getString('gitea.token', '')
$releasePlatform = $releaseConfig->getString('platform', 'git');
$releaseToken = $releasePlatform === 'git'
? $releaseConfig->getString('git.token', '')
: $releaseConfig->getString('github.token', '');
$acceptHeader = $releasePlatform === 'github' ? 'application/vnd.github+json' : 'application/json';
$ch = curl_init();
@@ -512,12 +512,12 @@ class JoomlaRelease extends CliFramework
$this->rmdir($tmpDir);
}
$config = Config::load();
$platform = $config->getString('platform', 'gitea');
$token = $platform === 'gitea'
? $config->getString('gitea.token', '')
$platform = $config->getString('platform', 'git');
$token = $platform === 'git'
? $config->getString('git.token', '')
: $config->getString('github.token', '');
$cloneHost = $platform === 'gitea'
? rtrim($config->getString('gitea.url', 'https://git.mokoconsulting.tech'), '/')
$cloneHost = $platform === 'git'
? rtrim($config->getString('git.url', 'https://git.mokoconsulting.tech'), '/')
: 'https://github.com';
$url = "https://x-access-token:{$token}@" . preg_replace('#^https?://#', '', $cloneHost) . '/' . self::ORG . "/{$repo}.git";
$cmd = ['git', 'clone', '--depth', '1', '--quiet', $url, $tmpDir];
+5 -5
View File
@@ -10,7 +10,7 @@
* INGROUP: mokocli
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /cli/license_manage.php
* BRIEF: Manage license packages and keys via MokoGitea licensing API
* BRIEF: Manage license packages and keys via MokoGit licensing API
*
* Usage:
* php bin/moko license:list --org MokoConsulting
@@ -38,9 +38,9 @@ class LicenseManage extends CliFramework
protected function configure(): void
{
$this->setDescription('Manage license packages and keys via MokoGitea licensing API');
$this->setDescription('Manage license packages and keys via MokoGit licensing API');
$this->addArgument('--org', 'Organization name', '');
$this->addArgument('--api-base', 'Gitea API base URL', '');
$this->addArgument('--api-base', 'Git API base URL', '');
$this->addArgument('--token', 'API token (or set GH_TOKEN env)', '');
// Package args
@@ -71,7 +71,7 @@ class LicenseManage extends CliFramework
{
// Resolve API base
$this->apiBase = $this->getArgument('--api-base')
?: getenv('GITEA_URL')
?: getenv('GIT_URL')
?: 'https://git.mokoconsulting.tech';
$this->apiBase = rtrim($this->apiBase, '/');
@@ -657,7 +657,7 @@ HELP;
if ($httpCode === 404) {
$this->log("API endpoint not found: {$path}", 'ERROR');
$this->log('The licensing API may not be deployed yet. Check MokoGitea version.', 'WARN');
$this->log('The licensing API may not be deployed yet. Check MokoGit version.', 'WARN');
return null;
}
+6 -6
View File
@@ -29,10 +29,10 @@ class ManifestDetectCli extends CliFramework
$this->addArgument('--json', 'Output as JSON', false);
$this->addArgument('--diff', 'Show diff against current manifest API values', false);
$this->addArgument('--update', 'Push detected fields to manifest API', false);
$this->addArgument('--token', 'Gitea API token (or GITEA_TOKEN env)', '');
$this->addArgument('--api-base', 'Gitea API base URL', 'https://git.mokoconsulting.tech/api/v1');
$this->addArgument('--org', 'Gitea org', 'MokoConsulting');
$this->addArgument('--repo', 'Gitea repo name (auto-detected from remote if empty)', '');
$this->addArgument('--token', 'Git API token (or GIT_TOKEN env)', '');
$this->addArgument('--api-base', 'Git API base URL', 'https://git.mokoconsulting.tech/api/v1');
$this->addArgument('--org', 'Git org', 'MokoConsulting');
$this->addArgument('--repo', 'Git repo name (auto-detected from remote if empty)', '');
$this->addArgument('--github-output', 'Append fields to $GITHUB_OUTPUT', false);
}
@@ -43,7 +43,7 @@ class ManifestDetectCli extends CliFramework
$diffMode = (bool) $this->getArgument('--diff');
$updateMode = (bool) $this->getArgument('--update');
$ghOutput = (bool) $this->getArgument('--github-output');
$token = $this->getArgument('--token') ?: getenv('GITEA_TOKEN') ?: '';
$token = $this->getArgument('--token') ?: getenv('GIT_TOKEN') ?: '';
$apiBase = rtrim($this->getArgument('--api-base'), '/');
$org = $this->getArgument('--org');
$repoName = $this->getArgument('--repo');
@@ -74,7 +74,7 @@ class ManifestDetectCli extends CliFramework
// ── Output ──────────────────────────────────────────────────
if ($diffMode || $updateMode) {
if ($token === '') {
$this->log('ERROR', 'API token required for --diff/--update (use --token or GITEA_TOKEN env)');
$this->log('ERROR', 'API token required for --diff/--update (use --token or GIT_TOKEN env)');
return 1;
}
if ($repoName === '') {
+1 -1
View File
@@ -40,7 +40,7 @@ class ManifestElementCli extends CliFramework
$githubOutput = (bool) $this->getArgument('--github-output');
$root = realpath($path) ?: $path;
$platform = 'generic';
$manifestXml = "{$root}/.mokogitea/manifest.xml";
$manifestXml = "{$root}/.mokogit/manifest.xml";
if (file_exists($manifestXml)) {
$content = file_get_contents($manifestXml);
if (preg_match('/<platform>([^<]+)<\/platform>/', $content, $pm)) {
+5 -5
View File
@@ -26,10 +26,10 @@ class ManifestIntegrityCli extends CliFramework
{
$this->setDescription('Cross-check manifest fields against repo contents across the org');
$this->addArgument('--path', 'Single repo path (local mode)', '');
$this->addArgument('--org', 'Gitea org (bulk mode)', 'MokoConsulting');
$this->addArgument('--org', 'Git org (bulk mode)', 'MokoConsulting');
$this->addArgument('--repo', 'Single repo name (remote mode)', '');
$this->addArgument('--token', 'Gitea API token (or GITEA_TOKEN env)', '');
$this->addArgument('--api-base', 'Gitea API base URL', 'https://git.mokoconsulting.tech/api/v1');
$this->addArgument('--token', 'Git API token (or GIT_TOKEN env)', '');
$this->addArgument('--api-base', 'Git API base URL', 'https://git.mokoconsulting.tech/api/v1');
$this->addArgument('--fix', 'Push fixes for detected drift', false);
$this->addArgument('--json', 'Output as JSON', false);
$this->addArgument('--quiet', 'Only show repos with issues', false);
@@ -40,14 +40,14 @@ class ManifestIntegrityCli extends CliFramework
$path = $this->getArgument('--path');
$org = $this->getArgument('--org');
$repoName = $this->getArgument('--repo');
$token = $this->getArgument('--token') ?: getenv('GITEA_TOKEN') ?: '';
$token = $this->getArgument('--token') ?: getenv('GIT_TOKEN') ?: '';
$apiBase = rtrim($this->getArgument('--api-base'), '/');
$fixMode = (bool) $this->getArgument('--fix');
$jsonMode = (bool) $this->getArgument('--json');
$quiet = (bool) $this->getArgument('--quiet');
if ($token === '') {
$this->log('ERROR', 'API token required (use --token or GITEA_TOKEN env)');
$this->log('ERROR', 'API token required (use --token or GIT_TOKEN env)');
return 1;
}
+2 -2
View File
@@ -21,7 +21,7 @@ require_once __DIR__ . '/../lib/Enterprise/CliFramework.php';
use MokoCli\{CliFramework, SourceResolver};
/**
* Reads the <licensing> block from .mokogitea/manifest.xml and ensures that the
* Reads the <licensing> block from .mokogit/manifest.xml and ensures that the
* Joomla extension manifest contains the correct <updateservers> and <dlid> tags.
*
* manifest.xml licensing block example:
@@ -53,7 +53,7 @@ class ManifestLicensingCli extends CliFramework
$ghOutput = (bool) $this->getArgument('--github-output');
// ── 1. Read manifest.xml ──────────────────────────────────────────
$manifestFile = "{$root}/.mokogitea/manifest.xml";
$manifestFile = "{$root}/.mokogit/manifest.xml";
if (!file_exists($manifestFile)) {
$this->log('WARN', "No manifest.xml found at {$manifestFile}");
+9 -9
View File
@@ -11,7 +11,7 @@
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /cli/manifest_read.php
* VERSION: 09.43.00
* BRIEF: Read repo metadata from Gitea manifest API, auto-detect the rest
* BRIEF: Read repo metadata from Git manifest API, auto-detect the rest
*/
declare(strict_types=1);
@@ -27,7 +27,7 @@ class ManifestReadCli extends CliFramework
protected function configure(): void
{
$this->setDescription('Read repo metadata from Gitea API with auto-detection fallback');
$this->setDescription('Read repo metadata from Git API with auto-detection fallback');
$this->addArgument('--path', 'Repository root path', '.');
$this->addArgument('--field', 'Single field name to output', '');
$this->addArgument('--all', 'Print all fields as KEY=VALUE lines', false);
@@ -55,7 +55,7 @@ class ManifestReadCli extends CliFramework
// ── 1. Resolve org/repo ──────────────────────────────────────────
[$org, $repo] = $this->resolveOrgRepo($root);
// ── 2. Primary: Gitea manifest API ───────────────────────────────
// ── 2. Primary: Git manifest API ───────────────────────────────
$fields = null;
if ($org !== '' && $repo !== '') {
$fields = $this->fetchFromApi($org, $repo);
@@ -82,12 +82,12 @@ class ManifestReadCli extends CliFramework
return $this->outputFields($fields, $mode, $field);
}
// ── Gitea manifest API ───────────────────────────────────────────────
// ── Git manifest API ───────────────────────────────────────────────
private function fetchFromApi(string $org, string $repo): ?array
{
$token = getenv('GA_TOKEN') ?: getenv('GITEA_TOKEN') ?: '';
$baseUrl = getenv('GITEA_URL') ?: 'https://git.mokoconsulting.tech';
$token = getenv('GA_TOKEN') ?: getenv('GIT_TOKEN') ?: '';
$baseUrl = getenv('GIT_URL') ?: 'https://git.mokoconsulting.tech';
$baseUrl = rtrim($baseUrl, '/');
if ($token === '') {
@@ -123,7 +123,7 @@ class ManifestReadCli extends CliFramework
return null;
}
$this->log('INFO', "Loaded metadata from Gitea manifest API ({$org}/{$repo})");
$this->log('INFO', "Loaded metadata from Git manifest API ({$org}/{$repo})");
return $data;
}
@@ -370,7 +370,7 @@ class ManifestReadCli extends CliFramework
*/
private function resolveOrgRepo(string $root): array
{
// 1. GITHUB_REPOSITORY env (set in Gitea Actions / GitHub Actions)
// 1. GITHUB_REPOSITORY env (set in Git Actions / GitHub Actions)
$envRepo = getenv('GITHUB_REPOSITORY') ?: '';
if ($envRepo !== '' && str_contains($envRepo, '/')) {
return explode('/', $envRepo, 2);
@@ -447,7 +447,7 @@ class ManifestReadCli extends CliFramework
break;
case 'github-output':
$outputFile = getenv('GITHUB_OUTPUT') ?: getenv('GITEA_OUTPUT') ?: '';
$outputFile = getenv('GITHUB_OUTPUT') ?: getenv('GIT_OUTPUT') ?: '';
$lines = [];
foreach ($fields as $k => $v) {
$envKey = str_replace('-', '_', $k);
+7 -7
View File
@@ -26,8 +26,8 @@ class PlatformDetectCli extends CliFramework
{
$this->setDescription('Auto-detect repository platform type and optionally update manifest');
$this->addArgument('--path', 'Local repo path to scan (default: .)', '.');
$this->addArgument('--token', 'Gitea API token for updating manifest', '');
$this->addArgument('--gitea-url', 'Gitea URL (default: https://git.mokoconsulting.tech)', 'https://git.mokoconsulting.tech');
$this->addArgument('--token', 'Git API token for updating manifest', '');
$this->addArgument('--git-url', 'Git URL (default: https://git.mokoconsulting.tech)', 'https://git.mokoconsulting.tech');
$this->addArgument('--owner', 'Repo owner for API update', '');
$this->addArgument('--repo', 'Repo name for API update', '');
$this->addArgument('--update', 'Update manifest.platform via API (flag)', 'false');
@@ -40,7 +40,7 @@ class PlatformDetectCli extends CliFramework
$root = realpath($path) ?: $path;
$token = $this->getArgument('--token');
$giteaUrl = rtrim($this->getArgument('--gitea-url'), '/');
$gitUrl = rtrim($this->getArgument('--git-url'), '/');
$owner = $this->getArgument('--owner');
$repo = $this->getArgument('--repo');
$doUpdate = $this->isFlagSet('--update');
@@ -79,7 +79,7 @@ class PlatformDetectCli extends CliFramework
$this->log('INFO', "Updating manifest.platform for {$owner}/{$repo} to \"{$platform}\"...");
$response = $this->apiRequest(
$giteaUrl,
$gitUrl,
$token,
'PATCH',
"/api/v1/repos/{$owner}/{$repo}/metadata",
@@ -136,7 +136,7 @@ class PlatformDetectCli extends CliFramework
// 5. Platform — is mokocli itself or org-config
$repoName = basename($root);
if (in_array($repoName, ['mokocli', 'mokogitea-org-config'])) {
if (in_array($repoName, ['mokocli', 'mokogit-org-config'])) {
return 'platform';
}
@@ -152,13 +152,13 @@ class PlatformDetectCli extends CliFramework
}
private function apiRequest(
string $giteaUrl,
string $gitUrl,
string $token,
string $method,
string $endpoint,
?string $body = null
): array {
$url = $giteaUrl . $endpoint;
$url = $gitUrl . $endpoint;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
+2 -2
View File
@@ -37,8 +37,8 @@ class ReleaseCli extends CliFramework
$repoRoot = dirname(__DIR__, 2);
$syncFile = "{$repoRoot}/lib/Enterprise/RepositorySynchronizer.php";
// Check both workflow directories for the bulk-repo-sync workflow
$bulkSyncFile = file_exists("{$repoRoot}/.mokogitea/workflows/bulk-repo-sync.yml")
? "{$repoRoot}/.mokogitea/workflows/bulk-repo-sync.yml"
$bulkSyncFile = file_exists("{$repoRoot}/.mokogit/workflows/bulk-repo-sync.yml")
? "{$repoRoot}/.mokogit/workflows/bulk-repo-sync.yml"
: "{$repoRoot}/.github/workflows/bulk-repo-sync.yml";
// -- Step 1: Read current version --
+6 -6
View File
@@ -10,7 +10,7 @@
* INGROUP: mokocli
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /cli/release_body_update.php
* BRIEF: Update Gitea release body with changelog extract and checksums
* BRIEF: Update Git release body with changelog extract and checksums
*/
declare(strict_types=1);
@@ -23,12 +23,12 @@ class ReleaseBodyUpdateCli extends CliFramework
{
protected function configure(): void
{
$this->setDescription('Update Gitea release body with changelog extract and checksums');
$this->setDescription('Update Git release body with changelog extract and checksums');
$this->addArgument('--path', 'Repo root for CHANGELOG.md', '.');
$this->addArgument('--version', 'Version string', '');
$this->addArgument('--release-tag', 'Gitea release tag', '');
$this->addArgument('--token', 'Gitea API token', '');
$this->addArgument('--api-base', 'Gitea API base URL', '');
$this->addArgument('--release-tag', 'Git release tag', '');
$this->addArgument('--token', 'Git API token', '');
$this->addArgument('--api-base', 'Git API base URL', '');
$this->addArgument('--zip-name', 'ZIP filename for checksum table', '');
$this->addArgument('--tar-name', 'tar.gz filename for checksum table', '');
$this->addArgument('--zip-sha', 'SHA256 of ZIP', '');
@@ -50,7 +50,7 @@ class ReleaseBodyUpdateCli extends CliFramework
$outputSummary = $this->getArgument('--output-summary');
if (empty($token)) {
$token = getenv('MOKOGITEA_TOKEN') ?: getenv('GITEA_TOKEN') ?: '';
$token = getenv('MOKOGIT_TOKEN') ?: getenv('GIT_TOKEN') ?: '';
}
if (empty($version) || empty($releaseTag) || empty($token) || empty($apiBase)) {
+11 -11
View File
@@ -40,8 +40,8 @@ class ReleaseCascadeCli extends CliFramework
{
$this->setDescription('Cascade release zip to all lower stability channels');
$this->addArgument('--stability', 'Source stability channel (required)', '');
$this->addArgument('--token', 'Gitea API token (required)', '');
$this->addArgument('--api-base', 'Gitea API base URL for the repo (required)', '');
$this->addArgument('--token', 'Git API token (required)', '');
$this->addArgument('--api-base', 'Git API base URL for the repo (required)', '');
}
protected function run(): int
@@ -51,9 +51,9 @@ class ReleaseCascadeCli extends CliFramework
$apiBase = rtrim($this->getArgument('--api-base'), '/');
if ($token === '') {
$envToken = getenv('MOKOGITEA_TOKEN');
$envToken = getenv('MOKOGIT_TOKEN');
if ($envToken === false || $envToken === '') {
$envToken = getenv('GITEA_TOKEN');
$envToken = getenv('GIT_TOKEN');
}
if ($envToken !== false && $envToken !== '') {
$token = $envToken;
@@ -85,7 +85,7 @@ class ReleaseCascadeCli extends CliFramework
}
// 1. Get source release
$sourceRelease = $this->giteaApi("{$apiBase}/releases/tags/{$sourceTag}", $token);
$sourceRelease = $this->gitApi("{$apiBase}/releases/tags/{$sourceTag}", $token);
if ($sourceRelease === null) {
$this->log('WARN', "No release found at tag '{$sourceTag}' — nothing to cascade.");
return 0;
@@ -179,7 +179,7 @@ class ReleaseCascadeCli extends CliFramework
}
// Find existing release at target tag
$existing = $this->giteaApi("{$apiBase}/releases/tags/{$targetTag}", $token);
$existing = $this->gitApi("{$apiBase}/releases/tags/{$targetTag}", $token);
if ($existing !== null && !empty($existing['id'])) {
$releaseId = (int) $existing['id'];
@@ -189,7 +189,7 @@ class ReleaseCascadeCli extends CliFramework
foreach ($existingAssets as $asset) {
$assetId = $asset['id'] ?? 0;
if ($assetId > 0) {
$this->giteaApi(
$this->gitApi(
"{$apiBase}/releases/{$releaseId}/assets/{$assetId}",
$token, 'DELETE'
);
@@ -201,7 +201,7 @@ class ReleaseCascadeCli extends CliFramework
'name' => $sourceVersion,
'body' => $sourceBody,
]);
$this->giteaApi(
$this->gitApi(
"{$apiBase}/releases/{$releaseId}",
$token, 'PATCH', $updatePayload
);
@@ -217,7 +217,7 @@ class ReleaseCascadeCli extends CliFramework
'body' => $sourceBody,
'prerelease' => ($targetTag !== 'stable'),
]);
$newRelease = $this->giteaApi("{$apiBase}/releases", $token, 'POST', $createPayload);
$newRelease = $this->gitApi("{$apiBase}/releases", $token, 'POST', $createPayload);
if ($newRelease === null || empty($newRelease['id'])) {
$this->log('ERROR', " Failed to create release at tag '{$targetTag}'");
return false;
@@ -302,9 +302,9 @@ class ReleaseCascadeCli extends CliFramework
}
/**
* Make an HTTP request to the Gitea API.
* Make an HTTP request to the Git API.
*/
private function giteaApi(
private function gitApi(
string $url,
string $token,
string $method = 'GET',
+13 -13
View File
@@ -10,7 +10,7 @@
* INGROUP: mokocli
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /cli/release_create.php
* BRIEF: Create or overwrite a Gitea release with proper naming
* BRIEF: Create or overwrite a Git release with proper naming
*/
declare(strict_types=1);
@@ -23,12 +23,12 @@ class ReleaseCreateCli extends CliFramework
{
protected function configure(): void
{
$this->setDescription('Create or overwrite a Gitea release with proper naming');
$this->setDescription('Create or overwrite a Git release with proper naming');
$this->addArgument('--path', 'Repo root for manifest detection (default: .)', '.');
$this->addArgument('--version', 'Version string (required)', '');
$this->addArgument('--tag', 'Release tag name (required)', '');
$this->addArgument('--token', 'Gitea API token (required)', '');
$this->addArgument('--api-base', 'Gitea API base URL for the repo (required)', '');
$this->addArgument('--token', 'Git API token (required)', '');
$this->addArgument('--api-base', 'Git API base URL for the repo (required)', '');
$this->addArgument('--branch', 'Target commitish (default: main)', 'main');
$this->addArgument('--repo', 'Repo name for fallback element detection', '');
$this->addArgument('--prerelease', 'Mark release as prerelease', false);
@@ -47,9 +47,9 @@ class ReleaseCreateCli extends CliFramework
// Allow token from environment
if ($token === '') {
$envToken = getenv('MOKOGITEA_TOKEN');
$envToken = getenv('MOKOGIT_TOKEN');
if ($envToken === false || $envToken === '') {
$envToken = getenv('GITEA_TOKEN');
$envToken = getenv('GIT_TOKEN');
}
if ($envToken !== false && $envToken !== '') {
$token = $envToken;
@@ -62,7 +62,7 @@ class ReleaseCreateCli extends CliFramework
$this->log('ERROR', " --branch main Target commitish (default: main)");
$this->log('ERROR', " --repo REPO Repo name for fallback element detection");
$this->log('ERROR', " --prerelease Mark release as prerelease");
$this->log('ERROR', " Token can also be set via MOKOGITEA_TOKEN or GITEA_TOKEN env var");
$this->log('ERROR', " Token can also be set via MOKOGIT_TOKEN or GIT_TOKEN env var");
return 1;
}
@@ -79,7 +79,7 @@ class ReleaseCreateCli extends CliFramework
// Detect platform and display name from manifest.xml
$platform = 'generic';
$prettyName = '';
$manifestXml = "{$root}/.mokogitea/manifest.xml";
$manifestXml = "{$root}/.mokogit/manifest.xml";
if (file_exists($manifestXml)) {
$content = file_get_contents($manifestXml);
if ($content !== false) {
@@ -238,16 +238,16 @@ class ReleaseCreateCli extends CliFramework
// ── Delete existing release at tag (if present) ─────────────────────────────
$existing = $this->giteaApi("{$apiBase}/releases/tags/{$tag}", $token);
$existing = $this->gitApi("{$apiBase}/releases/tags/{$tag}", $token);
if ($existing !== null && !empty($existing['id'])) {
$existingId = $existing['id'];
echo "Deleting existing release: {$tag} (id: {$existingId})\n";
// Delete release
$this->giteaApi("{$apiBase}/releases/{$existingId}", $token, 'DELETE');
$this->gitApi("{$apiBase}/releases/{$existingId}", $token, 'DELETE');
// Delete tag
$this->giteaApi("{$apiBase}/tags/{$tag}", $token, 'DELETE');
$this->gitApi("{$apiBase}/tags/{$tag}", $token, 'DELETE');
}
// ── Create new release ──────────────────────────────────────────────────────
@@ -260,7 +260,7 @@ class ReleaseCreateCli extends CliFramework
'prerelease' => $prerelease,
]);
$newRelease = $this->giteaApi("{$apiBase}/releases", $token, 'POST', $payload !== false ? $payload : '{}');
$newRelease = $this->gitApi("{$apiBase}/releases", $token, 'POST', $payload !== false ? $payload : '{}');
if ($newRelease === null || empty($newRelease['id'])) {
$this->log('ERROR', "Failed to create release at tag: {$tag}");
return 1;
@@ -274,7 +274,7 @@ class ReleaseCreateCli extends CliFramework
return 0;
}
private function giteaApi(string $url, string $token, string $method = 'GET', ?string $body = null): ?array
private function gitApi(string $url, string $token, string $method = 'GET', ?string $body = null): ?array
{
$ch = curl_init($url);
if ($ch === false) {
+16 -16
View File
@@ -10,7 +10,7 @@
* INGROUP: mokocli
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /cli/release_manage.php
* BRIEF: Create/update Gitea releases, upload assets, update release body
* BRIEF: Create/update Git releases, upload assets, update release body
*/
declare(strict_types=1);
@@ -23,7 +23,7 @@ class ReleaseManageCli extends CliFramework
{
protected function configure(): void
{
$this->setDescription('Create/update Gitea releases, upload assets, update release body');
$this->setDescription('Create/update Git releases, upload assets, update release body');
$this->addArgument('--action', 'create | upload | update-body | delete', null);
$this->addArgument('--tag', 'Release tag name', null);
$this->addArgument('--name', 'Release name/title', null);
@@ -31,8 +31,8 @@ class ReleaseManageCli extends CliFramework
$this->addArgument('--body-file', 'Read body from file', null);
$this->addArgument('--target', 'Target branch/commitish', 'main');
$this->addArgument('--files', 'Comma-separated file paths to upload', null);
$this->addArgument('--token', 'Gitea API token', null);
$this->addArgument('--api-base', 'Gitea API base URL', null);
$this->addArgument('--token', 'Git API token', null);
$this->addArgument('--api-base', 'Git API base URL', null);
}
protected function run(): int
@@ -48,7 +48,7 @@ class ReleaseManageCli extends CliFramework
$apiBase = $this->getArgument('--api-base');
$files = $filesArg !== null ? array_filter(explode(',', $filesArg)) : [];
if ($token === null) {
$token = getenv('MOKOGITEA_TOKEN') ?: getenv('GITEA_TOKEN') ?: null;
$token = getenv('MOKOGIT_TOKEN') ?: getenv('GIT_TOKEN') ?: null;
}
if ($bodyFile !== null && file_exists($bodyFile)) {
$body = file_get_contents($bodyFile);
@@ -62,12 +62,12 @@ class ReleaseManageCli extends CliFramework
$existing = $this->getReleaseByTag($apiBase, $tag, $token);
if ($existing !== null) {
$existingId = $existing['id'];
$this->releaseGiteaApi("{$apiBase}/releases/{$existingId}", 'DELETE', $token);
$this->releaseGiteaApi("{$apiBase}/tags/{$tag}", 'DELETE', $token);
$this->releaseGitApi("{$apiBase}/releases/{$existingId}", 'DELETE', $token);
$this->releaseGitApi("{$apiBase}/tags/{$tag}", 'DELETE', $token);
echo "Deleted previous release: {$tag} (id: {$existingId})\n";
}
$payload = json_encode(['tag_name' => $tag, 'name' => $name ?? $tag, 'body' => $body ?? '', 'target_commitish' => $target]);
$result = $this->releaseGiteaApi("{$apiBase}/releases", 'POST', $token, $payload);
$result = $this->releaseGitApi("{$apiBase}/releases", 'POST', $token, $payload);
if ($result['code'] >= 200 && $result['code'] < 300) {
$releaseId = $result['data']['id'] ?? 'unknown';
echo "Release created: {$name} (tag: {$tag}, id: {$releaseId})\n";
@@ -87,7 +87,7 @@ class ReleaseManageCli extends CliFramework
return 1;
}
$releaseId = $release['id'];
$assetsResult = $this->releaseGiteaApi("{$apiBase}/releases/{$releaseId}/assets", 'GET', $token);
$assetsResult = $this->releaseGitApi("{$apiBase}/releases/{$releaseId}/assets", 'GET', $token);
$existingAssets = $assetsResult['data'] ?? [];
foreach ($files as $filePath) {
$filePath = trim($filePath);
@@ -98,13 +98,13 @@ class ReleaseManageCli extends CliFramework
$fileName = basename($filePath);
foreach ($existingAssets as $asset) {
if (($asset['name'] ?? '') === $fileName) {
$this->releaseGiteaApi("{$apiBase}/releases/{$releaseId}/assets/{$asset['id']}", 'DELETE', $token);
$this->releaseGitApi("{$apiBase}/releases/{$releaseId}/assets/{$asset['id']}", 'DELETE', $token);
echo "Deleted existing asset: {$fileName}\n";
break;
}
}
$uploadUrl = "{$apiBase}/releases/{$releaseId}/assets?name=" . urlencode($fileName);
$result = $this->releaseGiteaApi($uploadUrl, 'POST', $token, null, $filePath);
$result = $this->releaseGitApi($uploadUrl, 'POST', $token, null, $filePath);
if ($result['code'] >= 200 && $result['code'] < 300) {
echo "Uploaded: {$fileName}\n";
} else {
@@ -119,7 +119,7 @@ class ReleaseManageCli extends CliFramework
return 1;
}
$payload = json_encode(['body' => $body ?? '']);
$result = $this->releaseGiteaApi("{$apiBase}/releases/{$release['id']}", 'PATCH', $token, $payload);
$result = $this->releaseGitApi("{$apiBase}/releases/{$release['id']}", 'PATCH', $token, $payload);
if ($result['code'] >= 200 && $result['code'] < 300) {
echo "Release body updated for tag: {$tag}\n";
} else {
@@ -130,8 +130,8 @@ class ReleaseManageCli extends CliFramework
case 'delete':
$existing = $this->getReleaseByTag($apiBase, $tag, $token);
if ($existing !== null) {
$this->releaseGiteaApi("{$apiBase}/releases/{$existing['id']}", 'DELETE', $token);
$this->releaseGiteaApi("{$apiBase}/tags/{$tag}", 'DELETE', $token);
$this->releaseGitApi("{$apiBase}/releases/{$existing['id']}", 'DELETE', $token);
$this->releaseGitApi("{$apiBase}/tags/{$tag}", 'DELETE', $token);
echo "Deleted: {$tag} (id: {$existing['id']})\n";
} else {
echo "No release found for tag: {$tag}\n";
@@ -144,7 +144,7 @@ class ReleaseManageCli extends CliFramework
return 0;
}
private function releaseGiteaApi(string $url, string $method, string $token, ?string $jsonBody = null, ?string $filePath = null): array
private function releaseGitApi(string $url, string $method, string $token, ?string $jsonBody = null, ?string $filePath = null): array
{
$ch = curl_init($url);
$headers = ["Authorization: token {$token}"];
@@ -166,7 +166,7 @@ class ReleaseManageCli extends CliFramework
private function getReleaseByTag(string $apiBase, string $tag, string $token): ?array
{
$result = $this->releaseGiteaApi("{$apiBase}/releases/tags/{$tag}", 'GET', $token);
$result = $this->releaseGitApi("{$apiBase}/releases/tags/{$tag}", 'GET', $token);
return ($result['code'] === 200 && isset($result['data']['id'])) ? $result['data'] : null;
}
}
+19 -19
View File
@@ -10,7 +10,7 @@
* INGROUP: mokocli
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /cli/release_mirror.php
* BRIEF: Mirror a Gitea release (with assets) to a GitHub repository
* BRIEF: Mirror a Git release (with assets) to a GitHub repository
*/
declare(strict_types=1);
@@ -23,11 +23,11 @@ class ReleaseMirrorCli extends CliFramework
{
protected function configure(): void
{
$this->setDescription('Mirror a Gitea release (with assets) to a GitHub repository');
$this->setDescription('Mirror a Git release (with assets) to a GitHub repository');
$this->addArgument('--version', 'Version string (required)', '');
$this->addArgument('--tag', 'Release tag name (required)', '');
$this->addArgument('--token', 'Gitea API token', '');
$this->addArgument('--api-base', 'Gitea API base URL for the repo (required)', '');
$this->addArgument('--token', 'Git API token', '');
$this->addArgument('--api-base', 'Git API base URL for the repo (required)', '');
$this->addArgument('--gh-token', 'GitHub personal access token', '');
$this->addArgument('--gh-repo', 'GitHub org/repo (required)', '');
$this->addArgument('--branch', 'Target branch (default: main)', 'main');
@@ -44,30 +44,30 @@ class ReleaseMirrorCli extends CliFramework
$branch = $this->getArgument('--branch');
// Allow tokens from environment
$token = $token ?: (getenv('MOKOGITEA_TOKEN') ?: (getenv('GITEA_TOKEN') ?: ''));
$token = $token ?: (getenv('MOKOGIT_TOKEN') ?: (getenv('GIT_TOKEN') ?: ''));
$ghToken = $ghToken ?: (getenv('GH_MIRROR_TOKEN') ?: '');
if ($version === '' || $tag === '' || $token === '' || $apiBase === '' || $ghToken === '' || $ghRepo === '') {
$this->log('ERROR', "Usage: release_mirror.php --version VER --tag TAG --token TOKEN " .
"--api-base URL --gh-token GH_MIRROR_TOKEN --gh-repo org/repo [--branch main]");
$this->log('ERROR', " --token: Gitea token (or MOKOGITEA_TOKEN / GITEA_TOKEN env)");
$this->log('ERROR', " --token: Git token (or MOKOGIT_TOKEN / GIT_TOKEN env)");
$this->log('ERROR', " --gh-token: GitHub token (or GH_MIRROR_TOKEN env)");
return 1;
}
// ── Step 1: Get Gitea release by tag ─────────────────────────────────────────
// ── Step 1: Get Git release by tag ─────────────────────────────────────────
echo "Fetching Gitea release: {$tag}\n";
$giteaRelease = $this->giteaApi("{$apiBase}/releases/tags/{$tag}", $token);
if (!$giteaRelease || empty($giteaRelease['id'])) {
$this->log('ERROR', "No Gitea release found with tag: {$tag}");
echo "Fetching Git release: {$tag}\n";
$gitRelease = $this->gitApi("{$apiBase}/releases/tags/{$tag}", $token);
if (!$gitRelease || empty($gitRelease['id'])) {
$this->log('ERROR', "No Git release found with tag: {$tag}");
return 1;
}
$giteaId = $giteaRelease['id'];
$releaseName = $giteaRelease['name'] ?? "{$version}";
$releaseBody = $giteaRelease['body'] ?? '';
$assets = $giteaRelease['assets'] ?? [];
$gitId = $gitRelease['id'];
$releaseName = $gitRelease['name'] ?? "{$version}";
$releaseBody = $gitRelease['body'] ?? '';
$assets = $gitRelease['assets'] ?? [];
echo " Name: {$releaseName}\n";
echo " Assets: " . count($assets) . " file(s)\n";
@@ -109,7 +109,7 @@ class ReleaseMirrorCli extends CliFramework
echo " Created GitHub release (id: {$ghReleaseId})\n";
}
// ── Step 3: Download assets from Gitea ───────────────────────────────────────
// ── Step 3: Download assets from Git ───────────────────────────────────────
$tmpDir = sys_get_temp_dir() . '/moko-mirror-' . getmypid();
@mkdir($tmpDir, 0755, true);
@@ -126,7 +126,7 @@ class ReleaseMirrorCli extends CliFramework
$localPath = "{$tmpDir}/{$name}";
echo " Downloading: {$name}\n";
if (!$this->giteaDownload($downloadUrl, $token, $localPath)) {
if (!$this->gitDownload($downloadUrl, $token, $localPath)) {
$this->log('ERROR', " Failed to download: {$name}");
continue;
}
@@ -151,7 +151,7 @@ class ReleaseMirrorCli extends CliFramework
return 0;
}
private function giteaApi(string $url, string $token, string $method = 'GET', ?string $body = null): ?array
private function gitApi(string $url, string $token, string $method = 'GET', ?string $body = null): ?array
{
$ch = curl_init($url);
curl_setopt_array($ch, [
@@ -176,7 +176,7 @@ class ReleaseMirrorCli extends CliFramework
return json_decode($response, true) ?: null;
}
private function giteaDownload(string $url, string $token, string $dest): bool
private function gitDownload(string $url, string $token, string $dest): bool
{
$ch = curl_init($url);
$fp = fopen($dest, 'wb');
+15 -15
View File
@@ -10,7 +10,7 @@
* INGROUP: mokocli
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /cli/release_package.php
* BRIEF: Build packages (ZIP + tar.gz) with SHA-256 and upload to Gitea release
* BRIEF: Build packages (ZIP + tar.gz) with SHA-256 and upload to Git release
*/
declare(strict_types=1);
@@ -35,12 +35,12 @@ class ReleasePackageCli extends CliFramework
protected function configure(): void
{
$this->setDescription('Build packages (ZIP + tar.gz) with SHA-256 and upload to Gitea release');
$this->setDescription('Build packages (ZIP + tar.gz) with SHA-256 and upload to Git release');
$this->addArgument('--path', 'Repository root path', '.');
$this->addArgument('--version', 'Release version', '');
$this->addArgument('--tag', 'Release tag name', '');
$this->addArgument('--token', 'Gitea API token', '');
$this->addArgument('--api-base', 'Gitea API base URL', '');
$this->addArgument('--token', 'Git API token', '');
$this->addArgument('--api-base', 'Git API base URL', '');
$this->addArgument('--repo', 'Repo name for element detection fallback', '');
$this->addArgument('--output', 'Output directory for built packages', '');
}
@@ -61,23 +61,23 @@ class ReleasePackageCli extends CliFramework
// Allow token from environment
if ($token === '' || $token === null) {
$token = getenv('MOKOGITEA_TOKEN') ?: (getenv('GITEA_TOKEN') ?: '');
$token = getenv('MOKOGIT_TOKEN') ?: (getenv('GIT_TOKEN') ?: '');
}
if ($version === '' || $tag === '' || $token === '' || $apiBase === '') {
$this->log('ERROR', "Usage: release_package.php --path . --version VER --tag TAG --token TOKEN --api-base URL");
$this->log('ERROR', " --repo REPO Repo name for element detection fallback");
$this->log('ERROR', " --output DIR Output directory for built packages (default: sys_get_temp_dir())");
$this->log('ERROR', " Token can also be set via MOKOGITEA_TOKEN or GITEA_TOKEN env var");
$this->log('ERROR', " Token can also be set via MOKOGIT_TOKEN or GIT_TOKEN env var");
return 1;
}
$root = realpath($path) ?: $path;
// ── Read platform from .mokogitea/manifest.xml ───────────────────────
// ── Read platform from .mokogit/manifest.xml ───────────────────────
$detectedPlatform = 'generic';
$detectedEntryPoint = '';
$mokoManifest = "{$root}/.mokogitea/manifest.xml";
$mokoManifest = "{$root}/.mokogit/manifest.xml";
if (file_exists($mokoManifest)) {
$mokoXml = @simplexml_load_file($mokoManifest);
if ($mokoXml !== false) {
@@ -458,7 +458,7 @@ class ReleasePackageCli extends CliFramework
}
// ── Get release ID from tag ──────────────────────────────────────────
$result = $this->giteaApiRequest("{$apiBase}/releases/tags/{$tag}", $token);
$result = $this->gitApiRequest("{$apiBase}/releases/tags/{$tag}", $token);
if ($result['data'] === null || !isset($result['data']['id'])) {
$this->log('ERROR', "No release found for tag: {$tag} (HTTP {$result['code']})");
return 1;
@@ -468,7 +468,7 @@ class ReleasePackageCli extends CliFramework
echo "Release ID: {$releaseId} (tag: {$tag})\n";
// ── Delete existing assets with same names ───────────────────────────
$assetsResult = $this->giteaApiRequest("{$apiBase}/releases/{$releaseId}/assets", $token);
$assetsResult = $this->gitApiRequest("{$apiBase}/releases/{$releaseId}/assets", $token);
$existingAssets = $assetsResult['data'] ?? [];
$uploadNames = [
@@ -485,7 +485,7 @@ class ReleasePackageCli extends CliFramework
$assetName = $asset['name'] ?? '';
$assetId = $asset['id'] ?? 0;
if (in_array($assetName, $uploadNames, true) && $assetId > 0) {
$this->giteaApiRequest("{$apiBase}/releases/{$releaseId}/assets/{$assetId}", $token, 'DELETE');
$this->gitApiRequest("{$apiBase}/releases/{$releaseId}/assets/{$assetId}", $token, 'DELETE');
echo "Deleted existing asset: {$assetName}\n";
}
}
@@ -506,7 +506,7 @@ class ReleasePackageCli extends CliFramework
}
$uploadUrl = "{$apiBase}/releases/{$releaseId}/assets?name=" . urlencode($name);
$httpCode = $this->giteaUploadAsset($uploadUrl, $token, $localPath);
$httpCode = $this->gitUploadAsset($uploadUrl, $token, $localPath);
$status = ($httpCode >= 200 && $httpCode < 300) ? 'OK' : "FAILED ({$httpCode})";
echo "Upload: {$name}{$status}\n";
@@ -527,11 +527,11 @@ class ReleasePackageCli extends CliFramework
}
/**
* Perform a Gitea API request.
* Perform a Git API request.
*
* @return array{data: array<string, mixed>|null, code: int}
*/
private function giteaApiRequest(string $url, string $token, string $method = 'GET', ?string $body = null): array
private function gitApiRequest(string $url, string $token, string $method = 'GET', ?string $body = null): array
{
$ch = curl_init($url);
if ($ch === false) {
@@ -564,7 +564,7 @@ class ReleasePackageCli extends CliFramework
/**
* Upload a file as a release asset.
*/
private function giteaUploadAsset(string $url, string $token, string $filePath): int
private function gitUploadAsset(string $url, string $token, string $filePath): int
{
$ch = curl_init($url);
if ($ch === false) {
+17 -17
View File
@@ -10,7 +10,7 @@
* INGROUP: mokocli
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /cli/release_promote.php
* BRIEF: Promote a Gitea release from one channel to another (rename release, tag, assets)
* BRIEF: Promote a Git release from one channel to another (rename release, tag, assets)
*/
declare(strict_types=1);
@@ -23,11 +23,11 @@ class ReleasePromoteCli extends CliFramework
{
protected function configure(): void
{
$this->setDescription('Promote a Gitea release from one channel to another');
$this->setDescription('Promote a Git release from one channel to another');
$this->addArgument('--from', 'Source channel (or "auto")', '');
$this->addArgument('--to', 'Target channel (required)', '');
$this->addArgument('--token', 'Gitea API token', '');
$this->addArgument('--api-base', 'Gitea API base URL for the repo', '');
$this->addArgument('--token', 'Git API token', '');
$this->addArgument('--api-base', 'Git API base URL for the repo', '');
$this->addArgument('--path', 'Repository root for type prefix detection', '.');
$this->addArgument('--branch', 'Target branch', 'main');
}
@@ -41,7 +41,7 @@ class ReleasePromoteCli extends CliFramework
$path = $this->getArgument('--path');
$branch = $this->getArgument('--branch');
$token = $token ?: (getenv('MOKOGITEA_TOKEN') ?: (getenv('GITEA_TOKEN') ?: null));
$token = $token ?: (getenv('MOKOGIT_TOKEN') ?: (getenv('GIT_TOKEN') ?: null));
if ($to === null || $token === null || $apiBase === null) {
$this->log('ERROR', "Usage: release_promote.php --from <channel|auto> --to <channel> --token TOKEN --api-base URL [--path .]");
@@ -64,7 +64,7 @@ class ReleasePromoteCli extends CliFramework
// ── Resolve --from auto ──────────────────────────────────────────────────────
if ($from === 'auto') {
foreach ($channelOrder as $candidate) {
$data = $this->giteaApi("{$apiBase}/releases/tags/{$candidate}", $token);
$data = $this->gitApi("{$apiBase}/releases/tags/{$candidate}", $token);
if ($data && !empty($data['id'])) {
$from = $candidate;
echo "Auto-detected source channel: {$from}\n";
@@ -78,7 +78,7 @@ class ReleasePromoteCli extends CliFramework
}
// ── Find source release ──────────────────────────────────────────────────────
$sourceRelease = $this->giteaApi("{$apiBase}/releases/tags/{$from}", $token);
$sourceRelease = $this->gitApi("{$apiBase}/releases/tags/{$from}", $token);
if (!$sourceRelease || empty($sourceRelease['id'])) {
$this->log('ERROR', "No release found with tag: {$from}");
return 1;
@@ -90,7 +90,7 @@ class ReleasePromoteCli extends CliFramework
echo "Source: {$from} (id: {$sourceId}) — {$sourceName}\n";
// ── Get source assets ────────────────────────────────────────────────────────
$assets = $this->giteaApi("{$apiBase}/releases/{$sourceId}/assets", $token) ?: [];
$assets = $this->gitApi("{$apiBase}/releases/{$sourceId}/assets", $token) ?: [];
echo "Assets: " . count($assets) . " file(s)\n";
// ── Download assets to temp ──────────────────────────────────────────────────
@@ -101,7 +101,7 @@ class ReleasePromoteCli extends CliFramework
$name = $asset['name'];
$downloadUrl = $asset['browser_download_url'];
echo " Downloading: {$name}\n";
$this->giteaDownload($downloadUrl, $token, "{$tmpDir}/{$name}");
$this->gitDownload($downloadUrl, $token, "{$tmpDir}/{$name}");
}
// ── Detect type prefix for stable promotion ──────────────────────────────────
@@ -188,15 +188,15 @@ class ReleasePromoteCli extends CliFramework
}
// ── Delete source release + tag ──────────────────────────────────────────────
$this->giteaApi("{$apiBase}/releases/{$sourceId}", $token, 'DELETE');
$this->giteaApi("{$apiBase}/tags/{$from}", $token, 'DELETE');
$this->gitApi("{$apiBase}/releases/{$sourceId}", $token, 'DELETE');
$this->gitApi("{$apiBase}/tags/{$from}", $token, 'DELETE');
echo "Deleted source: {$from} release + tag\n";
// ── Delete existing target release + tag (if any) ────────────────────────────
$existingTarget = $this->giteaApi("{$apiBase}/releases/tags/{$to}", $token);
$existingTarget = $this->gitApi("{$apiBase}/releases/tags/{$to}", $token);
if ($existingTarget && !empty($existingTarget['id'])) {
$this->giteaApi("{$apiBase}/releases/{$existingTarget['id']}", $token, 'DELETE');
$this->giteaApi("{$apiBase}/tags/{$to}", $token, 'DELETE');
$this->gitApi("{$apiBase}/releases/{$existingTarget['id']}", $token, 'DELETE');
$this->gitApi("{$apiBase}/tags/{$to}", $token, 'DELETE');
echo "Deleted existing target: {$to} release + tag\n";
}
@@ -217,7 +217,7 @@ class ReleasePromoteCli extends CliFramework
'prerelease' => $isPrerelease,
]);
$newRelease = $this->giteaApi("{$apiBase}/releases", $token, 'POST', $payload);
$newRelease = $this->gitApi("{$apiBase}/releases", $token, 'POST', $payload);
if (!$newRelease || empty($newRelease['id'])) {
$this->log('ERROR', "Failed to create {$to} release");
return 1;
@@ -263,7 +263,7 @@ class ReleasePromoteCli extends CliFramework
return 0;
}
private function giteaApi(string $url, string $token, string $method = 'GET', ?string $body = null): ?array
private function gitApi(string $url, string $token, string $method = 'GET', ?string $body = null): ?array
{
$ch = curl_init($url);
curl_setopt_array($ch, [
@@ -288,7 +288,7 @@ class ReleasePromoteCli extends CliFramework
return json_decode($response, true) ?: null;
}
private function giteaDownload(string $url, string $token, string $dest): bool
private function gitDownload(string $url, string $token, string $dest): bool
{
$ch = curl_init($url);
$fp = fopen($dest, 'wb');
+16 -16
View File
@@ -27,10 +27,10 @@ class ReleasePublishCli extends CliFramework
$this->setDescription('Publish a release and update stability streams');
$this->addArgument('--path', 'Repository root (default: .)', '.');
$this->addArgument('--stability', 'Target stability: dev|alpha|beta|rc|stable (required)', '');
$this->addArgument('--token', 'Gitea API token (required)', '');
$this->addArgument('--token', 'Git API token (required)', '');
$this->addArgument('--bump', 'Version bump type: patch|minor|none (default: none)', 'none');
$this->addArgument('--branch', 'Current branch (default: auto-detect)', '');
$this->addArgument('--gitea-url', 'Gitea URL', '');
$this->addArgument('--git-url', 'Git URL', '');
$this->addArgument('--org', 'Organization', '');
$this->addArgument('--repo', 'Repository name', '');
$this->addArgument('--repo-url', 'Repository URL for git auth', '');
@@ -44,9 +44,9 @@ class ReleasePublishCli extends CliFramework
$token = $this->getArgument('--token');
$bumpType = $this->getArgument('--bump');
$branch = $this->getArgument('--branch');
$giteaUrl = $this->getArgument('--gitea-url') ?: (getenv('GITEA_URL') ?: 'https://git.mokoconsulting.tech');
$org = $this->getArgument('--org') ?: (getenv('GITEA_ORG') ?: '');
$repo = $this->getArgument('--repo') ?: (getenv('GITEA_REPO') ?: '');
$gitUrl = $this->getArgument('--git-url') ?: (getenv('GIT_URL') ?: 'https://git.mokoconsulting.tech');
$org = $this->getArgument('--org') ?: (getenv('GIT_ORG') ?: '');
$repo = $this->getArgument('--repo') ?: (getenv('GIT_REPO') ?: '');
$repoUrl = $this->getArgument('--repo-url');
$skipUpdateStream = $this->getArgument('--skip-update-stream');
@@ -57,7 +57,7 @@ class ReleasePublishCli extends CliFramework
$cli = __DIR__;
$php = '"' . PHP_BINARY . '"';
$giteaUrl = rtrim($giteaUrl, '/');
$gitUrl = rtrim($gitUrl, '/');
// Resolve path early for shell commands (Windows needs native paths)
$resolvedPath = realpath($path) ?: $path;
@@ -81,7 +81,7 @@ class ReleasePublishCli extends CliFramework
// Auto-construct repo URL for git auth if not provided
if (empty($repoUrl) && !empty($token) && !empty($org) && !empty($repo)) {
$host = preg_replace('#^https?://#', '', $giteaUrl);
$host = preg_replace('#^https?://#', '', $gitUrl);
$repoUrl = "https://x-access-token:{$token}@{$host}/{$org}/{$repo}.git";
}
@@ -95,7 +95,7 @@ class ReleasePublishCli extends CliFramework
));
}
$apiBase = "{$giteaUrl}/api/v1/repos/{$org}/{$repo}";
$apiBase = "{$gitUrl}/api/v1/repos/{$org}/{$repo}";
// Stability ordering and suffix mapping
$allStabilities = ['dev', 'alpha', 'beta', 'rc', 'stable'];
@@ -189,11 +189,11 @@ class ReleasePublishCli extends CliFramework
$cdR = $cdPfx . escapeshellarg($root);
@shell_exec(
$cdR . " && git config --local user.email"
. " \"gitea-actions[bot]@mokoconsulting.tech\""
. " \"git-actions[bot]@mokoconsulting.tech\""
);
@shell_exec(
$cdR . " && git config --local user.name"
. " \"gitea-actions[bot]\""
. " \"git-actions[bot]\""
);
if (!empty($repoUrl)) {
@shell_exec(
@@ -239,8 +239,8 @@ class ReleasePublishCli extends CliFramework
@shell_exec(
$cdR . " && git commit -m "
. escapeshellarg($commitMsg)
. " --author=\"gitea-actions[bot]"
. " <gitea-actions[bot]@mokoconsulting.tech>\""
. " --author=\"git-actions[bot]"
. " <git-actions[bot]@mokoconsulting.tech>\""
);
$pushResult = @shell_exec(
$cdR . " && git push origin "
@@ -314,7 +314,7 @@ class ReleasePublishCli extends CliFramework
passthru("{$php} {$cli}/updates_xml_build.php --path " . escapeshellarg($path)
. " --version " . escapeshellarg($streamVersion)
. " --stability " . escapeshellarg($stream)
. " --gitea-url " . escapeshellarg($giteaUrl)
. " --git-url " . escapeshellarg($gitUrl)
. " --org " . escapeshellarg($org)
. " --repo " . escapeshellarg($repo)
. " {$shaFlag} 2>&1");
@@ -339,8 +339,8 @@ class ReleasePublishCli extends CliFramework
@shell_exec(
$cdRt . " && git commit -m "
. escapeshellarg($chMsg)
. " --author=\"gitea-actions[bot]"
. " <gitea-actions[bot]@mokoconsulting.tech>\""
. " --author=\"git-actions[bot]"
. " <git-actions[bot]@mokoconsulting.tech>\""
);
@shell_exec(
$cdRt . " && git push origin "
@@ -354,7 +354,7 @@ class ReleasePublishCli extends CliFramework
. " --current " . escapeshellarg($branch) . " --all"
. " --version " . escapeshellarg($releaseVersion)
. " --token " . escapeshellarg($token)
. " --gitea-url " . escapeshellarg($giteaUrl)
. " --git-url " . escapeshellarg($gitUrl)
. " --org " . escapeshellarg($org)
. " --repo " . escapeshellarg($repo) . " 2>&1");
} else {
+1 -1
View File
@@ -49,7 +49,7 @@ class ReleaseValidateCli extends CliFramework
}
$root = realpath($path) ?: $path;
if ($platform === null) {
$manifestXml = "{$root}/.mokogitea/manifest.xml";
$manifestXml = "{$root}/.mokogit/manifest.xml";
if (file_exists($manifestXml)) {
$mContent = file_get_contents($manifestXml);
if (preg_match('/<platform>([^<]+)<\/platform>/', $mContent, $pm)) {
+5 -5
View File
@@ -22,7 +22,7 @@ use MokoCli\{CliFramework, Config, PlatformAdapterFactory};
* Interactive repo setup wizard.
*
* Walks through platform selection, generates config files, workflows,
* and optionally creates the repo on Gitea via API.
* and optionally creates the repo on Git via API.
*
* @see https://git.mokoconsulting.tech/MokoConsulting/mokocli/issues/145
*/
@@ -54,7 +54,7 @@ class RepoWizard extends CliFramework
{
$this->setDescription('Interactive configuration wizard for new repositories');
$this->addArgument('--path', 'Directory to generate files in', '.');
$this->addArgument('--create-remote', 'Create repo on Gitea via API', false);
$this->addArgument('--create-remote', 'Create repo on Git via API', false);
$this->addArgument('--non-interactive', 'Use defaults (no prompts)', false);
}
@@ -155,8 +155,8 @@ class RepoWizard extends CliFramework
break;
}
// .mokogitea/workflows
$generated[] = $this->writeFile($path, '.mokogitea/workflows/pr-check.yml',
// .mokogit/workflows
$generated[] = $this->writeFile($path, '.mokogit/workflows/pr-check.yml',
"# PR check workflow — synced from mokocli templates\n# Run: moko sync to update\n");
// .gitignore
@@ -205,7 +205,7 @@ class RepoWizard extends CliFramework
$org = $this->answers['org'];
if ($this->dryRun) {
$this->log('INFO', "[dry-run] Would create {$org}/{$this->answers['name']} on Gitea");
$this->log('INFO', "[dry-run] Would create {$org}/{$this->answers['name']} on Git");
return;
}
+14 -14
View File
@@ -28,16 +28,16 @@ class ScaffoldClientCli extends CliFramework
{
$this->setDescription('Scaffold a new client-waas repo from Template-Client');
$this->addArgument('--name', 'Client name', '');
$this->addArgument('--org', 'Gitea organization', '');
$this->addArgument('--gitea-url', 'Gitea URL', 'https://git.mokoconsulting.tech');
$this->addArgument('--token', 'Gitea API token', '');
$this->addArgument('--org', 'Git organization', '');
$this->addArgument('--git-url', 'Git URL', 'https://git.mokoconsulting.tech');
$this->addArgument('--token', 'Git API token', '');
}
protected function run(): int
{
$name = $this->getArgument('--name');
$org = $this->getArgument('--org');
$giteaUrl = rtrim($this->getArgument('--gitea-url'), '/');
$gitUrl = rtrim($this->getArgument('--git-url'), '/');
$token = $this->getArgument('--token');
if ($name === '' || $org === '' || $token === '') {
$this->log('ERROR', '--name, --org, and --token are required.');
@@ -45,11 +45,11 @@ class ScaffoldClientCli extends CliFramework
}
$repoName = 'client-waas-' . $name;
$this->log('INFO', "Scaffolding client repo: {$org}/{$repoName}");
$this->log('INFO', "Gitea URL: {$giteaUrl}");
$this->log('INFO', "Git URL: {$gitUrl}");
if ($this->dryRun) {
$this->log('INFO', '[DRY RUN] Would create repo from template MokoConsulting/Template-Client');
$this->log('INFO', "[DRY RUN] Repo: {$org}/{$repoName}");
$this->printPostSetupInstructions($repoName, $giteaUrl, $org);
$this->printPostSetupInstructions($repoName, $gitUrl, $org);
return 0;
}
$this->log('INFO', 'Step 1: Creating repo from template...');
@@ -65,7 +65,7 @@ class ScaffoldClientCli extends CliFramework
$response = $this->apiRequest(
'POST',
"/api/v1/repos/MokoConsulting/Template-Client/generate",
$giteaUrl,
$gitUrl,
$token,
$createPayload
);
@@ -75,12 +75,12 @@ class ScaffoldClientCli extends CliFramework
}
$this->log('INFO', "Repo created: {$org}/{$repoName}");
$this->log('INFO', 'Step 2: Updating repo description...');
$this->apiRequest('PATCH', "/api/v1/repos/{$org}/{$repoName}", $giteaUrl, $token, json_encode(['description' => "{$name} WaaS site"]));
$this->apiRequest('PATCH', "/api/v1/repos/{$org}/{$repoName}", $gitUrl, $token, json_encode(['description' => "{$name} WaaS site"]));
$this->log('INFO', 'Step 3: Creating dev branch from main...');
$response = $this->apiRequest(
'POST',
"/api/v1/repos/{$org}/{$repoName}/branches",
$giteaUrl,
$gitUrl,
$token,
json_encode([
'new_branch_name' => 'dev',
@@ -92,15 +92,15 @@ class ScaffoldClientCli extends CliFramework
} else {
$this->log('WARN', "Could not create dev branch (HTTP {$response['code']}).");
}
$this->printPostSetupInstructions($repoName, $giteaUrl, $org);
$this->printPostSetupInstructions($repoName, $gitUrl, $org);
$this->log('INFO', 'Scaffold complete.');
return 0;
}
private function printPostSetupInstructions(string $repoName, string $giteaUrl, string $org): void
private function printPostSetupInstructions(string $repoName, string $gitUrl, string $org): void
{
fwrite(STDERR, "\n=== POST-SETUP INSTRUCTIONS ===\n\n"
. "Navigate to: {$giteaUrl}/{$org}/{$repoName}/settings\n\n"
. "Navigate to: {$gitUrl}/{$org}/{$repoName}/settings\n\n"
. "Set REPO VARIABLES:\n"
. " DEV_SYNC_HOST, DEV_SYNC_PORT, DEV_SYNC_USER, DEV_SYNC_PATH\n"
. " LIVE_SSH_HOST, LIVE_SSH_PORT, LIVE_SSH_USER, LIVE_SYNC_PATH\n\n"
@@ -109,10 +109,10 @@ class ScaffoldClientCli extends CliFramework
. "================================\n");
}
private function apiRequest(string $method, string $endpoint, string $giteaUrl, string $token, ?string $body = null): array
private function apiRequest(string $method, string $endpoint, string $gitUrl, string $token, ?string $body = null): array
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $giteaUrl . $endpoint);
curl_setopt($ch, CURLOPT_URL, $gitUrl . $endpoint);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json', 'Accept: application/json', "Authorization: token {$token}"]);
+6 -6
View File
@@ -13,7 +13,7 @@
* BRIEF: Validate a client MokoOnyx theme package — required CSS variables
* (derived dynamically from the MokoOnyx standard theme) are defined in
* the client's light/dark custom CSS, required files exist, the manifest
* is sane, and (optionally) the repo's Gitea metadata is set.
* is sane, and (optionally) the repo's Git metadata is set.
*
* Standalone (no CliFramework dependency) so it runs even when the shared
* framework autoloader is unavailable.
@@ -166,7 +166,7 @@ if (is_file($manifest)) {
if ($server === '') {
$fail('<updateservers><server> is missing');
} elseif (strpos($server, '/raw/branch/') !== false) {
$fail('update server uses a legacy raw/branch URL; use the dynamic MokoGitea feed');
$fail('update server uses a legacy raw/branch URL; use the dynamic MokoGit feed');
} else {
$ok("update server: $server");
}
@@ -224,12 +224,12 @@ if (is_file($manifest)) {
}
}
// 4) Repository metadata via Gitea API (optional) -------------------------
// 4) Repository metadata via Git API (optional) -------------------------
$apiBase = isset($opts['api-base']) && is_string($opts['api-base']) ? rtrim($opts['api-base'], '/') : '';
$repoSlug = isset($opts['repo']) && is_string($opts['repo']) ? trim($opts['repo']) : '';
$token = isset($opts['token']) && is_string($opts['token']) ? trim($opts['token']) : '';
if ($apiBase !== '' && $repoSlug !== '' && $token !== '') {
echo "\n=== Repository metadata (Gitea API) ===\n";
echo "\n=== Repository metadata (Git API) ===\n";
$url = "$apiBase/repos/$repoSlug";
$ctx = stream_context_create(['http' => [
'method' => 'GET',
@@ -240,7 +240,7 @@ if ($apiBase !== '' && $repoSlug !== '' && $token !== '') {
$resp = @file_get_contents($url, false, $ctx);
$data = $resp !== false ? json_decode($resp, true) : null;
if (!is_array($data) || !isset($data['name'])) {
$fail("could not read repo metadata from Gitea API ($url)");
$fail("could not read repo metadata from Git API ($url)");
} else {
trim((string) ($data['description'] ?? '')) !== '' ? $ok('description set')
: $fail('repo description is empty');
@@ -272,7 +272,7 @@ if ($apiBase !== '' && $repoSlug !== '' && $token !== '') {
}
}
} else {
echo "\n=== Repository metadata (Gitea API) ===\n";
echo "\n=== Repository metadata (Git API) ===\n";
$note('API args not provided; skipping repo metadata check');
}
+10 -10
View File
@@ -28,7 +28,7 @@ class UpdatesXmlBuildCli extends CliFramework
$this->addArgument('--version', 'Version string (required)', '');
$this->addArgument('--stability', 'One of: stable, rc, beta, alpha, development (default: stable)', 'stable');
$this->addArgument('--sha', 'SHA-256 hash of the ZIP package', '');
$this->addArgument('--gitea-url', 'Gitea instance URL', '');
$this->addArgument('--git-url', 'Git instance URL', '');
$this->addArgument('--org', 'Organization', '');
$this->addArgument('--repo', 'Repository name', '');
$this->addArgument('--output', 'Output file path (default: updates.xml in --path)', '');
@@ -41,9 +41,9 @@ class UpdatesXmlBuildCli extends CliFramework
$version = $this->getArgument('--version');
$stability = $this->getArgument('--stability');
$sha = $this->getArgument('--sha') ?: null;
$giteaUrl = $this->getArgument('--gitea-url') ?: (getenv('GITEA_URL') ?: 'https://git.mokoconsulting.tech');
$org = $this->getArgument('--org') ?: (getenv('GITEA_ORG') ?: '');
$repo = $this->getArgument('--repo') ?: (getenv('GITEA_REPO') ?: '');
$gitUrl = $this->getArgument('--git-url') ?: (getenv('GIT_URL') ?: 'https://git.mokoconsulting.tech');
$org = $this->getArgument('--org') ?: (getenv('GIT_ORG') ?: '');
$repo = $this->getArgument('--repo') ?: (getenv('GIT_REPO') ?: '');
$outputFile = $this->getArgument('--output') ?: null;
$githubOutput = $this->getArgument('--github-output');
@@ -57,12 +57,12 @@ class UpdatesXmlBuildCli extends CliFramework
$root = realpath($path) ?: $path;
// -- Read platform from .mokogitea/manifest.xml --------------------------------
// -- Read platform from .mokogit/manifest.xml --------------------------------
$detectedPlatform = 'joomla';
$detectedName = $repo;
$detectedPackageType = '';
$detectedDisplayName = '';
$mokoManifest = "{$root}/.mokogitea/manifest.xml";
$mokoManifest = "{$root}/.mokogit/manifest.xml";
if (file_exists($mokoManifest)) {
$mokoXml = @simplexml_load_file($mokoManifest);
if ($mokoXml !== false) {
@@ -312,12 +312,12 @@ class UpdatesXmlBuildCli extends CliFramework
// -- Write ONLY the single channel being released --------------------------------
$entries = [];
$giteaTag = $releaseTagMap[$stability] ?? $stability;
$gitTag = $releaseTagMap[$stability] ?? $stability;
$channelVersion = $version . ($stabilitySuffixMap[$stability] ?? '');
$channelDownloadUrl = "{$giteaUrl}/{$org}/{$repo}/releases/download/{$giteaTag}/{$typePrefix}{$extElement}-{$channelVersion}.zip";
$channelInfoUrl = "{$giteaUrl}/{$org}/{$repo}/releases/tag/{$giteaTag}";
$channelDownloadUrl = "{$gitUrl}/{$org}/{$repo}/releases/download/{$gitTag}/{$typePrefix}{$extElement}-{$channelVersion}.zip";
$channelInfoUrl = "{$gitUrl}/{$org}/{$repo}/releases/tag/{$gitTag}";
$joomlaTag = $stabilityTagMap[$stability] ?? $stability;
$changelogUrl = "{$giteaUrl}/{$org}/{$repo}/raw/branch/main/CHANGELOG.md";
$changelogUrl = "{$gitUrl}/{$org}/{$repo}/raw/branch/main/CHANGELOG.md";
$entries[] = $this->buildEntry(
$joomlaTag,
+16 -16
View File
@@ -11,7 +11,7 @@
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /cli/updates_xml_sync.php
* VERSION: 09.43.00
* BRIEF: Sync updates.xml to target branches via Gitea API
* BRIEF: Sync updates.xml to target branches via Git API
* NOTE: Called by pre-release and auto-release workflows after updates.xml
* is modified on the current branch. Pushes the file to other branches
* without requiring a git checkout (avoids merge conflicts).
@@ -27,14 +27,14 @@ class UpdatesXmlSyncCli extends CliFramework
{
protected function configure(): void
{
$this->setDescription('Sync updates.xml to target branches via Gitea API');
$this->setDescription('Sync updates.xml to target branches via Git API');
$this->addArgument('--path', 'Repository root containing updates.xml', '.');
$this->addArgument('--branches', 'Comma-separated target branches to sync to', 'main,dev');
$this->addArgument('--all', 'Auto-discover all branches via Gitea API', false);
$this->addArgument('--all', 'Auto-discover all branches via Git API', false);
$this->addArgument('--current', 'Current branch to skip (required)', '');
$this->addArgument('--version', 'Version string for commit message', '');
$this->addArgument('--token', 'Gitea API token', '');
$this->addArgument('--gitea-url', 'Gitea instance URL', '');
$this->addArgument('--token', 'Git API token', '');
$this->addArgument('--git-url', 'Git instance URL', '');
$this->addArgument('--org', 'Organization', '');
$this->addArgument('--repo', 'Repository name', '');
}
@@ -47,22 +47,22 @@ class UpdatesXmlSyncCli extends CliFramework
$current = $this->getArgument('--current');
$version = $this->getArgument('--version');
$token = $this->getArgument('--token');
$giteaUrl = $this->getArgument('--gitea-url');
$gitUrl = $this->getArgument('--git-url');
$org = $this->getArgument('--org');
$repo = $this->getArgument('--repo');
// Fall back to environment variables
if ($token === '') {
$token = getenv('MOKOGITEA_TOKEN') ?: '';
$token = getenv('MOKOGIT_TOKEN') ?: '';
}
if ($giteaUrl === '') {
$giteaUrl = getenv('GITEA_URL') ?: 'https://git.mokoconsulting.tech';
if ($gitUrl === '') {
$gitUrl = getenv('GIT_URL') ?: 'https://git.mokoconsulting.tech';
}
if ($org === '') {
$org = getenv('GITEA_ORG') ?: '';
$org = getenv('GIT_ORG') ?: '';
}
if ($repo === '') {
$repo = getenv('GITEA_REPO') ?: '';
$repo = getenv('GIT_REPO') ?: '';
}
if ($current === '') {
@@ -71,18 +71,18 @@ class UpdatesXmlSyncCli extends CliFramework
}
if ($token === '') {
$this->log('ERROR', '--token or MOKOGITEA_TOKEN env is required');
$this->log('ERROR', '--token or MOKOGIT_TOKEN env is required');
return 1;
}
if ($org === '' || $repo === '') {
$this->log('ERROR', '--org and --repo (or GITEA_ORG/GITEA_REPO env) are required');
$this->log('ERROR', '--org and --repo (or GIT_ORG/GIT_REPO env) are required');
return 1;
}
// Auto-discover branches if --all flag is set
if ($discoverAll) {
$apiUrl = "{$giteaUrl}/api/v1/repos/{$org}/{$repo}/branches?limit=50";
$apiUrl = "{$gitUrl}/api/v1/repos/{$org}/{$repo}/branches?limit=50";
$ch = curl_init($apiUrl);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
@@ -118,8 +118,8 @@ class UpdatesXmlSyncCli extends CliFramework
$content = file_get_contents($updatesFile);
$encoded = base64_encode($content);
$giteaUrl = rtrim($giteaUrl, '/');
$apiBase = "{$giteaUrl}/api/v1/repos/{$org}/{$repo}";
$gitUrl = rtrim($gitUrl, '/');
$apiBase = "{$gitUrl}/api/v1/repos/{$org}/{$repo}";
$vLabel = $version !== '' ? " {$version}" : '';
$targets = array_filter(
+5 -5
View File
@@ -70,7 +70,7 @@ class VersionAutoBumpCli extends CliFramework
// Auto-detect watch path from manifest.xml if not provided
if (empty($watchPath)) {
$manifestFile = realpath($path) . '/.mokogitea/manifest.xml';
$manifestFile = realpath($path) . '/.mokogit/manifest.xml';
if (file_exists($manifestFile)) {
$xml = @simplexml_load_file($manifestFile);
if ($xml && isset($xml->build->{'entry-point'})) {
@@ -176,11 +176,11 @@ class VersionAutoBumpCli extends CliFramework
$cdRoot = $cd . escapeshellarg($root);
@shell_exec(
$cdRoot . " && git config --local user.email"
. " \"gitea-actions[bot]@mokoconsulting.tech\""
. " \"git-actions[bot]@mokoconsulting.tech\""
);
@shell_exec(
$cdRoot . " && git config --local user.name"
. " \"gitea-actions[bot]\""
. " \"git-actions[bot]\""
);
if (!empty($repoUrl)) {
@@ -196,8 +196,8 @@ class VersionAutoBumpCli extends CliFramework
: "chore(version): set {$stability} suffix {$displayVersion} [skip ci]";
@shell_exec(
$cdRoot . " && git commit -m " . escapeshellarg($commitMsg)
. " --author=\"gitea-actions[bot]"
. " <gitea-actions[bot]@mokoconsulting.tech>\""
. " --author=\"git-actions[bot]"
. " <git-actions[bot]@mokoconsulting.tech>\""
);
$pushResult = @shell_exec(
+2 -2
View File
@@ -44,7 +44,7 @@ class VersionBumpCli extends CliFramework
$mokoVersion = null;
$existingSuffix = '';
$versionPrefix = '';
$mokoManifest = "{$root}/.mokogitea/manifest.xml";
$mokoManifest = "{$root}/.mokogit/manifest.xml";
$mokoContent = '';
if (file_exists($mokoManifest)) {
$mokoContent = file_get_contents($mokoManifest);
@@ -363,7 +363,7 @@ class VersionBumpCli extends CliFramework
if (in_array($relPath, $updatedFiles ?? [], true)) {
continue;
}
if (strpos($relPath, '.mokogitea/manifest.xml') !== false) {
if (strpos($relPath, '.mokogit/manifest.xml') !== false) {
continue;
}
$content = @file_get_contents($filePath);
+13 -13
View File
@@ -10,7 +10,7 @@
* INGROUP: mokocli
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /cli/version_bump_remote.php
* BRIEF: Bump version in manifest XML and CHANGELOG.md on a remote branch via Gitea API
* BRIEF: Bump version in manifest XML and CHANGELOG.md on a remote branch via Git API
*/
declare(strict_types=1);
@@ -23,15 +23,15 @@ class VersionBumpRemoteCli extends CliFramework
{
protected function configure(): void
{
$this->setDescription('Bump version in manifest XML and CHANGELOG.md on a remote branch via Gitea API');
$this->setDescription('Bump version in manifest XML and CHANGELOG.md on a remote branch via Git API');
$this->addArgument('--path', 'Repository root', '.');
$this->addArgument('--branch', 'Target branch to bump (required)', null);
$this->addArgument('--bump', 'Bump type: patch | minor | major', 'minor');
$this->addArgument('--token', 'Gitea API token (or MOKOGITEA_TOKEN env var)', null);
$this->addArgument('--api-base', 'Gitea API base URL for the repo', null);
$this->addArgument('--token', 'Git API token (or MOKOGIT_TOKEN env var)', null);
$this->addArgument('--api-base', 'Git API base URL for the repo', null);
$this->addArgument('--no-changelog', 'Skip CHANGELOG.md bump', false);
$this->addArgument('--repo', 'Repository path (owner/repo)', null);
$this->addArgument('--gitea-url', 'Gitea instance URL', null);
$this->addArgument('--git-url', 'Git instance URL', null);
}
protected function run(): int
@@ -43,15 +43,15 @@ class VersionBumpRemoteCli extends CliFramework
$apiBase = $this->getArgument('--api-base');
$noChangelog = (bool) $this->getArgument('--no-changelog');
$repo = $this->getArgument('--repo');
$giteaUrl = $this->getArgument('--gitea-url');
$gitUrl = $this->getArgument('--git-url');
if ($token === null) {
$token = getenv('MOKOGITEA_TOKEN') ?: getenv('GITEA_TOKEN') ?: null;
$token = getenv('MOKOGIT_TOKEN') ?: getenv('GIT_TOKEN') ?: null;
}
if ($giteaUrl === null) {
$giteaUrl = getenv('GITEA_URL') ?: 'https://git.mokoconsulting.tech';
if ($gitUrl === null) {
$gitUrl = getenv('GIT_URL') ?: 'https://git.mokoconsulting.tech';
}
if ($apiBase === null && $repo !== null) {
$apiBase = rtrim($giteaUrl, '/') . '/api/v1/repos/' . $repo;
$apiBase = rtrim($gitUrl, '/') . '/api/v1/repos/' . $repo;
}
if ($branch === null || $token === null || $apiBase === null) {
$this->log('ERROR', "Usage: version_bump_remote.php --branch BRANCH --token TOKEN --api-base URL [--bump minor|patch|major]");
@@ -148,7 +148,7 @@ class VersionBumpRemoteCli extends CliFramework
return 0;
}
private function giteaApi(string $method, string $url, string $token, ?string $body = null): ?array
private function gitApi(string $method, string $url, string $token, ?string $body = null): ?array
{
$ch = curl_init($url);
curl_setopt_array($ch, [
@@ -180,7 +180,7 @@ class VersionBumpRemoteCli extends CliFramework
callable $transform,
string $commitMessage
): bool {
$file = $this->giteaApi('GET', "{$apiBase}/contents/{$filePath}?ref={$branch}", $token);
$file = $this->gitApi('GET', "{$apiBase}/contents/{$filePath}?ref={$branch}", $token);
if ($file === null || !isset($file['sha']) || !isset($file['content'])) {
return false;
}
@@ -191,7 +191,7 @@ class VersionBumpRemoteCli extends CliFramework
return true;
}
$payload = json_encode(['content' => base64_encode($newContent), 'sha' => $file['sha'], 'message' => $commitMessage, 'branch' => $branch]);
$result = $this->giteaApi('PUT', "{$apiBase}/contents/{$filePath}", $token, $payload);
$result = $this->gitApi('PUT', "{$apiBase}/contents/{$filePath}", $token, $payload);
if ($result === null) {
$this->log('ERROR', "{$filePath}: failed to update");
return false;
+5 -5
View File
@@ -38,14 +38,14 @@ class VersionCheckCli extends CliFramework
$root = realpath($path) ?: $path;
$errors = 0;
$versions = [];
$mokoManifest = "{$root}/.mokogitea/manifest.xml";
$mokoManifest = "{$root}/.mokogit/manifest.xml";
if (file_exists($mokoManifest)) {
$xml = @simplexml_load_file($mokoManifest);
if ($xml !== false) {
$v = (string)($xml->identity->version ?? '');
$base = preg_replace('/(-(dev|alpha|beta|rc))+$/', '', $v);
if (preg_match('/^\d{2}\.\d{2}\.\d{2}$/', $base)) {
$versions['.mokogitea/manifest.xml'] = $base;
$versions['.mokogit/manifest.xml'] = $base;
}
}
}
@@ -124,7 +124,7 @@ class VersionCheckCli extends CliFramework
file_put_contents($readme, $updated);
} echo " Fixed: README.md -> {$highestVersion}\n";
}
if (isset($versions['.mokogitea/manifest.xml']) && $versions['.mokogitea/manifest.xml'] !== $highestVersion) {
if (isset($versions['.mokogit/manifest.xml']) && $versions['.mokogit/manifest.xml'] !== $highestVersion) {
$content = file_get_contents($mokoManifest);
$vPat = '#<version>\d{2}\.\d{2}\.\d{2}'
. '(?:(?:-(?:dev|alpha|beta|rc))+)?</version>#';
@@ -137,7 +137,7 @@ class VersionCheckCli extends CliFramework
if ($updated !== null) {
$updated = preg_replace('#(\s*<version>[^<]*</version>)\s*<version>[^<]*</version>#', '$1', $updated);
file_put_contents($mokoManifest, $updated);
} echo " Fixed: .mokogitea/manifest.xml -> {$highestVersion}\n";
} echo " Fixed: .mokogit/manifest.xml -> {$highestVersion}\n";
}
if (isset($versions['CHANGELOG.md']) && $versions['CHANGELOG.md'] !== $highestVersion) {
$content = file_get_contents($changelog);
@@ -179,7 +179,7 @@ class VersionCheckCli extends CliFramework
} echo " Fixed: pyproject.toml -> {$highestVersion}\n";
}
foreach ($versions as $source => $ver) {
if (in_array($source, ['README.md', 'CHANGELOG.md', '.mokogitea/manifest.xml', 'package.json', 'pyproject.toml'], true)) {
if (in_array($source, ['README.md', 'CHANGELOG.md', '.mokogit/manifest.xml', 'package.json', 'pyproject.toml'], true)) {
continue;
} if ($ver === $highestVersion) {
continue;
+2 -2
View File
@@ -32,10 +32,10 @@ class VersionReadCli extends CliFramework
$path = $this->getArgument('--path');
$root = realpath($path) ?: $path;
// -- 1. Read from .mokogitea/manifest.xml (canonical source) --
// -- 1. Read from .mokogit/manifest.xml (canonical source) --
$mokoVersion = null;
$versionPrefix = '';
$mokoManifest = "{$root}/.mokogitea/manifest.xml";
$mokoManifest = "{$root}/.mokogit/manifest.xml";
if (file_exists($mokoManifest)) {
$xml = @simplexml_load_file($mokoManifest);
if ($xml !== false) {
+11 -11
View File
@@ -10,7 +10,7 @@
* INGROUP: mokocli
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /cli/version_reset_dev.php
* BRIEF: Reset platform version to 'development' on a branch via Gitea API
* BRIEF: Reset platform version to 'development' on a branch via Git API
*/
declare(strict_types=1);
@@ -23,9 +23,9 @@ class VersionResetDevCli extends CliFramework
{
protected function configure(): void
{
$this->setDescription('Reset platform version to development on a branch via Gitea API');
$this->addArgument('--token', 'Gitea API token (also reads MOKOGITEA_TOKEN / GITEA_TOKEN env)', '');
$this->addArgument('--api-base', 'Gitea API base URL for the repo', '');
$this->setDescription('Reset platform version to development on a branch via Git API');
$this->addArgument('--token', 'Git API token (also reads MOKOGIT_TOKEN / GIT_TOKEN env)', '');
$this->addArgument('--api-base', 'Git API base URL for the repo', '');
$this->addArgument('--branch', 'Target branch (default: dev)', 'dev');
$this->addArgument('--platform', 'Platform type: dolibarr, crm-module, joomla, waas-component', '');
$this->addArgument('--path', 'Repo root for auto-detecting platform from manifest.xml', '');
@@ -41,13 +41,13 @@ class VersionResetDevCli extends CliFramework
// Allow token from environment
if ($token === '') {
$envToken = getenv('MOKOGITEA_TOKEN');
$envToken = getenv('MOKOGIT_TOKEN');
if ($envToken !== false && $envToken !== '') {
$token = $envToken;
}
}
if ($token === '') {
$envToken = getenv('GITEA_TOKEN');
$envToken = getenv('GIT_TOKEN');
if ($envToken !== false && $envToken !== '') {
$token = $envToken;
}
@@ -93,7 +93,7 @@ class VersionResetDevCli extends CliFramework
private function detectPlatform(string $repoPath): ?string
{
$root = realpath($repoPath) ?: $repoPath;
$manifestXml = "{$root}/.mokogitea/manifest.xml";
$manifestXml = "{$root}/.mokogit/manifest.xml";
if (!file_exists($manifestXml)) {
return null;
@@ -114,7 +114,7 @@ class VersionResetDevCli extends CliFramework
return null;
}
private function giteaApiCall(string $url, string $token, string $method = 'GET', ?string $body = null): ?array
private function gitApiCall(string $url, string $token, string $method = 'GET', ?string $body = null): ?array
{
$ch = curl_init($url);
if ($ch === false) {
@@ -161,7 +161,7 @@ class VersionResetDevCli extends CliFramework
{
// Search the repo tree for mod*.class.php files
$treeUrl = "{$apiBase}/git/trees/{$branch}?recursive=true";
$tree = $this->giteaApiCall($treeUrl, $token);
$tree = $this->gitApiCall($treeUrl, $token);
if ($tree === null || !isset($tree['tree']) || !is_array($tree['tree'])) {
$this->log('ERROR', "Could not read repository tree for branch '{$branch}'.");
@@ -191,7 +191,7 @@ class VersionResetDevCli extends CliFramework
// GET file contents via API
$encodedPath = implode('/', array_map('rawurlencode', explode('/', $filePath)));
$fileUrl = "{$apiBase}/contents/{$encodedPath}?ref={$branch}";
$fileData = $this->giteaApiCall($fileUrl, $token);
$fileData = $this->gitApiCall($fileUrl, $token);
if ($fileData === null || !isset($fileData['content'])) {
echo "Skipping {$filePath}: could not fetch contents.\n";
@@ -233,7 +233,7 @@ class VersionResetDevCli extends CliFramework
]);
$putUrl = "{$apiBase}/contents/{$encodedPath}";
$result = $this->giteaApiCall($putUrl, $token, 'PUT', $putBody);
$result = $this->gitApiCall($putUrl, $token, 'PUT', $putBody);
if ($result !== null) {
echo "Reset: {$filePath} -> \$this->version = 'development'\n";
+3 -3
View File
@@ -80,8 +80,8 @@ class VersionSetPlatformCli extends CliFramework
// Detect platform — check manifest.xml first, then legacy .mokostandards
$platform = '';
// New format: .mokogitea/manifest.xml (XML with <platform> tag)
$manifestXml = "{$root}/.mokogitea/manifest.xml";
// New format: .mokogit/manifest.xml (XML with <platform> tag)
$manifestXml = "{$root}/.mokogit/manifest.xml";
if (file_exists($manifestXml)) {
$xml = @simplexml_load_file($manifestXml);
if ($xml && isset($xml->governance->platform)) {
@@ -93,7 +93,7 @@ class VersionSetPlatformCli extends CliFramework
if (empty($platform)) {
$mokoStandards = "{$root}/.github/.mokostandards";
if (!file_exists($mokoStandards)) {
$mokoStandards = "{$root}/.mokogitea/manifest.xml";
$mokoStandards = "{$root}/.mokogit/manifest.xml";
}
if (!file_exists($mokoStandards)) {
$mokoStandards = "{$root}/.mokostandards";
+4 -4
View File
@@ -22,7 +22,7 @@ use MokoCli\CliFramework;
class WikiSyncCli extends CliFramework
{
private string $giteaUrl = 'https://git.mokoconsulting.tech';
private string $gitUrl = 'https://git.mokoconsulting.tech';
private string $token = '';
private string $org = 'MokoConsulting';
private string $sourceRepo = 'mokocli';
@@ -39,7 +39,7 @@ class WikiSyncCli extends CliFramework
protected function configure(): void
{
$this->setDescription('Sync wiki pages from mokocli to template repos');
$this->addArgument('--token', 'Gitea API token (required)', '');
$this->addArgument('--token', 'Git API token (required)', '');
$this->addArgument('--org', 'Organization (default: MokoConsulting)', 'MokoConsulting');
$this->addArgument('--source', 'Source repo (default: mokocli)', 'mokocli');
$this->addArgument('--target', 'Target repo (can repeat)', '');
@@ -195,7 +195,7 @@ class WikiSyncCli extends CliFramework
private function apiGet(string $endpoint): ?array
{
$url = "{$this->giteaUrl}/api/v1{$endpoint}";
$url = "{$this->gitUrl}/api/v1{$endpoint}";
$opts = [
'http' => [
'method' => 'GET',
@@ -224,7 +224,7 @@ class WikiSyncCli extends CliFramework
private function apiWrite(string $method, string $endpoint, string $payload): ?array
{
$url = "{$this->giteaUrl}/api/v1{$endpoint}";
$url = "{$this->gitUrl}/api/v1{$endpoint}";
$opts = [
'http' => [
'method' => $method,
+46 -46
View File
@@ -55,8 +55,8 @@ class WorkflowSyncCli extends CliFramework
protected function configure(): void
{
$this->setDescription('Sync workflows from Generic → platform templates → live repos based on manifest.platform');
$this->addArgument('--gitea-url', 'Gitea URL (default: https://git.mokoconsulting.tech)', 'https://git.mokoconsulting.tech');
$this->addArgument('--token', 'Gitea API token', '');
$this->addArgument('--git-url', 'Git URL (default: https://git.mokoconsulting.tech)', 'https://git.mokoconsulting.tech');
$this->addArgument('--token', 'Git API token', '');
$this->addArgument('--org', 'Target organization', '');
$this->addArgument('--branch', 'Target branch (default: main)', 'main');
$this->addArgument('--phase', 'Phase to run: all, templates, repos (default: all)', 'all');
@@ -66,7 +66,7 @@ class WorkflowSyncCli extends CliFramework
protected function run(): int
{
$giteaUrl = rtrim($this->getArgument('--gitea-url'), '/');
$gitUrl = rtrim($this->getArgument('--git-url'), '/');
$token = $this->getArgument('--token');
$org = $this->getArgument('--org');
$branch = $this->getArgument('--branch');
@@ -102,7 +102,7 @@ class WorkflowSyncCli extends CliFramework
// Phase 1: Sync Generic → Platform Templates
if ($phase === 'all' || $phase === 'templates') {
$result = $this->syncGenericToTemplates($giteaUrl, $token, $org, $branch, $platformFilter);
$result = $this->syncGenericToTemplates($gitUrl, $token, $org, $branch, $platformFilter);
if ($result !== 0) {
return $result;
@@ -111,7 +111,7 @@ class WorkflowSyncCli extends CliFramework
// Phase 2: Sync Platform Templates → Live Repos
if ($phase === 'all' || $phase === 'repos') {
$result = $this->syncTemplatesToRepos($giteaUrl, $token, $org, $branch, $platformFilter);
$result = $this->syncTemplatesToRepos($gitUrl, $token, $org, $branch, $platformFilter);
if ($result !== 0) {
return $result;
@@ -130,7 +130,7 @@ class WorkflowSyncCli extends CliFramework
* Skips platform-specific overrides (files that exist in the platform template but NOT in Generic).
*/
private function syncGenericToTemplates(
string $giteaUrl,
string $gitUrl,
string $token,
string $org,
string $branch,
@@ -140,7 +140,7 @@ class WorkflowSyncCli extends CliFramework
echo "\n";
// Get all workflow files from Template-Generic
$genericWorkflows = $this->listWorkflows($giteaUrl, $token, $org, self::GENERIC_TEMPLATE, $branch);
$genericWorkflows = $this->listWorkflows($gitUrl, $token, $org, self::GENERIC_TEMPLATE, $branch);
if ($genericWorkflows === null) {
$this->log('ERROR', 'Could not list workflows from ' . self::GENERIC_TEMPLATE);
@@ -186,12 +186,12 @@ class WorkflowSyncCli extends CliFramework
$this->skipped++;
continue;
}
$destPath = '.mokogitea/workflows/' . $filename;
$destPath = '.mokogit/workflows/' . $filename;
$label = "{$templateRepo}/{$filename}";
// Get file content from Generic
$sourceContent = $this->getFileContent(
$giteaUrl, $token, $org,
$gitUrl, $token, $org,
self::GENERIC_TEMPLATE, $destPath, $branch
);
@@ -204,7 +204,7 @@ class WorkflowSyncCli extends CliFramework
$commitMsg = "chore: sync {$filename} from " . self::GENERIC_TEMPLATE . " [skip ci]";
$this->pushFile(
$giteaUrl, $token, $org, $templateRepo,
$gitUrl, $token, $org, $templateRepo,
$destPath, $sourceContent, $branch, $commitMsg, $label
);
}
@@ -218,7 +218,7 @@ class WorkflowSyncCli extends CliFramework
* Phase 2: Sync platform template workflows to live repos based on manifest.platform.
*/
private function syncTemplatesToRepos(
string $giteaUrl,
string $gitUrl,
string $token,
string $org,
string $branch,
@@ -227,7 +227,7 @@ class WorkflowSyncCli extends CliFramework
$this->log('INFO', '=== Phase 2: Sync Platform Templates → Live Repos ===');
echo "\n";
$repos = $this->fetchOrgRepos($giteaUrl, $token, $org);
$repos = $this->fetchOrgRepos($gitUrl, $token, $org);
if ($repos === null) {
return 1;
@@ -251,7 +251,7 @@ class WorkflowSyncCli extends CliFramework
}
// Read manifest.platform
$platform = $this->getRepoPlatform($giteaUrl, $token, $org, $repoName, $branch);
$platform = $this->getRepoPlatform($gitUrl, $token, $org, $repoName, $branch);
// Apply platform filter
if ($platformFilter !== '' && $platform !== $platformFilter) {
@@ -263,11 +263,11 @@ class WorkflowSyncCli extends CliFramework
// Get workflows from the template (cached)
if (!isset($templateWorkflowCache[$templateRepo])) {
$workflows = $this->listWorkflows($giteaUrl, $token, $org, $templateRepo, $branch);
$workflows = $this->listWorkflows($gitUrl, $token, $org, $templateRepo, $branch);
if ($workflows === null) {
$this->log('WARN', "Could not list workflows from {$templateRepo}, falling back to " . self::GENERIC_TEMPLATE);
$workflows = $this->listWorkflows($giteaUrl, $token, $org, self::GENERIC_TEMPLATE, $branch);
$workflows = $this->listWorkflows($gitUrl, $token, $org, self::GENERIC_TEMPLATE, $branch);
}
$templateWorkflowCache[$templateRepo] = $workflows ?? [];
@@ -281,7 +281,7 @@ class WorkflowSyncCli extends CliFramework
foreach ($workflows as $workflow) {
$filename = $workflow['name'];
$destPath = '.mokogitea/workflows/' . $filename;
$destPath = '.mokogit/workflows/' . $filename;
$label = "{$repoFullName}/{$filename}";
// Skip platform-excluded workflows
@@ -293,7 +293,7 @@ class WorkflowSyncCli extends CliFramework
// Get source content from template
$sourceContent = $this->getFileContent(
$giteaUrl, $token, $org,
$gitUrl, $token, $org,
$templateRepo, $destPath, $branch
);
@@ -306,7 +306,7 @@ class WorkflowSyncCli extends CliFramework
$commitMsg = "chore: sync {$filename} from {$templateRepo} [skip ci]";
$this->pushFile(
$giteaUrl, $token, $org, $repoName,
$gitUrl, $token, $org, $repoName,
$destPath, $sourceContent, $branch, $commitMsg, $label
);
}
@@ -315,7 +315,7 @@ class WorkflowSyncCli extends CliFramework
if ($this->getArgument('--delete-orphans', false)) {
$templateNames = array_map(fn($w) => $w['name'], $workflows);
$this->deleteOrphanWorkflows(
$giteaUrl, $token, $org, $repoName, $branch, $templateNames, $platform
$gitUrl, $token, $org, $repoName, $branch, $templateNames, $platform
);
}
}
@@ -328,7 +328,7 @@ class WorkflowSyncCli extends CliFramework
* Push a file to a repo — create or update, skip if identical.
*/
private function pushFile(
string $giteaUrl,
string $gitUrl,
string $token,
string $org,
string $repoName,
@@ -339,7 +339,7 @@ class WorkflowSyncCli extends CliFramework
string $label
): void {
$existing = $this->apiRequest(
$giteaUrl,
$gitUrl,
$token,
'GET',
"/api/v1/repos/{$org}/{$repoName}/contents/"
@@ -373,7 +373,7 @@ class WorkflowSyncCli extends CliFramework
]);
$response = $this->apiRequest(
$giteaUrl,
$gitUrl,
$token,
'PUT',
"/api/v1/repos/{$org}/{$repoName}/contents/" . $destPath,
@@ -401,7 +401,7 @@ class WorkflowSyncCli extends CliFramework
]);
$response = $this->apiRequest(
$giteaUrl,
$gitUrl,
$token,
'POST',
"/api/v1/repos/{$org}/{$repoName}/contents/" . $destPath,
@@ -431,7 +431,7 @@ class WorkflowSyncCli extends CliFramework
* - Platform-excluded workflows
*/
private function deleteOrphanWorkflows(
string $giteaUrl,
string $gitUrl,
string $token,
string $org,
string $repoName,
@@ -439,7 +439,7 @@ class WorkflowSyncCli extends CliFramework
array $templateNames,
string $platform
): void {
$repoWorkflows = $this->listWorkflows($giteaUrl, $token, $org, $repoName, $branch);
$repoWorkflows = $this->listWorkflows($gitUrl, $token, $org, $repoName, $branch);
if ($repoWorkflows === null) {
return;
}
@@ -469,7 +469,7 @@ class WorkflowSyncCli extends CliFramework
}
// Delete orphan
$filePath = '.mokogitea/workflows/' . $name;
$filePath = '.mokogit/workflows/' . $name;
$label = "{$org}/{$repoName}/{$name}";
if ($this->dryRun) {
@@ -478,7 +478,7 @@ class WorkflowSyncCli extends CliFramework
continue;
}
$deleted = $this->deleteFile($giteaUrl, $token, $org, $repoName, $filePath, $branch);
$deleted = $this->deleteFile($gitUrl, $token, $org, $repoName, $filePath, $branch);
if ($deleted) {
fprintf(STDERR, "%-45s | %s\n", $label, 'DELETED');
$this->deleted++;
@@ -490,10 +490,10 @@ class WorkflowSyncCli extends CliFramework
}
/**
* Delete a file from a repo via the Gitea Contents API.
* Delete a file from a repo via the Git Contents API.
*/
private function deleteFile(
string $giteaUrl,
string $gitUrl,
string $token,
string $org,
string $repoName,
@@ -502,7 +502,7 @@ class WorkflowSyncCli extends CliFramework
): bool {
// Get SHA first
$existing = $this->apiRequest(
$giteaUrl, $token, 'GET',
$gitUrl, $token, 'GET',
"/api/v1/repos/{$org}/{$repoName}/contents/{$filePath}?ref={$branch}"
);
@@ -523,7 +523,7 @@ class WorkflowSyncCli extends CliFramework
]);
$response = $this->apiRequest(
$giteaUrl, $token, 'DELETE',
$gitUrl, $token, 'DELETE',
"/api/v1/repos/{$org}/{$repoName}/contents/{$filePath}",
$payload
);
@@ -532,20 +532,20 @@ class WorkflowSyncCli extends CliFramework
}
/**
* List workflow files in a repo's .mokogitea/workflows/ directory.
* List workflow files in a repo's .mokogit/workflows/ directory.
*/
private function listWorkflows(
string $giteaUrl,
string $gitUrl,
string $token,
string $org,
string $repoName,
string $branch
): ?array {
$response = $this->apiRequest(
$giteaUrl,
$gitUrl,
$token,
'GET',
"/api/v1/repos/{$org}/{$repoName}/contents/.mokogitea/workflows?ref={$branch}"
"/api/v1/repos/{$org}/{$repoName}/contents/.mokogit/workflows?ref={$branch}"
);
if ($response['code'] !== 200) {
@@ -566,7 +566,7 @@ class WorkflowSyncCli extends CliFramework
* Get file content from a repo as a raw string.
*/
private function getFileContent(
string $giteaUrl,
string $gitUrl,
string $token,
string $org,
string $repoName,
@@ -574,7 +574,7 @@ class WorkflowSyncCli extends CliFramework
string $branch
): ?string {
$response = $this->apiRequest(
$giteaUrl,
$gitUrl,
$token,
'GET',
"/api/v1/repos/{$org}/{$repoName}/contents/{$filePath}?ref={$branch}"
@@ -594,20 +594,20 @@ class WorkflowSyncCli extends CliFramework
}
/**
* Read a repo's platform from the MokoGitea metadata API.
* Read a repo's platform from the MokoGit metadata API.
* Returns 'generic' if metadata is missing or has no platform field.
* (Replaces the retired .mokogitea/manifest.xml lookup — platform now lives
* (Replaces the retired .mokogit/manifest.xml lookup — platform now lives
* in the repo Metadata endpoint: GET /api/v1/repos/{owner}/{repo}/metadata.)
*/
private function getRepoPlatform(
string $giteaUrl,
string $gitUrl,
string $token,
string $org,
string $repoName,
string $branch
): string {
$response = $this->apiRequest(
$giteaUrl,
$gitUrl,
$token,
'GET',
"/api/v1/repos/{$org}/{$repoName}/metadata"
@@ -629,7 +629,7 @@ class WorkflowSyncCli extends CliFramework
/**
* Fetch all non-archived repos in an org (paginated).
*/
private function fetchOrgRepos(string $giteaUrl, string $token, string $org): ?array
private function fetchOrgRepos(string $gitUrl, string $token, string $org): ?array
{
$this->log('INFO', "Fetching repos from org: {$org}");
@@ -638,7 +638,7 @@ class WorkflowSyncCli extends CliFramework
while (true) {
$response = $this->apiRequest(
$giteaUrl,
$gitUrl,
$token,
'GET',
"/api/v1/orgs/{$org}/repos?"
@@ -680,16 +680,16 @@ class WorkflowSyncCli extends CliFramework
}
/**
* Make an HTTP request to the Gitea API.
* Make an HTTP request to the Git API.
*/
private function apiRequest(
string $giteaUrl,
string $gitUrl,
string $token,
string $method,
string $endpoint,
?string $body = null
): array {
$url = $giteaUrl . $endpoint;
$url = $gitUrl . $endpoint;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
+1 -1
View File
@@ -61,7 +61,7 @@ Shared library code
- GitHub client
### [Wiki](https://git.mokoconsulting.tech/MokoConsulting/mokocli/wiki)
All documentation lives in the MokoGitea wiki.
All documentation lives in the MokoGit wiki.
### [Tests](tests/)
Test scripts
+1 -1
View File
@@ -154,7 +154,7 @@ class ApiClient
* @param bool $enableCaching Enable response caching
* @param string $userAgent User agent string
* @param LoggerInterface|null $logger Optional logger
* @param string $authScheme Authorization scheme ('Bearer' for GitHub, 'token' for Gitea)
* @param string $authScheme Authorization scheme ('Bearer' for GitHub, 'token' for Git)
*/
public function __construct(
string $baseUrl,
+10 -10
View File
@@ -74,14 +74,14 @@ class Config
private const DEFAULT_CONFIG = [
'version' => '04.00.04',
'environment' => 'development',
'platform' => 'gitea',
'platform' => 'git',
'github' => [
'organization' => 'mokoconsulting-tech',
'rate_limit' => 5000,
'max_retries' => 3,
'timeout' => 30,
],
'gitea' => [
'git' => [
'url' => 'https://git.mokoconsulting.tech',
'organization' => 'mokoconsulting-tech',
'rate_limit' => 5000,
@@ -227,16 +227,16 @@ class Config
$configData['github']['organization'] = $org;
}
// Gitea token resolution: GA_TOKEN env var (Gitea Actions)
$giteaToken = getenv('GA_TOKEN') ?: '';
if (!empty($giteaToken)) {
$configData['gitea']['token'] = $giteaToken;
// Git token resolution: GA_TOKEN env var (Git Actions)
$gitToken = getenv('GA_TOKEN') ?: '';
if (!empty($gitToken)) {
$configData['git']['token'] = $gitToken;
}
if ($giteaUrl = getenv('GITEA_URL')) {
$configData['gitea']['url'] = rtrim($giteaUrl, '/');
if ($gitUrl = getenv('GIT_URL')) {
$configData['git']['url'] = rtrim($gitUrl, '/');
}
if ($giteaOrg = getenv('GITEA_ORG')) {
$configData['gitea']['organization'] = $giteaOrg;
if ($gitOrg = getenv('GIT_ORG')) {
$configData['git']['organization'] = $gitOrg;
}
// Logging configuration
+1 -1
View File
@@ -419,7 +419,7 @@ class GitHubAdapter implements GitPlatformAdapter
public function migrateRepository(array $options): array
{
throw new RuntimeException('Repository migration is not supported on GitHub — use Gitea\'s built-in migration');
throw new RuntimeException('Repository migration is not supported on GitHub — use Git\'s built-in migration');
}
// ──────────────────────────────────────────────
+10 -10
View File
@@ -11,7 +11,7 @@
* INGROUP: MokoCLI.Enterprise
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /lib/Enterprise/GitPlatformAdapter.php
* BRIEF: Interface defining all git platform operations for GitHub/Gitea abstraction
* BRIEF: Interface defining all git platform operations for GitHub/Git abstraction
*/
declare(strict_types=1);
@@ -22,7 +22,7 @@ namespace MokoCli;
* Git Platform Adapter Interface
*
* Defines all platform operations required by mokocli automation.
* Implementations exist for GitHub (GitHubAdapter) and Gitea (MokoGiteaAdapter),
* Implementations exist for GitHub (GitHubAdapter) and Git (MokoGitAdapter),
* allowing scripts to work against either platform transparently.
*
* @package MokoCLI\Enterprise
@@ -37,7 +37,7 @@ interface GitPlatformAdapter
/**
* Get the platform name identifier.
*
* @return string 'github' or 'gitea'
* @return string 'github' or 'git'
*/
public function getPlatformName(): string;
@@ -51,14 +51,14 @@ interface GitPlatformAdapter
/**
* Get the workflow directory name for this platform.
*
* @return string '.github/workflows' or '.mokogitea/workflows'
* @return string '.github/workflows' or '.mokogit/workflows'
*/
public function getWorkflowDir(): string;
/**
* Get the platform-specific metadata directory.
*
* @return string '.github' or '.mokogitea'
* @return string '.github' or '.mokogit'
*/
public function getMetadataDir(): string;
@@ -104,7 +104,7 @@ interface GitPlatformAdapter
/**
* Get the environment variable name for step summary output (CI-specific).
*
* @return string 'GITHUB_STEP_SUMMARY' or 'GITEA_STEP_SUMMARY'
* @return string 'GITHUB_STEP_SUMMARY' or 'GIT_STEP_SUMMARY'
*/
public function getStepSummaryEnvVar(): string;
@@ -379,7 +379,7 @@ interface GitPlatformAdapter
* @param string $org Organization name
* @param string $repo Repository name
* @param int $number Issue/PR number
* @param array<string> $labels Label names (GitHub) or label IDs (Gitea)
* @param array<string> $labels Label names (GitHub) or label IDs (Git)
* @return array<string, mixed> API response
*/
public function addIssueLabels(string $org, string $repo, int $number, array $labels): array;
@@ -391,7 +391,7 @@ interface GitPlatformAdapter
/**
* Set branch protection rules.
*
* On GitHub this maps to rulesets; on Gitea to branch_protections.
* On GitHub this maps to rulesets; on Git to branch_protections.
*
* @param string $org Organization name
* @param string $repo Repository name
@@ -450,13 +450,13 @@ interface GitPlatformAdapter
public function paginateAll(string $endpoint, array $params = [], int $perPage = 100): array;
// ──────────────────────────────────────────────
// Migration (Gitea-specific, no-op on GitHub)
// Migration (Git-specific, no-op on GitHub)
// ──────────────────────────────────────────────
/**
* Migrate a repository from an external service.
*
* On Gitea, this calls POST /api/v1/repos/migrate.
* On Git, this calls POST /api/v1/repos/migrate.
* On GitHub, this is a no-op (throws UnsupportedOperationException).
*
* @param array<string, mixed> $options Migration options (clone_addr, service, auth_token, etc.)
+1 -1
View File
@@ -26,7 +26,7 @@ use SimpleXMLElement;
* MokoCli Parser
*
* Reads, writes, and validates the manifest.xml repository manifest.
* The file uses XML format (no file extension) and lives at .mokogitea/manifest.xml.
* The file uses XML format (no file extension) and lives at .mokogit/manifest.xml.
*
* @package MokoCLI\Enterprise
* @version 04.07.00
+5 -5
View File
@@ -11,7 +11,7 @@
* INGROUP: mokocli
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /lib/Enterprise/ManifestReader.php
* BRIEF: Read and parse .mokogitea/manifest.xml — shared across all CLI tools
* BRIEF: Read and parse .mokogit/manifest.xml — shared across all CLI tools
*/
declare(strict_types=1);
@@ -21,7 +21,7 @@ namespace MokoCli;
/**
* Manifest Reader
*
* Parses .mokogitea/manifest.xml and provides typed access to all fields.
* Parses .mokogit/manifest.xml and provides typed access to all fields.
* Used by CLI tools and the Enterprise library to determine platform,
* build configuration, and deployment settings from the repository manifest.
*
@@ -56,9 +56,9 @@ class ManifestReader
public function load(string $root): void
{
$candidates = [
"{$root}/.mokogitea/manifest.xml",
"{$root}/.mokogitea/.manifest.xml",
"{$root}/.mokogitea/.mokocli",
"{$root}/.mokogit/manifest.xml",
"{$root}/.mokogit/.manifest.xml",
"{$root}/.mokogit/.mokocli",
];
$manifestFile = null;
+27 -27
View File
@@ -10,8 +10,8 @@
* DEFGROUP: MokoCLI.Enterprise.Platform
* INGROUP: MokoCLI.Enterprise
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /lib/Enterprise/MokoGiteaAdapter.php
* BRIEF: Gitea implementation of GitPlatformAdapter
* PATH: /lib/Enterprise/MokoGitAdapter.php
* BRIEF: Git implementation of GitPlatformAdapter
*/
declare(strict_types=1);
@@ -22,32 +22,32 @@ use Exception;
use RuntimeException;
/**
* Gitea implementation of GitPlatformAdapter.
* Git implementation of GitPlatformAdapter.
*
* Wraps ApiClient with Gitea-specific API semantics:
* Wraps ApiClient with Git-specific API semantics:
* - Base URL: https://git.mokoconsulting.tech/api/v1
* - Auth: token {token}
* - Pagination: limit + page params
* - File ops: POST for create, PUT for update (check existence first)
* - Topics: PUT with {"topics": [...]}
* - Branch protection: flat API (not rulesets)
* - Workflow dir: .mokogitea/workflows
* - Workflow dir: .mokogit/workflows
*
* @package MokoCLI\Enterprise
* @since 04.06.10
* @see GitPlatformAdapter
*/
class MokoGiteaAdapter implements GitPlatformAdapter
class MokoGitAdapter implements GitPlatformAdapter
{
/** @var ApiClient HTTP client for Gitea API calls. */
/** @var ApiClient HTTP client for Git API calls. */
private ApiClient $apiClient;
/** @var string Base URL for Gitea API (e.g. https://git.mokoconsulting.tech/api/v1). */
/** @var string Base URL for Git API (e.g. https://git.mokoconsulting.tech/api/v1). */
private string $baseUrl;
/**
* @param ApiClient $apiClient Configured API client
* @param string $baseUrl Gitea API base URL
* @param string $baseUrl Git API base URL
*/
public function __construct(ApiClient $apiClient, string $baseUrl = 'https://git.mokoconsulting.tech/api/v1')
{
@@ -61,7 +61,7 @@ class MokoGiteaAdapter implements GitPlatformAdapter
public function getPlatformName(): string
{
return 'gitea';
return 'git';
}
public function getBaseUrl(): string
@@ -71,12 +71,12 @@ class MokoGiteaAdapter implements GitPlatformAdapter
public function getWorkflowDir(): string
{
return '.mokogitea/workflows';
return '.mokogit/workflows';
}
public function getMetadataDir(): string
{
return '.mokogitea';
return '.mokogit';
}
public function getRepoWebUrl(string $org, string $repo): string
@@ -88,7 +88,7 @@ class MokoGiteaAdapter implements GitPlatformAdapter
public function getPullRequestWebUrl(string $org, string $repo, int $number): string
{
// Gitea uses /pulls/ (not /pull/) for web UI
// Git uses /pulls/ (not /pull/) for web UI
$webBase = preg_replace('#/api/v1$#', '', $this->baseUrl);
return "{$webBase}/{$org}/{$repo}/pulls/{$number}";
}
@@ -106,14 +106,14 @@ class MokoGiteaAdapter implements GitPlatformAdapter
public function getBranchWebUrl(string $org, string $repo, string $branch): string
{
// Gitea uses /src/branch/ (not /tree/) for web UI
// Git uses /src/branch/ (not /tree/) for web UI
$webBase = preg_replace('#/api/v1$#', '', $this->baseUrl);
return "{$webBase}/{$org}/{$repo}/src/branch/{$branch}";
}
public function getStepSummaryEnvVar(): string
{
return 'GITEA_STEP_SUMMARY';
return 'GIT_STEP_SUMMARY';
}
// ──────────────────────────────────────────────
@@ -157,7 +157,7 @@ class MokoGiteaAdapter implements GitPlatformAdapter
public function archiveRepo(string $org, string $repo): array
{
// Gitea uses PATCH with archived flag, same as GitHub
// Git uses PATCH with archived flag, same as GitHub
return $this->apiClient->patch("/repos/{$org}/{$repo}", [
'archived' => true,
]);
@@ -165,7 +165,7 @@ class MokoGiteaAdapter implements GitPlatformAdapter
public function setRepoTopics(string $org, string $repo, array $topics): void
{
// Gitea uses {"topics": [...]} not {"names": [...]}
// Git uses {"topics": [...]} not {"names": [...]}
$this->apiClient->put("/repos/{$org}/{$repo}/topics", [
'topics' => $topics,
]);
@@ -209,12 +209,12 @@ class MokoGiteaAdapter implements GitPlatformAdapter
}
if ($sha !== null) {
// Update existing file — Gitea uses PUT with SHA
// Update existing file — Git uses PUT with SHA
$data['sha'] = $sha;
return $this->apiClient->put("/repos/{$org}/{$repo}/contents/{$path}", $data);
}
// Create new file — Gitea uses POST
// Create new file — Git uses POST
return $this->apiClient->post("/repos/{$org}/{$repo}/contents/{$path}", $data);
}
@@ -226,7 +226,7 @@ class MokoGiteaAdapter implements GitPlatformAdapter
string $message,
?string $branch = null
): array {
// Gitea's delete uses the same endpoint but with DELETE method
// Git's delete uses the same endpoint but with DELETE method
// ApiClient::delete() doesn't support a body, so we use the raw approach
// For now, this matches GitHubAdapter's limitation
return $this->apiClient->delete("/repos/{$org}/{$repo}/contents/{$path}");
@@ -281,7 +281,7 @@ class MokoGiteaAdapter implements GitPlatformAdapter
string $body = '',
array $options = []
): array {
// Gitea expects label IDs (int64), not names. Resolve if needed.
// Git expects label IDs (int64), not names. Resolve if needed.
if (!empty($options['labels']) && is_string($options['labels'][0] ?? null)) {
$labelNames = $options['labels'];
$existing = $this->listLabels($org, $repo);
@@ -330,7 +330,7 @@ class MokoGiteaAdapter implements GitPlatformAdapter
public function createLabel(string $org, string $repo, string $name, string $color, string $description = ''): array
{
// Gitea expects color with # prefix
// Git expects color with # prefix
$color = ltrim($color, '#');
return $this->apiClient->post("/repos/{$org}/{$repo}/labels", [
'name' => $name,
@@ -341,7 +341,7 @@ class MokoGiteaAdapter implements GitPlatformAdapter
public function addIssueLabels(string $org, string $repo, int $number, array $labels): array
{
// Gitea requires label IDs, not names. Resolve names to IDs first.
// Git requires label IDs, not names. Resolve names to IDs first.
$allLabels = $this->listLabels($org, $repo);
$labelMap = [];
foreach ($allLabels as $label) {
@@ -372,7 +372,7 @@ class MokoGiteaAdapter implements GitPlatformAdapter
public function setBranchProtection(string $org, string $repo, string $branch, array $rules): array
{
// Gitea uses a flat branch protection API
// Git uses a flat branch protection API
$whitelistActions = $rules['whitelist_actions_user'] ?? false;
$protection = [
'branch_name' => $branch,
@@ -421,7 +421,7 @@ class MokoGiteaAdapter implements GitPlatformAdapter
// Try as a tag first
try {
$tag = $this->apiClient->get("/repos/{$org}/{$repo}/git/tags/{$ref}");
// Gitea tag objects have a 'commit' field with the SHA
// Git tag objects have a 'commit' field with the SHA
if (isset($tag['commit']['sha'])) {
return $tag['commit']['sha'];
}
@@ -458,7 +458,7 @@ class MokoGiteaAdapter implements GitPlatformAdapter
{
$all = [];
$page = 1;
// Gitea uses 'limit' instead of 'per_page'
// Git uses 'limit' instead of 'per_page'
$params['limit'] = $perPage;
while (true) {
@@ -488,7 +488,7 @@ class MokoGiteaAdapter implements GitPlatformAdapter
public function migrateRepository(array $options): array
{
// Gitea's built-in migration endpoint
// Git's built-in migration endpoint
$data = array_merge([
'service' => 'github',
'issues' => true,
+28 -28
View File
@@ -44,18 +44,18 @@ class PlatformAdapterFactory
* Create a GitPlatformAdapter based on configuration.
*
* @param Config $config Configuration instance
* @param string|null $platformOverride Force a specific platform ('github' or 'gitea')
* @param string|null $platformOverride Force a specific platform ('github' or 'git')
* @return GitPlatformAdapter The constructed adapter
* @throws RuntimeException If the platform is not supported or token is missing
*/
public static function create(Config $config, ?string $platformOverride = null): GitPlatformAdapter
{
$platform = $platformOverride ?? $config->getString('platform', 'gitea');
$platform = $platformOverride ?? $config->getString('platform', 'git');
return match ($platform) {
'github' => self::createGitHubAdapter($config),
'gitea' => self::createMokoGiteaAdapter($config),
default => throw new RuntimeException("Unsupported git platform: {$platform}. Use 'github' or 'gitea'."),
'git' => self::createMokoGitAdapter($config),
default => throw new RuntimeException("Unsupported git platform: {$platform}. Use 'github' or 'git'."),
};
}
@@ -87,54 +87,54 @@ class PlatformAdapterFactory
}
/**
* Create a MokoGiteaAdapter with configured ApiClient.
* Create a MokoGitAdapter with configured ApiClient.
*
* @param Config $config Configuration instance
* @return MokoGiteaAdapter Configured Gitea adapter
* @throws RuntimeException If Gitea token is not available
* @return MokoGitAdapter Configured Git adapter
* @throws RuntimeException If Git token is not available
*/
private static function createMokoGiteaAdapter(Config $config): MokoGiteaAdapter
private static function createMokoGitAdapter(Config $config): MokoGitAdapter
{
$token = $config->getString('gitea.token', '');
$token = $config->getString('git.token', '');
if (empty($token)) {
throw new RuntimeException(
'Gitea token not found. Set GA_TOKEN environment variable.'
'Git token not found. Set GA_TOKEN environment variable.'
);
}
$giteaUrl = $config->getString('gitea.url', 'https://git.mokoconsulting.tech');
$apiBaseUrl = rtrim($giteaUrl, '/') . '/api/v1';
$gitUrl = $config->getString('git.url', 'https://git.mokoconsulting.tech');
$apiBaseUrl = rtrim($gitUrl, '/') . '/api/v1';
$apiClient = new ApiClient(
baseUrl: $apiBaseUrl,
authToken: $token,
maxRequestsPerHour: $config->getInt('gitea.rate_limit', 5000),
maxRetries: $config->getInt('gitea.max_retries', 3),
maxRequestsPerHour: $config->getInt('git.rate_limit', 5000),
maxRetries: $config->getInt('git.max_retries', 3),
authScheme: 'token'
);
return new MokoGiteaAdapter($apiClient, $apiBaseUrl);
return new MokoGitAdapter($apiClient, $apiBaseUrl);
}
/**
* Create adapters for both platforms (useful during migration).
*
* @param Config $config Configuration instance
* @return array{github: GitHubAdapter, gitea: MokoGiteaAdapter} Both adapters
* @return array{github: GitHubAdapter, git: MokoGitAdapter} Both adapters
* @throws RuntimeException If either token is missing
*/
public static function createBoth(Config $config): array
{
return [
'github' => self::createGitHubAdapter($config),
'gitea' => self::createMokoGiteaAdapter($config),
'git' => self::createMokoGitAdapter($config),
];
}
/**
* Sync a file between Gitea (primary) and GitHub (mirror) for a given repo.
* Sync a file between Git (primary) and GitHub (mirror) for a given repo.
*
* Reads the file from Gitea and pushes it to GitHub, ensuring both platforms
* Reads the file from Git and pushes it to GitHub, ensuring both platforms
* serve identical content. Commonly used for updates.xml sync after releases.
*
* @param Config $config Configuration instance
@@ -151,18 +151,18 @@ class PlatformAdapterFactory
string $filePath = 'updates.xml'
): bool {
$adapters = self::createBoth($config);
$giteaOrg = $config->getString('gitea.organization', 'mokoconsulting-tech');
$gitOrg = $config->getString('git.organization', 'mokoconsulting-tech');
$githubOrg = $config->getString('github.organization', 'mokoconsulting-tech');
// Read from Gitea (primary)
// Read from Git (primary)
try {
$giteaFile = $adapters['gitea']->getFileContents($giteaOrg, $repo, $filePath, $branch);
$gitFile = $adapters['git']->getFileContents($gitOrg, $repo, $filePath, $branch);
} catch (\Exception $e) {
throw new RuntimeException("Failed to read {$filePath} from Gitea ({$giteaOrg}/{$repo}): " . $e->getMessage());
throw new RuntimeException("Failed to read {$filePath} from Git ({$gitOrg}/{$repo}): " . $e->getMessage());
}
$giteaContent = base64_decode($giteaFile['content'] ?? '');
if (empty($giteaContent)) {
$gitContent = base64_decode($gitFile['content'] ?? '');
if (empty($gitContent)) {
return false;
}
@@ -173,7 +173,7 @@ class PlatformAdapterFactory
$githubContent = base64_decode($githubFile['content'] ?? '');
$githubSha = $githubFile['sha'] ?? null;
if ($githubContent === $giteaContent) {
if ($githubContent === $gitContent) {
return true;
}
} catch (\Exception $e) {
@@ -184,8 +184,8 @@ class PlatformAdapterFactory
$githubOrg,
$repo,
$filePath,
$giteaContent,
"chore(sync): sync {$filePath} from Gitea primary",
$gitContent,
"chore(sync): sync {$filePath} from Git primary",
$githubSha,
$branch
);
+3 -3
View File
@@ -288,7 +288,7 @@ class ApiPlugin extends AbstractProjectPlugin
'docker-compose.yml',
'kubernetes/*.yaml',
'tests/ or test/',
'.mokogitea/workflows/* or .gitea/workflows/* or .gitlab-ci.yml',
'.mokogit/workflows/* or .gitea/workflows/* or .gitlab-ci.yml',
'middleware/ or middlewares/',
];
}
@@ -696,8 +696,8 @@ class ApiPlugin extends AbstractProjectPlugin
*/
private function hasCICD(string $projectPath): bool
{
return $this->fileExists($projectPath, '.mokogitea/workflows') ||
$this->fileExists($projectPath, '.mokogitea/workflows') ||
return $this->fileExists($projectPath, '.mokogit/workflows') ||
$this->fileExists($projectPath, '.mokogit/workflows') ||
$this->fileExists($projectPath, '.gitlab-ci.yml') ||
$this->fileExists($projectPath, 'Jenkinsfile') ||
$this->fileExists($projectPath, '.circleci');
+5 -5
View File
@@ -80,8 +80,8 @@ class GenericPlugin extends AbstractProjectPlugin
}
// Check for CI/CD configuration
$hasCICD = $this->fileExists($projectPath, '.mokogitea/workflows') ||
$this->fileExists($projectPath, '.mokogitea/workflows') ||
$hasCICD = $this->fileExists($projectPath, '.mokogit/workflows') ||
$this->fileExists($projectPath, '.mokogit/workflows') ||
$this->fileExists($projectPath, '.gitlab-ci.yml') ||
$this->fileExists($projectPath, '.travis.yml') ||
$this->fileExists($projectPath, 'Jenkinsfile') ||
@@ -288,7 +288,7 @@ class GenericPlugin extends AbstractProjectPlugin
'CONTRIBUTING.md',
'CODE_OF_CONDUCT.md',
'SECURITY.md',
'.mokogitea/workflows/* or .gitea/workflows/* or .gitlab-ci.yml',
'.mokogit/workflows/* or .gitea/workflows/* or .gitlab-ci.yml',
'docs/ or documentation/',
'tests/ or test/',
];
@@ -372,8 +372,8 @@ class GenericPlugin extends AbstractProjectPlugin
*/
private function hasCICD(string $projectPath): bool
{
return $this->fileExists($projectPath, '.mokogitea/workflows') ||
$this->fileExists($projectPath, '.mokogitea/workflows') ||
return $this->fileExists($projectPath, '.mokogit/workflows') ||
$this->fileExists($projectPath, '.mokogit/workflows') ||
$this->fileExists($projectPath, '.gitlab-ci.yml') ||
$this->fileExists($projectPath, '.travis.yml') ||
$this->fileExists($projectPath, 'Jenkinsfile') ||
+3 -3
View File
@@ -344,7 +344,7 @@ class MobilePlugin extends AbstractProjectPlugin
'App icons for all required sizes',
'Splash screen assets',
'tests/ or __tests__/',
'.mokogitea/workflows/* or .gitea/workflows/* or fastlane/',
'.mokogit/workflows/* or .gitea/workflows/* or fastlane/',
'React Native: metro.config.js',
'Flutter: analysis_options.yaml',
'iOS: Podfile',
@@ -551,8 +551,8 @@ class MobilePlugin extends AbstractProjectPlugin
*/
private function hasCICD(string $projectPath): bool
{
return $this->fileExists($projectPath, '.mokogitea/workflows') ||
$this->fileExists($projectPath, '.mokogitea/workflows') ||
return $this->fileExists($projectPath, '.mokogit/workflows') ||
$this->fileExists($projectPath, '.mokogit/workflows') ||
$this->fileExists($projectPath, '.gitlab-ci.yml') ||
$this->fileExists($projectPath, 'fastlane') ||
$this->fileExists($projectPath, '.circleci');
+3 -3
View File
@@ -327,7 +327,7 @@ class NodeJsPlugin extends AbstractProjectPlugin
'.nvmrc or .node-version',
'.editorconfig',
'jest.config.js or vitest.config.js',
'.mokogitea/workflows/* or .gitea/workflows/* or .gitlab-ci.yml',
'.mokogit/workflows/* or .gitea/workflows/* or .gitlab-ci.yml',
];
}
@@ -539,8 +539,8 @@ class NodeJsPlugin extends AbstractProjectPlugin
*/
private function hasCICD(string $projectPath): bool
{
return $this->fileExists($projectPath, '.mokogitea/workflows') ||
$this->fileExists($projectPath, '.mokogitea/workflows') ||
return $this->fileExists($projectPath, '.mokogit/workflows') ||
$this->fileExists($projectPath, '.mokogit/workflows') ||
$this->fileExists($projectPath, '.gitlab-ci.yml') ||
$this->fileExists($projectPath, '.travis.yml') ||
$this->fileExists($projectPath, '.circleci/config.yml');
+3 -3
View File
@@ -344,7 +344,7 @@ class PythonPlugin extends AbstractProjectPlugin
'pytest.ini or pyproject.toml',
'.python-version or .tool-versions',
'Dockerfile',
'.mokogitea/workflows/* or .gitea/workflows/* or .gitlab-ci.yml',
'.mokogit/workflows/* or .gitea/workflows/* or .gitlab-ci.yml',
];
}
@@ -566,8 +566,8 @@ class PythonPlugin extends AbstractProjectPlugin
*/
private function hasCICD(string $projectPath): bool
{
return $this->fileExists($projectPath, '.mokogitea/workflows') ||
$this->fileExists($projectPath, '.mokogitea/workflows') ||
return $this->fileExists($projectPath, '.mokogit/workflows') ||
$this->fileExists($projectPath, '.mokogit/workflows') ||
$this->fileExists($projectPath, '.gitlab-ci.yml') ||
$this->fileExists($projectPath, '.travis.yml') ||
$this->fileExists($projectPath, 'tox.ini');
+4 -4
View File
@@ -126,13 +126,13 @@ class ProjectMetricsCollector
// CI/CD — check both .github/workflows and .gitea/workflows
$hasGithubWf = is_dir("{$path}/.github/workflows");
$hasGiteaWf = is_dir("{$path}/.mokogitea/workflows");
$this->collectedMetrics['has_ci_workflows'] = ($hasGithubWf || $hasGiteaWf) ? 1 : 0;
$hasGitWf = is_dir("{$path}/.mokogit/workflows");
$this->collectedMetrics['has_ci_workflows'] = ($hasGithubWf || $hasGitWf) ? 1 : 0;
$this->collectedMetrics['workflow_count'] =
$this->countFiles("{$path}/.github/workflows", '*.yml') +
$this->countFiles("{$path}/.github/workflows", '*.yaml') +
$this->countFiles("{$path}/.mokogitea/workflows", '*.yml') +
$this->countFiles("{$path}/.mokogitea/workflows", '*.yaml');
$this->countFiles("{$path}/.mokogit/workflows", '*.yml') +
$this->countFiles("{$path}/.mokogit/workflows", '*.yaml');
}
private function collectNodeJSMetrics(string $path): void
+8 -8
View File
@@ -206,9 +206,9 @@ class RepositoryHealthChecker
// Check both .github/workflows and .gitea/workflows
$githubDir = "{$path}/.github/workflows";
$giteaDir = "{$path}/.mokogitea/workflows";
$hasWorkflowDir = is_dir($githubDir) || is_dir($giteaDir);
$workflowDir = is_dir($giteaDir) ? $giteaDir : $githubDir;
$gitDir = "{$path}/.mokogit/workflows";
$hasWorkflowDir = is_dir($githubDir) || is_dir($gitDir);
$workflowDir = is_dir($gitDir) ? $gitDir : $githubDir;
// Check workflows directory exists
$this->addCheck(
@@ -253,15 +253,15 @@ class RepositoryHealthChecker
10
);
// Check for security scanning workflow (CodeQL on GitHub, Trivy on Gitea)
// Check for security scanning workflow (CodeQL on GitHub, Trivy on Git)
$githubWf = "{$path}/.github/workflows";
$giteaWf = "{$path}/.mokogitea/workflows";
$gitWf = "{$path}/.mokogit/workflows";
$hasSecurityScan = false;
if (is_dir($githubWf)) {
$hasSecurityScan = !empty(glob("{$githubWf}/*codeql*.yml")) || !empty(glob("{$githubWf}/*codeql*.yaml"));
}
if (!$hasSecurityScan && is_dir($giteaWf)) {
$hasSecurityScan = !empty(glob("{$giteaWf}/*trivy*.yml")) || !empty(glob("{$giteaWf}/*trivy*.yaml"));
if (!$hasSecurityScan && is_dir($gitWf)) {
$hasSecurityScan = !empty(glob("{$gitWf}/*trivy*.yml")) || !empty(glob("{$gitWf}/*trivy*.yaml"));
}
$this->addCheck(
$category,
@@ -270,7 +270,7 @@ class RepositoryHealthChecker
10
);
// Check for dependency management (Dependabot on GitHub, Renovate on Gitea)
// Check for dependency management (Dependabot on GitHub, Renovate on Git)
$this->addCheck(
$category,
'Dependency management configured',
+8 -8
View File
@@ -62,7 +62,7 @@ class RepositorySynchronizer
?CheckpointManager $checkpoints = null,
?GitPlatformAdapter $adapter = null
) {
$this->adapter = $adapter ?? new MokoGiteaAdapter($apiClient);
$this->adapter = $adapter ?? new MokoGitAdapter($apiClient);
$this->logger = $logger;
$this->metrics = $metrics;
$this->checkpoints = $checkpoints ?? new CheckpointManager('.checkpoints');
@@ -266,7 +266,7 @@ class RepositorySynchronizer
/**
* Read the platform slug from the remote manifest.xml.
* Checks .mokogitea/manifest.xml, then legacy locations (.mokostandards, .github/.mokostandards).
* Checks .mokogit/manifest.xml, then legacy locations (.mokostandards, .github/.mokostandards).
*
* @return string|null Platform slug or null if not found/parseable
*/
@@ -278,7 +278,7 @@ class RepositorySynchronizer
"{$metaDir}/.mokostandards",
'.mokostandards',
];
if ($metaDir === '.mokogitea') {
if ($metaDir === '.mokogit') {
$paths[] = '.github/.mokostandards';
}
@@ -637,7 +637,7 @@ class RepositorySynchronizer
* and convert legacy YAML-like format to the new XML manifest.
*
* Handles:
* 1. Location migration: root or .github/ → .mokogitea/manifest.xml
* 1. Location migration: root or .github/ → .mokogit/manifest.xml
* 2. Format migration: legacy "platform: xxx" → XML manifest
* 3. Update existing XML: refresh <governance><last-synced> timestamp
*/
@@ -654,7 +654,7 @@ class RepositorySynchronizer
// ── Collect existing files from all legacy locations ─────────
$legacySources = ['.mokostandards'];
if ($metaDir === '.mokogitea') {
if ($metaDir === '.mokogit') {
$legacySources[] = '.github/.mokostandards';
}
@@ -762,7 +762,7 @@ class RepositorySynchronizer
* @param string $org Organization name
* @param string $repo Repository name
* @param string $platform Detected platform slug
* @param array $repoInfo Gitea API repo object
* @param array $repoInfo Git API repo object
* @param string|null $existingContent Current .mokostandards content (XML or legacy)
* @return string Well-formed XML content
*/
@@ -1068,8 +1068,8 @@ class RepositorySynchronizer
}
// Read all .yml files from the template's workflow directory
$sourceDir = "{$cacheDir}/.mokogitea/workflows";
// Fallback to legacy path if .mokogitea doesn't exist
$sourceDir = "{$cacheDir}/.mokogit/workflows";
// Fallback to legacy path if .mokogit doesn't exist
if (!is_dir($sourceDir)) {
$sourceDir = "{$cacheDir}/.gitea/workflows";
}

Some files were not shown because too many files have changed in this diff Show More