diff --git a/.mokogitea/workflows/pre-release.yml b/.mokogitea/workflows/pre-release.yml index 1a9eeef0ec..9615a4ea3a 100644 --- a/.mokogitea/workflows/pre-release.yml +++ b/.mokogitea/workflows/pre-release.yml @@ -1,241 +1,243 @@ -# Copyright (C) 2026 Moko Consulting -# -# SPDX-License-Identifier: GPL-3.0-or-later -# -# FILE INFORMATION -# DEFGROUP: Gitea.Workflow -# INGROUP: moko-platform.Release -# REPO: https://git.mokoconsulting.tech/MokoConsulting/moko-platform -# PATH: /templates/workflows/universal/pre-release.yml.template -# VERSION: 05.01.00 -# BRIEF: Manual pre-release -- builds dev/alpha/beta/rc packages from any branch - -name: "Universal: Pre-Release" - -on: - pull_request: - types: [closed] - branches: - - dev - pull_request_target: - types: [synchronize, opened, reopened] - branches: - - main - workflow_dispatch: - inputs: - stability: - description: 'Pre-release channel' - required: true - type: choice - options: - - development - - alpha - - beta - - release-candidate - -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 }} - -jobs: - build: - name: "Build Pre-Release (${{ inputs.stability || 'development' }})" - runs-on: release - if: >- - github.event_name == 'workflow_dispatch' || - (github.event_name == 'pull_request' && github.event.pull_request.merged == true && github.event.pull_request.base.ref == 'dev') || - (github.event_name == 'pull_request_target' && github.event.pull_request.base.ref == 'main') - - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 - token: ${{ secrets.MOKOGITEA_TOKEN }} - ref: ${{ github.event_name == 'pull_request_target' && github.event.pull_request.head.sha || '' }} - - - name: Setup moko-platform tools - env: - MOKO_CLONE_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }} - MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting - run: | - # Use pre-installed /opt/moko-platform if available (updated by cron every 6h) - if [ -f “/opt/moko-platform/cli/version_bump.php” ] && [ -f “/opt/moko-platform/vendor/autoload.php” ]; then - echo “Using pre-installed /opt/moko-platform” - echo “MOKO_CLI=/opt/moko-platform/cli” >> “$GITHUB_ENV” - else - echo “Falling back to fresh clone” - if ! command -v composer &> /dev/null; then - sudo apt-get update -qq && sudo apt-get install -y -qq php-cli php-mbstring php-xml php-zip php-curl composer >/dev/null 2>&1 - fi - rm -rf /tmp/moko-platform-api - git clone --depth 1 --branch main --quiet \ - “https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/moko-platform.git” \ - /tmp/moko-platform-api - cd /tmp/moko-platform-api && composer install --no-dev --no-interaction --quiet - echo “MOKO_CLI=/tmp/moko-platform-api/cli” >> “$GITHUB_ENV” - fi - - - name: Detect platform - id: platform - run: | - php ${MOKO_CLI}/manifest_read.php --path . --github-output - - - name: Resolve metadata and bump version - id: meta - run: | - # Auto-detect stability: RC for PRs targeting main, else use input or default to development - if [ "${{ github.event_name }}" = "pull_request_target" ] && [ "${{ github.event.pull_request.base.ref }}" = "main" ]; then - STABILITY="release-candidate" - else - STABILITY="${{ inputs.stability || 'development' }}" - fi - - case "$STABILITY" in - development) SUFFIX="-dev"; TAG="development" ;; - alpha) SUFFIX="-alpha"; TAG="alpha" ;; - beta) SUFFIX="-beta"; TAG="beta" ;; - release-candidate) SUFFIX="-rc"; TAG="release-candidate" ;; - esac - - # Bump version via CLI: patch for dev/alpha/beta, minor for RC - case "$STABILITY" in - release-candidate) BUMP="minor" ;; - *) BUMP="patch" ;; - esac - - php ${MOKO_CLI}/version_bump.php --path . $([ "$BUMP" = "minor" ] && echo "--minor") 2>/dev/null || true - - # Set stability suffix and verify consistency - VERSION=$(php ${MOKO_CLI}/version_read.php --path . 2>/dev/null || echo "00.00.01") - VERSION=$(echo "$VERSION" | sed 's/-\(dev\|alpha\|beta\|rc\)$//') - - php ${MOKO_CLI}/version_set_platform.php \ - --path . --version "$VERSION" --branch "${{ github.ref_name }}" --stability "$STABILITY" 2>/dev/null || true - php ${MOKO_CLI}/version_check.php --path . --fix 2>/dev/null || true - - # Append suffix for output - if [ -n "$SUFFIX" ]; then - VERSION="${VERSION}${SUFFIX}" - fi - - # Commit version bump - 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 add -A - git diff --cached --quiet || { - git commit -m "chore(version): pre-release bump to ${VERSION} [skip ci]" - git push origin HEAD 2>&1 - } - - # Auto-detect element via manifest_element.php - php ${MOKO_CLI}/manifest_element.php \ - --path . --version "$VERSION" --stability "$STABILITY" \ - --repo "${GITEA_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 "$ZIP_NAME" ] && ZIP_NAME="${EXT_ELEMENT}-${VERSION}.zip" - - echo "version=${VERSION}" >> "$GITHUB_OUTPUT" - echo "stability=${STABILITY}" >> "$GITHUB_OUTPUT" - echo "suffix=${SUFFIX}" >> "$GITHUB_OUTPUT" - echo "tag=${TAG}" >> "$GITHUB_OUTPUT" - echo "zip_name=${ZIP_NAME}" >> "$GITHUB_OUTPUT" - echo "ext_element=${EXT_ELEMENT}" >> "$GITHUB_OUTPUT" - - echo "=== Pre-Release: ${EXT_ELEMENT} ${VERSION}${SUFFIX} ===" - - - name: Create release - id: release - run: | - TAG="${{ steps.meta.outputs.tag }}" - VERSION="${{ steps.meta.outputs.version }}" - API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" - php ${MOKO_CLI}/release_create.php \ - --path . --version "$VERSION" --tag "$TAG" \ - --token "${{ secrets.MOKOGITEA_TOKEN }}" --api-base "$API_BASE" \ - --repo "${GITEA_REPO}" --branch dev --prerelease - - - name: Update release notes from CHANGELOG.md - run: | - TAG="${{ steps.meta.outputs.tag }}" - VERSION="${{ steps.meta.outputs.version }}" - API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" - - # Extract [Unreleased] section from changelog (everything between [Unreleased] and next ## heading) - if [ -f "CHANGELOG.md" ]; then - NOTES=$(awk '/^## \[Unreleased\]/{found=1; next} /^## \[/{if(found) exit} found{print}' CHANGELOG.md) - [ -z "$NOTES" ] && NOTES="Release ${VERSION}" - else - NOTES="Release ${VERSION}" - fi - - # Update release body via API - RELEASE_ID=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGITEA_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 - python3 -c " - import json, urllib.request - body = open('/dev/stdin').read() - payload = json.dumps({'body': body}).encode() - req = urllib.request.Request( - '${API_BASE}/releases/${RELEASE_ID}', - data=payload, method='PATCH', - headers={ - 'Authorization': 'token ${{ secrets.MOKOGITEA_TOKEN }}', - 'Content-Type': 'application/json' - }) - urllib.request.urlopen(req) - " <<< "$NOTES" - echo "Release notes updated from CHANGELOG.md" - fi - - - name: Build package and upload - id: package - run: | - VERSION="${{ steps.meta.outputs.version }}" - TAG="${{ steps.meta.outputs.tag }}" - API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_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 - - # updates.xml is generated dynamically by MokoGitea license server - # No need to build, commit, or sync updates.xml from workflows - - - name: "Delete lesser pre-release channels (cascade)" - continue-on-error: true - run: | - API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" - TOKEN="${{ secrets.MOKOGITEA_TOKEN }}" - - php ${MOKO_CLI}/release_cascade.php \ - --stability "${{ steps.meta.outputs.stability }}" \ - --token "${TOKEN}" \ - --api-base "${API_BASE}" - - - name: Summary - if: always() - run: | - VERSION="${{ steps.meta.outputs.version }}" - STABILITY="${{ steps.meta.outputs.stability }}" - ZIP_NAME="${{ steps.meta.outputs.zip_name }}" - SHA256="${{ steps.package.outputs.sha256_zip }}" - echo "## Pre-Release Complete" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "| Field | Value |" >> $GITHUB_STEP_SUMMARY - echo "|-------|-------|" >> $GITHUB_STEP_SUMMARY - echo "| Version | \`${VERSION}\` |" >> $GITHUB_STEP_SUMMARY - echo "| Channel | ${STABILITY} |" >> $GITHUB_STEP_SUMMARY - echo "| Package | \`${ZIP_NAME}\` |" >> $GITHUB_STEP_SUMMARY - echo "| SHA-256 | \`${SHA256:-n/a}\` |" >> $GITHUB_STEP_SUMMARY +# Copyright (C) 2026 Moko Consulting +# +# SPDX-License-Identifier: GPL-3.0-or-later +# +# FILE INFORMATION +# DEFGROUP: Gitea.Workflow +# INGROUP: moko-platform.Release +# REPO: https://git.mokoconsulting.tech/MokoConsulting/moko-platform +# PATH: /templates/workflows/universal/pre-release.yml.template +# VERSION: 05.01.00 +# BRIEF: Manual pre-release -- builds dev/alpha/beta/rc packages from any branch + +name: "Universal: Pre-Release" + +on: + pull_request: + types: [closed] + branches: + - dev + pull_request_target: + types: [synchronize, opened, reopened] + branches: + - main + workflow_dispatch: + inputs: + stability: + description: 'Pre-release channel' + required: true + type: choice + options: + - development + - alpha + - beta + - release-candidate + +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 }} + +jobs: + build: + name: "Build Pre-Release (${{ inputs.stability || 'development' }})" + runs-on: release + if: >- + github.event_name == 'workflow_dispatch' || + (github.event_name == 'pull_request' && github.event.pull_request.merged == true && github.event.pull_request.base.ref == 'dev') || + (github.event_name == 'pull_request_target' && github.event.pull_request.base.ref == 'main') + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ secrets.MOKOGITEA_TOKEN }} + ref: ${{ github.event_name == 'pull_request_target' && github.event.pull_request.head.sha || '' }} + + - name: Setup moko-platform tools + env: + MOKO_CLONE_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }} + MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting + run: | + # Use pre-installed /opt/moko-platform if available (updated by cron every 6h) + if [ -f /opt/moko-platform/cli/version_bump.php ] && [ -f /opt/moko-platform/cli/manifest_element.php ] && [ -f /opt/moko-platform/vendor/autoload.php ]; then + echo Using pre-installed /opt/moko-platform + echo MOKO_CLI=/opt/moko-platform/cli >> $GITHUB_ENV + else + echo Falling back to fresh clone + if ! command -v composer > /dev/null 2>&1; then + sudo apt-get update -qq && sudo apt-get install -y -qq php-cli php-mbstring php-xml php-zip php-curl composer > /dev/null 2>&1 + fi + rm -rf /tmp/moko-platform-api + CLONE_URL=https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/moko-platform.git + git clone --depth 1 --branch main --quiet $CLONE_URL /tmp/moko-platform-api + cd /tmp/moko-platform-api && composer install --no-dev --no-interaction --quiet + echo MOKO_CLI=/tmp/moko-platform-api/cli >> $GITHUB_ENV + fi + + - name: Detect platform + id: platform + run: | + php ${MOKO_CLI}/manifest_read.php --path . --github-output + + - name: Resolve metadata and bump version + id: meta + run: | + # Auto-detect stability: RC for PRs targeting main, else use input or default to development + if [ "${{ github.event_name }}" = "pull_request_target" ] && [ "${{ github.event.pull_request.base.ref }}" = "main" ]; then + STABILITY="release-candidate" + else + STABILITY="${{ inputs.stability || 'development' }}" + fi + + case "$STABILITY" in + development) SUFFIX="-dev"; TAG="development" ;; + alpha) SUFFIX="-alpha"; TAG="alpha" ;; + beta) SUFFIX="-beta"; TAG="beta" ;; + release-candidate) SUFFIX="-rc"; TAG="release-candidate" ;; + esac + + # Bump version via CLI: patch for dev/alpha/beta, minor for RC + case "$STABILITY" in + release-candidate) BUMP="minor" ;; + *) BUMP="patch" ;; + esac + + php ${MOKO_CLI}/version_bump.php --path . $([ "$BUMP" = "minor" ] && echo "--minor") 2>/dev/null || true + + # Set stability suffix and verify consistency + VERSION=$(php ${MOKO_CLI}/version_read.php --path . 2>/dev/null || echo "00.00.01") + VERSION=$(echo "$VERSION" | sed 's/-\(dev\|alpha\|beta\|rc\)$//') + + php ${MOKO_CLI}/version_set_platform.php \ + --path . --version "$VERSION" --branch "${{ github.ref_name }}" --stability "$STABILITY" 2>/dev/null || true + php ${MOKO_CLI}/version_check.php --path . --fix 2>/dev/null || true + + # Ensure licensing tags (updateservers, dlid) if enabled in manifest.xml + php ${MOKO_CLI}/manifest_licensing.php --path . --fix 2>/dev/null || true + + # Append suffix for output + if [ -n "$SUFFIX" ]; then + VERSION="${VERSION}${SUFFIX}" + fi + + # Commit version bump + 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 add -A + git diff --cached --quiet || { + git commit -m "chore(version): pre-release bump to ${VERSION} [skip ci]" + git push origin HEAD 2>&1 + } + + # Auto-detect element via manifest_element.php + php ${MOKO_CLI}/manifest_element.php \ + --path . --version "$VERSION" --stability "$STABILITY" \ + --repo "${GITEA_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 "$ZIP_NAME" ] && ZIP_NAME="${EXT_ELEMENT}-${VERSION}.zip" + + echo "version=${VERSION}" >> "$GITHUB_OUTPUT" + echo "stability=${STABILITY}" >> "$GITHUB_OUTPUT" + echo "suffix=${SUFFIX}" >> "$GITHUB_OUTPUT" + echo "tag=${TAG}" >> "$GITHUB_OUTPUT" + echo "zip_name=${ZIP_NAME}" >> "$GITHUB_OUTPUT" + echo "ext_element=${EXT_ELEMENT}" >> "$GITHUB_OUTPUT" + + echo "=== Pre-Release: ${EXT_ELEMENT} ${VERSION}${SUFFIX} ===" + + - name: Create release + id: release + run: | + TAG="${{ steps.meta.outputs.tag }}" + VERSION="${{ steps.meta.outputs.version }}" + API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" + php ${MOKO_CLI}/release_create.php \ + --path . --version "$VERSION" --tag "$TAG" \ + --token "${{ secrets.MOKOGITEA_TOKEN }}" --api-base "$API_BASE" \ + --repo "${GITEA_REPO}" --branch dev --prerelease + + - name: Update release notes from CHANGELOG.md + run: | + TAG="${{ steps.meta.outputs.tag }}" + VERSION="${{ steps.meta.outputs.version }}" + API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" + + # Extract [Unreleased] section from changelog (everything between [Unreleased] and next ## heading) + if [ -f "CHANGELOG.md" ]; then + NOTES=$(awk '/^## \[Unreleased\]/{found=1; next} /^## \[/{if(found) exit} found{print}' CHANGELOG.md) + [ -z "$NOTES" ] && NOTES="Release ${VERSION}" + else + NOTES="Release ${VERSION}" + fi + + # Update release body via API + RELEASE_ID=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGITEA_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 + python3 -c " + import json, urllib.request + body = open('/dev/stdin').read() + payload = json.dumps({'body': body}).encode() + req = urllib.request.Request( + '${API_BASE}/releases/${RELEASE_ID}', + data=payload, method='PATCH', + headers={ + 'Authorization': 'token ${{ secrets.MOKOGITEA_TOKEN }}', + 'Content-Type': 'application/json' + }) + urllib.request.urlopen(req) + " <<< "$NOTES" + echo "Release notes updated from CHANGELOG.md" + fi + + - name: Build package and upload + id: package + run: | + VERSION="${{ steps.meta.outputs.version }}" + TAG="${{ steps.meta.outputs.tag }}" + API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_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 + + # updates.xml is generated dynamically by MokoGitea license server + # No need to build, commit, or sync updates.xml from workflows + + - name: "Delete lesser pre-release channels (cascade)" + continue-on-error: true + run: | + API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" + TOKEN="${{ secrets.MOKOGITEA_TOKEN }}" + + php ${MOKO_CLI}/release_cascade.php \ + --stability "${{ steps.meta.outputs.stability }}" \ + --token "${TOKEN}" \ + --api-base "${API_BASE}" + + - name: Summary + if: always() + run: | + VERSION="${{ steps.meta.outputs.version }}" + STABILITY="${{ steps.meta.outputs.stability }}" + ZIP_NAME="${{ steps.meta.outputs.zip_name }}" + SHA256="${{ steps.package.outputs.sha256_zip }}" + echo "## Pre-Release Complete" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "| Field | Value |" >> $GITHUB_STEP_SUMMARY + echo "|-------|-------|" >> $GITHUB_STEP_SUMMARY + echo "| Version | \`${VERSION}\` |" >> $GITHUB_STEP_SUMMARY + echo "| Channel | ${STABILITY} |" >> $GITHUB_STEP_SUMMARY + echo "| Package | \`${ZIP_NAME}\` |" >> $GITHUB_STEP_SUMMARY + echo "| SHA-256 | \`${SHA256:-n/a}\` |" >> $GITHUB_STEP_SUMMARY diff --git a/wiki/branding.md b/wiki/branding.md new file mode 100644 index 0000000000..ec2b48d274 --- /dev/null +++ b/wiki/branding.md @@ -0,0 +1,32 @@ +# Custom Branding + +## Logo & Favicon + +Located in the container at `/var/lib/gitea/custom/public/assets/img/`: +- `logo.svg` — Navbar logo +- `logo.png` — Fallback logo +- `favicon.png` — Browser tab icon +- `favicon.svg` — SVG favicon + +Source: Moko Consulting CRM favicon + +## Landing Page + +- `LANDING_PAGE = organizations` in `app.ini` +- Custom JS redirects home/logo clicks to `/explore/organizations` +- After login, users see the organizations list + +## Themes + +Custom CSS themes at `/var/lib/gitea/custom/public/assets/css/`: +- `theme-moko-dark.css` +- `theme-moko-light.css` +- `theme-moko-auto.css` + +--- + +*Repo: [MokoGitea](https://git.mokoconsulting.tech/MokoConsulting/MokoGitea) · [moko-platform](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/Home)* + +| Revision | Date | Author | Description | +|---|---|---|---| +| 1.0 | 2026-05-09 | Moko Consulting | Initial version | diff --git a/wiki/deployment.md b/wiki/deployment.md new file mode 100644 index 0000000000..420d3d3eb1 --- /dev/null +++ b/wiki/deployment.md @@ -0,0 +1,48 @@ +# Deployment + +## Docker Image + +MokoGitea runs as a custom Docker image built from the `moko/1.25.5-project-api` branch. + +### Build +```bash +cd /opt/MokoGitea +git pull +docker build -t mokogitea:1.25.5-project-api -f Dockerfile.rootless . +``` + +### Deploy +The docker-compose at `/opt/gitea/docker-compose.yml` references the image: +```yaml +services: + gitea: + image: mokogitea:1.25.5-project-api +``` + +### Update Process +1. Pull latest from `moko/1.25.5-project-api` +2. Rebuild Docker image +3. `docker compose down gitea && docker compose up -d gitea` + +## Volumes + +| Path | Purpose | +|------|---------| +| `./gitea/data` | Repository data, LFS, avatars | +| `./gitea/conf` | `app.ini` configuration | + +## Custom Files + +Located at `/var/lib/gitea/custom/`: +- `templates/custom/header.tmpl` — Branding, logo redirect +- `public/assets/img/logo.svg` — Moko logo +- `public/assets/img/favicon.png` — Moko favicon +- `public/assets/css/theme-moko-*.css` — Custom themes + +--- + +*Repo: [MokoGitea](https://git.mokoconsulting.tech/MokoConsulting/MokoGitea) · [moko-platform](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/Home)* + +| Revision | Date | Author | Description | +|---|---|---|---| +| 1.0 | 2026-05-09 | Moko Consulting | Initial version | diff --git a/wiki/home.md b/wiki/home.md index 89d80177e5..7eec97ac60 100644 --- a/wiki/home.md +++ b/wiki/home.md @@ -7,7 +7,7 @@ Moko Consulting's custom fork of [Gitea](https://gitea.com), extending the self- | **Language** | Go | | **License** | MIT | | **Upstream** | Gitea 1.26.1 | -| **Version** | v1.26.1-moko.06.04.00 | +| **Version** | v1.26.1-moko.06.07.03 | | **Platform** | [Gitea](https://git.mokoconsulting.tech/MokoConsulting/MokoGitea) | --- diff --git a/wiki/org-branch-protection-api.md b/wiki/org-branch-protection-api.md new file mode 100644 index 0000000000..dc6471734d --- /dev/null +++ b/wiki/org-branch-protection-api.md @@ -0,0 +1,115 @@ +# Org-Level Branch Protection API + +## Overview + +MokoGitea v1261.0.0 introduces **organization-level branch protection rulesets** that cascade automatically to all repositories within an organization. This eliminates the need to configure identical branch protection rules on each repo individually. + +## How Inheritance Works + +1. **Repo rules take precedence** — If a repo has its own protection rule for a branch pattern (e.g., `main`), the org rule is ignored for that repo. +2. **Org rules are the fallback** — If no repo-level rule matches a branch, the system checks org-level rules. +3. **Team-based only** — Org rules reference teams, not individual users (use repo-level rules for per-user whitelists). + +## API Endpoints + +All endpoints require authentication (`token`) and org ownership permissions. + +### List Rules + +``` +GET /api/v1/orgs/{org}/branch_protections +``` + +### Create Rule + +``` +POST /api/v1/orgs/{org}/branch_protections +``` + +**Body:** +```json +{ + "rule_name": "main", + "enable_push": true, + "enable_push_whitelist": true, + "push_whitelist_teams": ["developers"], + "enable_merge_whitelist": true, + "merge_whitelist_teams": ["maintainers"], + "required_approvals": 2, + "block_on_rejected_reviews": true, + "block_on_outdated_branch": true, + "dismiss_stale_approvals": true, + "require_signed_commits": false +} +``` + +### Get Rule + +``` +GET /api/v1/orgs/{org}/branch_protections/{name} +``` + +### Update Rule + +``` +PATCH /api/v1/orgs/{org}/branch_protections/{name} +``` + +Only fields included in the request body are updated. + +### Delete Rule + +``` +DELETE /api/v1/orgs/{org}/branch_protections/{name} +``` + +## Glob Patterns + +Rule names support glob patterns for matching multiple branches: + +| Pattern | Matches | +|---------|---------| +| `main` | Exactly `main` | +| `dev` | Exactly `dev` | +| `rc/*` | `rc/1.0`, `rc/2.0-beta`, etc. | +| `beta/*` | `beta/feature-x`, etc. | +| `release/**` | `release/v1`, `release/v1/hotfix`, etc. | + +## Example: Protect All Standard Branches + +```bash +TOKEN="your-token" +ORG="MokoConsulting" +API="https://git.mokoconsulting.tech/api/v1" + +for BRANCH in main dev "rc/*" "beta/*" "alpha/*"; do + curl -X POST "$API/orgs/$ORG/branch_protections" \ + -H "Authorization: token $TOKEN" \ + -H "Content-Type: application/json" \ + -d "{ + \"rule_name\": \"$BRANCH\", + \"enable_push\": true, + \"enable_push_whitelist\": true, + \"push_whitelist_teams\": [\"developers\"], + \"required_approvals\": 1, + \"block_on_rejected_reviews\": true, + \"block_on_outdated_branch\": true + }" +done +``` + +## Configuration: Help & Support URLs + +Also new in v1261.0.0 — configurable help/support links in `app.ini`: + +```ini +[DEFAULT] +HELP_URL = https://docs.mokoconsulting.tech +SUPPORT_URL = https://mokoconsulting.tech/support +``` + +These replace the hardcoded `docs.gitea.com` links in the navigation bar and are visible in **Site Admin > Configuration**. + +## Version Convention + +MokoGitea uses `1261.xx.xx` versioning where `1261` represents the fork starting point from upstream Gitea. Minor and patch numbers track MokoGitea-specific releases. diff --git a/wiki/project-api.md b/wiki/project-api.md new file mode 100644 index 0000000000..4721851a06 --- /dev/null +++ b/wiki/project-api.md @@ -0,0 +1,202 @@ +# Project Board API Reference + +Complete REST API for managing Gitea project boards, columns, and issue cards. This API was added by MokoGitea and is not available in upstream Gitea. + +## Authentication + +All write endpoints require a token with `issue` scope: +``` +Authorization: token YOUR_TOKEN +``` + +## Projects + +### List Projects +``` +GET /api/v1/repos/{owner}/{repo}/projects +``` +Query parameters: +- `state` — `open` (default), `closed`, or `all` +- `page` — page number (1-based) +- `limit` — results per page + +Response: Array of Project objects + +### Create Project +``` +POST /api/v1/repos/{owner}/{repo}/projects +``` +Body: +```json +{ + "title": "Sprint Q2 2026", + "description": "Second quarter sprint", + "board_type": 1, + "card_type": 0 +} +``` +- `board_type`: 0=none, 1=basic kanban, 2=bug triage +- `card_type`: 0=text only, 1=images and text + +### Get Project +``` +GET /api/v1/repos/{owner}/{repo}/projects/{id} +``` + +### Update Project +``` +PATCH /api/v1/repos/{owner}/{repo}/projects/{id} +``` +Body: +```json +{ + "title": "Updated Title", + "description": "Updated description" +} +``` + +### Delete Project +``` +DELETE /api/v1/repos/{owner}/{repo}/projects/{id} +``` + +### Close/Reopen Project +``` +POST /api/v1/repos/{owner}/{repo}/projects/{id}/close +POST /api/v1/repos/{owner}/{repo}/projects/{id}/reopen +``` + +## Columns + +### List Columns +``` +GET /api/v1/repos/{owner}/{repo}/projects/{id}/columns +``` + +### Create Column +``` +POST /api/v1/repos/{owner}/{repo}/projects/{id}/columns +``` +Body: +```json +{ + "title": "Backlog", + "color": "#0075ca" +} +``` + +### Delete Column +``` +DELETE /api/v1/repos/{owner}/{repo}/projects/{id}/columns/{columnId} +``` + +## Issue Cards + +### List Issues in Column +``` +GET /api/v1/repos/{owner}/{repo}/projects/{id}/columns/{columnId}/issues +``` + +Response: Array of ProjectColumnIssue objects with `issue_id`, `project_id`, `column_id`, `sorting` + +### Add Issue to Column +``` +POST /api/v1/repos/{owner}/{repo}/projects/{id}/columns/{columnId}/issues +``` +Body: +```json +{ + "issue_id": 42 +} +``` + +### Move Issue Between Columns +``` +PATCH /api/v1/repos/{owner}/{repo}/projects/{id}/issues/{issueId}/move +``` +Body: +```json +{ + "column_id": 5, + "sorting": 0 +} +``` + +### Remove Issue from Project +``` +DELETE /api/v1/repos/{owner}/{repo}/projects/{id}/issues/{issueId} +``` + +## Data Types + +### Project +```json +{ + "id": 1, + "title": "Roadmap", + "description": "Development roadmap", + "owner_id": 2, + "repo_id": 68, + "creator_id": 1, + "is_closed": false, + "created_at": "2026-05-08T00:06:45Z", + "updated_at": "2026-05-08T00:06:45Z", + "closed_at": null +} +``` + +### ProjectColumn +```json +{ + "id": 7, + "title": "Backlog", + "sorting": 0, + "color": "#0075ca", + "project_id": 1, + "default": false, + "created_at": "2026-05-08T00:06:58Z", + "updated_at": "2026-05-08T00:06:58Z" +} +``` + +### ProjectColumnIssue +```json +{ + "id": 1, + "issue_id": 42, + "project_id": 1, + "column_id": 7, + "sorting": 0 +} +``` + +## MCP Integration + +The `project-mcp` server wraps this API. Key tool: `project_setup_roadmap` creates a full project board with columns and loads all open issues in one call. + +## Quick Start + +```bash +# Create a project +curl -X POST -H "Authorization: token TOKEN" \ + https://git.mokoconsulting.tech/api/v1/repos/MokoConsulting/MokoCRM/projects \ + -d '{"title":"Roadmap","board_type":1}' + +# Add columns +curl -X POST -H "Authorization: token TOKEN" \ + https://git.mokoconsulting.tech/api/v1/repos/MokoConsulting/MokoCRM/projects/1/columns \ + -d '{"title":"Backlog"}' + +# Add an issue +curl -X POST -H "Authorization: token TOKEN" \ + https://git.mokoconsulting.tech/api/v1/repos/MokoConsulting/MokoCRM/projects/1/columns/1/issues \ + -d '{"issue_id":42}' +``` + +--- + +*Repo: [MokoGitea](https://git.mokoconsulting.tech/MokoConsulting/MokoGitea) · [moko-platform](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/Home)* + +| Revision | Date | Author | Description | +|---|---|---|---| +| 1.0 | 2026-05-09 | Moko Consulting | Initial version | diff --git a/wiki/roadmap.md b/wiki/roadmap.md new file mode 100644 index 0000000000..b13ba56865 --- /dev/null +++ b/wiki/roadmap.md @@ -0,0 +1,42 @@ +# MokoGitea Roadmap + +## Recently Completed (v1.26.1-moko.06.07) + +- Well-known file tabs (README/LICENSE/CONTRIBUTING/SECURITY/CHANGELOG) +- Custom issue statuses with auto close/reopen +- Org-level issue priorities (Critical/High/Medium/Low) +- Repo manifest settings with REST API +- Manifest auto-sync on push to default branch +- Status dropdown replaces close button +- Auto-seed default statuses and priorities for orgs +- MCP server published to npm (@mokoconsulting/mokogitea-mcp) +- MCP SSE transport for hosted deployments + +## In Progress + +- Granular role-based permissions for all features (#9) +- Built-in secret scanning (#508) +- Enterprise Wiki with hierarchical folder navigation (#79) +- Wire moko-platform CLI to manifest API (#505) + +## Planned + +- Standard status presets and cross-org migration (#507) +- Auto-create default teams on org creation (#513) +- Update server reads from repo_manifest (#512) +- Payment gateways for license keys (#135) +- Independent visibility controls for issues/wiki/projects (#133) + +## Infrastructure + +- MCP SSE endpoint at git.mokoconsulting.tech/mcp +- Smithery/Claude Code marketplace listing +- Docker image for MCP server +- npm auto-publish workflow on release + +--- + +| Revision | Date | Author | Description | +|---|---|---|---| +| 2.0 | 2026-06-06 | Jonathan Miller (@jmiller) | Complete rewrite with current features and priorities | +| 1.0 | 2026-05-09 | Jonathan Miller (@jmiller) | Initial version |