Compare commits

..

2 Commits

Author SHA1 Message Date
jmiller 4c4d2ac956 Merge pull request 'rc(v05.06.00): security backports, actions deadlock fix, dep bumps' (#228) from rc/05.06.00 into main
Universal: Auto Version Bump / Patch Bump (push) Successful in 6s
rc(v05.06.00): security backports, actions deadlock fix, dep bumps (#228)
2026-05-26 22:37:06 +00:00
jmiller 47ddd6a277 chore(ci): update auto-release.yml from moko-platform [skip ci] 2026-05-26 22:35:53 +00:00
20 changed files with 1724 additions and 1346 deletions
+24 -15
View File
@@ -8,7 +8,7 @@
# REPO: https://git.mokoconsulting.tech/MokoConsulting/moko-platform # REPO: https://git.mokoconsulting.tech/MokoConsulting/moko-platform
# PATH: /.mokogitea/workflows/auto-bump.yml # PATH: /.mokogitea/workflows/auto-bump.yml
# VERSION: 09.02.00 # VERSION: 09.02.00
# BRIEF: Auto patch-bump version on every push to dev (skips merge commits) # BRIEF: Auto patch-bump version on every push to dev
name: "Universal: Auto Version Bump" name: "Universal: Auto Version Bump"
@@ -16,9 +16,9 @@ on:
push: push:
branches: branches:
- dev - dev
- main
env: env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }} GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
permissions: permissions:
@@ -26,18 +26,17 @@ permissions:
jobs: jobs:
bump: bump:
name: Version Bump name: Patch Bump
runs-on: release runs-on: release
if: >- if: >-
!contains(github.event.head_commit.message, '[skip ci]') && !contains(github.event.head_commit.message, '[skip ci]') &&
!contains(github.event.head_commit.message, '[skip bump]') && !contains(github.event.head_commit.message, '[skip bump]')
!startsWith(github.event.head_commit.message, 'Merge pull request')
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with: with:
token: ${{ secrets.MOKOGITEA_TOKEN }} token: ${{ secrets.GA_TOKEN }}
fetch-depth: 1 fetch-depth: 1
- name: Setup moko-platform tools - name: Setup moko-platform tools
@@ -49,7 +48,7 @@ jobs:
echo "MOKO_CLI=/opt/moko-platform/cli" >> "$GITHUB_ENV" echo "MOKO_CLI=/opt/moko-platform/cli" >> "$GITHUB_ENV"
else else
git clone --depth 1 --branch main --quiet \ git clone --depth 1 --branch main --quiet \
"https://x-access-token:${{ secrets.MOKOGITEA_TOKEN }}@git.mokoconsulting.tech/MokoConsulting/moko-platform.git" \ "https://x-access-token:${{ secrets.GA_TOKEN }}@git.mokoconsulting.tech/MokoConsulting/moko-platform.git" \
/tmp/moko-platform-api /tmp/moko-platform-api
cd /tmp/moko-platform-api && composer install --no-dev --no-interaction --quiet cd /tmp/moko-platform-api && composer install --no-dev --no-interaction --quiet
echo "MOKO_CLI=/tmp/moko-platform-api/cli" >> "$GITHUB_ENV" echo "MOKO_CLI=/tmp/moko-platform-api/cli" >> "$GITHUB_ENV"
@@ -57,17 +56,27 @@ jobs:
- name: Bump version - name: Bump version
run: | run: |
BUMP=$(php ${MOKO_CLI}/version_bump.php --path . 2>&1) || true BRANCH="${{ github.ref_name }}"
# main = minor bump, dev = patch bump
if [ "$BRANCH" = "main" ]; then
BUMP_TYPE="--minor"
BUMP_LABEL="minor"
else
BUMP_TYPE=""
BUMP_LABEL="patch"
fi
BUMP=$(php ${MOKO_CLI}/version_bump.php --path . $BUMP_TYPE 2>&1) || true
echo "$BUMP" echo "$BUMP"
VERSION=$(php ${MOKO_CLI}/version_read.php --path . 2>/dev/null) || true VERSION=$(php ${MOKO_CLI}/version_read.php --path . 2>/dev/null) || true
[ -z "$VERSION" ] && { echo "No version found — skipping"; exit 0; } [ -z "$VERSION" ] && { echo "No version found — skipping"; exit 0; }
# Propagate to platform manifests with -dev suffix # Propagate to platform manifests
php ${MOKO_CLI}/version_set_platform.php \ php ${MOKO_CLI}/version_set_platform.php \
--path . --version "$VERSION" --branch dev --stability dev 2>/dev/null || true --path . --version "$VERSION" --branch "$BRANCH" 2>/dev/null || true
php ${MOKO_CLI}/version_check.php --path . --fix 2>/dev/null || true php ${MOKO_CLI}/version_check.php --path . --fix 2>/dev/null || true
VERSION="${VERSION}-dev"
# Commit if anything changed # Commit if anything changed
if git diff --quiet && git diff --cached --quiet; then if git diff --quiet && git diff --cached --quiet; then
@@ -77,9 +86,9 @@ jobs:
git config --local user.email "gitea-actions[bot]@mokoconsulting.tech" git config --local user.email "gitea-actions[bot]@mokoconsulting.tech"
git config --local user.name "gitea-actions[bot]" 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 remote set-url origin "https://jmiller:${{ secrets.GA_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git"
git add -A git add -A
git commit -m "chore(version): auto-bump patch ${VERSION} [skip ci]" \ git commit -m "chore(version): ${BUMP_LABEL} bump to ${VERSION} [skip ci]" \
--author="gitea-actions[bot] <gitea-actions[bot]@mokoconsulting.tech>" --author="gitea-actions[bot] <gitea-actions[bot]@mokoconsulting.tech>"
git push origin dev git push origin "$BRANCH"
echo "Bumped to ${VERSION}" >> $GITHUB_STEP_SUMMARY echo "Bumped to ${VERSION} (${BUMP_LABEL})" >> $GITHUB_STEP_SUMMARY
+64 -97
View File
@@ -63,19 +63,17 @@ jobs:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with: with:
token: ${{ secrets.MOKOGITEA_TOKEN }} token: ${{ secrets.GA_TOKEN }}
fetch-depth: 1 fetch-depth: 1
- name: Setup moko-platform tools - name: Setup moko-platform tools
env: env:
MOKO_CLONE_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }} MOKO_CLONE_TOKEN: ${{ secrets.GA_TOKEN }}
MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting
run: | run: |
if ! command -v composer &> /dev/null; then if ! command -v composer &> /dev/null; then
sudo apt-get update -qq && sudo apt-get install -y -qq php-cli php-mbstring php-xml php-zip php-curl composer >/dev/null 2>&1 sudo apt-get update -qq && sudo apt-get install -y -qq php-cli php-mbstring php-xml php-zip php-curl composer >/dev/null 2>&1
fi fi
# Always fetch latest CLI tools — never use stale cache from previous runs
rm -rf /tmp/moko-platform-api
git clone --depth 1 --branch main --quiet \ git clone --depth 1 --branch main --quiet \
"https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/moko-platform.git" \ "https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/moko-platform.git" \
/tmp/moko-platform-api /tmp/moko-platform-api
@@ -87,9 +85,9 @@ jobs:
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
php /tmp/moko-platform-api/cli/release_promote.php \ php /tmp/moko-platform-api/cli/release_promote.php \
--from auto --to release-candidate \ --from auto --to release-candidate \
--token "${{ secrets.MOKOGITEA_TOKEN }}" \ --token "${{ secrets.GA_TOKEN }}" \
--api-base "${API_BASE}" \ --api-base "${API_BASE}" \
--branch "${{ github.event.pull_request.head.ref || 'dev' }}" --branch "${{ github.event.pull_request.head.ref }}"
- name: Cascade lesser channels - name: Cascade lesser channels
continue-on-error: true continue-on-error: true
@@ -97,7 +95,7 @@ jobs:
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
php /tmp/moko-platform-api/cli/release_cascade.php \ php /tmp/moko-platform-api/cli/release_cascade.php \
--stability release-candidate \ --stability release-candidate \
--token "${{ secrets.MOKOGITEA_TOKEN }}" \ --token "${{ secrets.GA_TOKEN }}" \
--api-base "${API_BASE}" --api-base "${API_BASE}"
- name: Summary - name: Summary
@@ -118,27 +116,19 @@ jobs:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with: with:
token: ${{ secrets.MOKOGITEA_TOKEN }} token: ${{ secrets.GA_TOKEN }}
fetch-depth: 0 fetch-depth: 0
- name: Configure git for bot pushes
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"
- name: Setup moko-platform tools - name: Setup moko-platform tools
env: env:
MOKO_CLONE_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }} MOKO_CLONE_TOKEN: ${{ secrets.GA_TOKEN }}
MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting
COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GH_MIRROR_TOKEN }}"}}' COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GH_TOKEN }}"}}'
run: | run: |
# Ensure PHP + Composer are available # Ensure PHP + Composer are available
if ! command -v composer &> /dev/null; then if ! command -v composer &> /dev/null; then
sudo apt-get update -qq && sudo apt-get install -y -qq php-cli php-mbstring php-xml php-zip php-curl composer >/dev/null 2>&1 sudo apt-get update -qq && sudo apt-get install -y -qq php-cli php-mbstring php-xml php-zip php-curl composer >/dev/null 2>&1
fi fi
# Always fetch latest CLI tools — never use stale cache from previous runs
rm -rf /tmp/moko-platform-api
git clone --depth 1 --branch main --quiet \ git clone --depth 1 --branch main --quiet \
"https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/moko-platform.git" \ "https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/moko-platform.git" \
/tmp/moko-platform-api /tmp/moko-platform-api
@@ -165,8 +155,6 @@ jobs:
echo "skip=true" >> "$GITHUB_OUTPUT" echo "skip=true" >> "$GITHUB_OUTPUT"
exit 0 exit 0
fi fi
# Strip any pre-release suffix merged from dev (e.g. 01.02.20-dev → 01.02.20)
VERSION=$(echo "$VERSION" | sed 's/-\(dev\|alpha\|beta\|rc\)$//')
MAJOR=$(echo "$VERSION" | cut -d. -f1) MAJOR=$(echo "$VERSION" | cut -d. -f1)
echo "version=${VERSION}" >> "$GITHUB_OUTPUT" echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
echo "release_tag=stable" >> "$GITHUB_OUTPUT" echo "release_tag=stable" >> "$GITHUB_OUTPUT"
@@ -179,7 +167,7 @@ jobs:
if: steps.version.outputs.skip != 'true' if: steps.version.outputs.skip != 'true'
run: | run: |
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
RC_JSON=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \ RC_JSON=$(curl -sf -H "Authorization: token ${{ secrets.GA_TOKEN }}" \
"${API_BASE}/releases/tags/release-candidate" 2>/dev/null || echo "{}") "${API_BASE}/releases/tags/release-candidate" 2>/dev/null || echo "{}")
RC_ID=$(echo "$RC_JSON" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('id',''))" 2>/dev/null || true) RC_ID=$(echo "$RC_JSON" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('id',''))" 2>/dev/null || true)
@@ -192,17 +180,7 @@ jobs:
echo "::notice::No RC release — full build pipeline" echo "::notice::No RC release — full build pipeline"
fi fi
- name: "Step 1b: Minor bump version" # Version bump handled by auto-bump.yml (minor on main, patch on dev)
id: bump
if: >-
steps.version.outputs.skip != 'true' &&
steps.rc.outputs.promote != 'true'
run: |
MOKO_API="/tmp/moko-platform-api/cli"
php ${MOKO_API}/version_bump.php --path . --minor 2>&1 || true
VERSION=$(php ${MOKO_API}/version_read.php --path .)
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
echo "Bumped to: ${VERSION}"
- name: Check if already released - name: Check if already released
if: steps.version.outputs.skip != 'true' if: steps.version.outputs.skip != 'true'
@@ -229,7 +207,7 @@ jobs:
steps.version.outputs.skip != 'true' && steps.version.outputs.skip != 'true' &&
steps.check.outputs.already_released != 'true' steps.check.outputs.already_released != 'true'
run: | run: |
VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" VERSION="${{ steps.version.outputs.version }}"
php /tmp/moko-platform-api/cli/release_validate.php \ php /tmp/moko-platform-api/cli/release_validate.php \
--path . --version "$VERSION" --output-summary --github-output || true --path . --version "$VERSION" --output-summary --github-output || true
@@ -240,7 +218,7 @@ jobs:
run: | run: |
BRANCH="${{ steps.version.outputs.branch }}" BRANCH="${{ steps.version.outputs.branch }}"
IS_MINOR="${{ steps.version.outputs.is_minor }}" IS_MINOR="${{ steps.version.outputs.is_minor }}"
PATCH="${{ steps.bump.outputs.version || steps.version.outputs.version }}" PATCH="${{ steps.version.outputs.version }}"
PATCH_NUM=$(echo "$PATCH" | awk -F. '{print $3}') PATCH_NUM=$(echo "$PATCH" | awk -F. '{print $3}')
# Check if branch exists # Check if branch exists
@@ -259,7 +237,7 @@ jobs:
steps.version.outputs.skip != 'true' && steps.version.outputs.skip != 'true' &&
steps.check.outputs.already_released != 'true' steps.check.outputs.already_released != 'true'
run: | run: |
VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" VERSION="${{ steps.version.outputs.version }}"
php /tmp/moko-platform-api/cli/version_set_platform.php \ php /tmp/moko-platform-api/cli/version_set_platform.php \
--path . --version "$VERSION" --branch main --path . --version "$VERSION" --branch main
@@ -267,24 +245,12 @@ jobs:
- name: "Step 4: Update version badges" - name: "Step 4: Update version badges"
if: steps.version.outputs.skip != 'true' if: steps.version.outputs.skip != 'true'
run: | run: |
VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" VERSION="${{ steps.version.outputs.version }}"
php /tmp/moko-platform-api/cli/badge_update.php --path . --version "${VERSION}" 2>/dev/null || true php /tmp/moko-platform-api/cli/badge_update.php --path . --version "${VERSION}" 2>/dev/null || true
php /tmp/moko-platform-api/cli/version_check.php --path . --fix 2>/dev/null || true php /tmp/moko-platform-api/cli/version_check.php --path . --fix 2>/dev/null || true
# Step 5 (updates.xml) moved after Step 8 to include SHA-256 checksum # Step 5 (updates.xml) moved after Step 8 to include SHA-256 checksum
- name: "Step 4b: Promote and prune CHANGELOG"
if: >-
steps.version.outputs.skip != 'true' &&
steps.check.outputs.already_released != 'true'
run: |
VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}"
MOKO_API="/tmp/moko-platform-api/cli"
if [ -f "CHANGELOG.md" ]; then
php ${MOKO_API}/changelog_promote.php --path . --version "$VERSION" 2>&1 || true
php ${MOKO_API}/changelog_prune.php --path . --keep 5 2>&1 || true
fi
- name: Commit release changes - name: Commit release changes
if: >- if: >-
steps.version.outputs.skip != 'true' && steps.version.outputs.skip != 'true' &&
@@ -294,12 +260,15 @@ jobs:
echo "No changes to commit" echo "No changes to commit"
exit 0 exit 0
fi fi
VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" VERSION="${{ steps.version.outputs.version }}"
git config --local user.email "gitea-actions[bot]@mokoconsulting.tech"
git config --local user.name "gitea-actions[bot]"
# Set push URL with token for branch-protected repos
git remote set-url origin "https://jmiller:${{ secrets.GA_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git"
git add -A git add -A
git commit -m "chore(release): build ${VERSION} [skip ci]" \ git commit -m "chore(release): build ${VERSION} [skip ci]" \
--author="gitea-actions[bot] <gitea-actions[bot]@mokoconsulting.tech>" --author="gitea-actions[bot] <gitea-actions[bot]@mokoconsulting.tech>"
# Detached HEAD on PR merge — push explicitly to main git push -u origin HEAD
git push origin HEAD:refs/heads/main
# -- STEP 6: Create tag --------------------------------------------------- # -- STEP 6: Create tag ---------------------------------------------------
- name: "Step 6: Create git tag" - name: "Step 6: Create git tag"
@@ -323,11 +292,11 @@ jobs:
steps.version.outputs.skip != 'true' && steps.version.outputs.skip != 'true' &&
steps.rc.outputs.promote == 'true' steps.rc.outputs.promote == 'true'
run: | run: |
VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" VERSION="${{ steps.version.outputs.version }}"
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
php /tmp/moko-platform-api/cli/release_promote.php \ php /tmp/moko-platform-api/cli/release_promote.php \
--from release-candidate --to stable \ --from release-candidate --to stable \
--token "${{ secrets.MOKOGITEA_TOKEN }}" \ --token "${{ secrets.GA_TOKEN }}" \
--api-base "${API_BASE}" \ --api-base "${API_BASE}" \
--path . --branch main --path . --branch main
echo "Promoted RC → stable (${VERSION})" >> $GITHUB_STEP_SUMMARY echo "Promoted RC → stable (${VERSION})" >> $GITHUB_STEP_SUMMARY
@@ -338,12 +307,12 @@ jobs:
steps.version.outputs.skip != 'true' && steps.version.outputs.skip != 'true' &&
steps.rc.outputs.promote != 'true' steps.rc.outputs.promote != 'true'
run: | run: |
VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" VERSION="${{ steps.version.outputs.version }}"
RELEASE_TAG="${{ steps.version.outputs.release_tag }}" RELEASE_TAG="${{ steps.version.outputs.release_tag }}"
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
php /tmp/moko-platform-api/cli/release_create.php \ php /tmp/moko-platform-api/cli/release_create.php \
--path . --version "$VERSION" --tag "$RELEASE_TAG" \ --path . --version "$VERSION" --tag "$RELEASE_TAG" \
--token "${{ secrets.MOKOGITEA_TOKEN }}" --api-base "$API_BASE" \ --token "${{ secrets.GA_TOKEN }}" --api-base "$API_BASE" \
--repo "${GITEA_REPO}" --branch main --repo "${GITEA_REPO}" --branch main
echo "Release created: ${VERSION}" >> $GITHUB_STEP_SUMMARY echo "Release created: ${VERSION}" >> $GITHUB_STEP_SUMMARY
@@ -354,25 +323,25 @@ jobs:
steps.version.outputs.skip != 'true' && steps.version.outputs.skip != 'true' &&
steps.rc.outputs.promote != 'true' steps.rc.outputs.promote != 'true'
run: | run: |
VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" VERSION="${{ steps.version.outputs.version }}"
RELEASE_TAG="${{ steps.version.outputs.release_tag }}" RELEASE_TAG="${{ steps.version.outputs.release_tag }}"
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
php /tmp/moko-platform-api/cli/release_package.php \ php /tmp/moko-platform-api/cli/release_package.php \
--path . --version "$VERSION" --tag "$RELEASE_TAG" \ --path . --version "$VERSION" --tag "$RELEASE_TAG" \
--token "${{ secrets.MOKOGITEA_TOKEN }}" --api-base "$API_BASE" \ --token "${{ secrets.GA_TOKEN }}" --api-base "$API_BASE" \
--repo "${GITEA_REPO}" --output /tmp || true --repo "${GITEA_REPO}" --output /tmp || true
# -- STEP 5: Write update stream (after build so SHA-256 is available) ----- # -- STEP 5: Write update stream (after build so SHA-256 is available) -----
- name: "Step 5: Write update stream" - name: "Step 5: Write update stream"
if: steps.version.outputs.skip != 'true' if: steps.version.outputs.skip != 'true'
run: | run: |
VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" VERSION="${{ steps.version.outputs.version }}"
SHA256="${{ steps.package.outputs.sha256_zip }}" SHA256="${{ steps.package.outputs.sha256_zip }}"
# Fetch latest updates.xml from main so preserve logic has all channels # Fetch latest updates.xml from main so preserve logic has all channels
GITEA_TOKEN="${{ secrets.MOKOGITEA_TOKEN }}" GA_TOKEN="${{ secrets.GA_TOKEN }}"
API="${GITEA_URL}/api/v1/repos/${{ github.repository }}" API="${GITEA_URL}/api/v1/repos/${{ github.repository }}"
curl -sf -H "Authorization: token ${GITEA_TOKEN}" \ curl -sf -H "Authorization: token ${GA_TOKEN}" \
"${API}/contents/updates.xml?ref=main" 2>/dev/null | \ "${API}/contents/updates.xml?ref=main" 2>/dev/null | \
python3 -c "import sys,json,base64; print(base64.b64decode(json.load(sys.stdin)['content']).decode())" \ python3 -c "import sys,json,base64; print(base64.b64decode(json.load(sys.stdin)['content']).decode())" \
> updates.xml 2>/dev/null || true > updates.xml 2>/dev/null || true
@@ -387,41 +356,58 @@ jobs:
# Commit updates.xml if changed # Commit updates.xml if changed
if ! git diff --quiet updates.xml 2>/dev/null; then if ! git diff --quiet updates.xml 2>/dev/null; then
git config --local user.email "gitea-actions[bot]@mokoconsulting.tech"
git config --local user.name "gitea-actions[bot]"
git remote set-url origin "https://jmiller:${{ secrets.GA_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git"
git add updates.xml git add updates.xml
git commit -m "chore: update stable channel ${VERSION} [skip ci]" \ git commit -m "chore: update stable channel ${VERSION} [skip ci]" \
--author="gitea-actions[bot] <gitea-actions[bot]@mokoconsulting.tech>" --author="gitea-actions[bot] <gitea-actions[bot]@mokoconsulting.tech>"
git push origin HEAD:refs/heads/main 2>&1 || true git push origin HEAD 2>&1 || true
fi fi
# -- STEP 8b: Update release description with changelog ---------------------- # -- STEP 8b: Update release description with changelog ----------------------
- name: "Step 8b: Update release body" - name: "Step 8b: Update release body"
if: steps.version.outputs.skip != 'true' if: steps.version.outputs.skip != 'true'
continue-on-error: true
run: | run: |
VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" VERSION="${{ steps.version.outputs.version }}"
RELEASE_TAG="${{ steps.version.outputs.release_tag }}" RELEASE_TAG="${{ steps.version.outputs.release_tag }}"
php /tmp/moko-platform-api/cli/release_body_update.php \ MOKO_CLI="/tmp/moko-platform-api/cli"
php ${MOKO_CLI}/release_body_update.php \
--path . --version "${VERSION}" --tag "${RELEASE_TAG}" \ --path . --version "${VERSION}" --tag "${RELEASE_TAG}" \
--token "${{ secrets.MOKOGITEA_TOKEN }}" \ --token "${{ secrets.GA_TOKEN }}" \
--gitea-url "${GITEA_URL}" --org "${GITEA_ORG}" --repo "${GITEA_REPO}" \ --gitea-url "${GITEA_URL}" --org "${GITEA_ORG}" --repo "${GITEA_REPO}" \
2>&1 || true 2>/dev/null || {
# Fallback: simple body update if CLI not available
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
RELEASE_ID=$(curl -sf -H "Authorization: token ${{ secrets.GA_TOKEN }}" \
"${API_BASE}/releases/tags/${RELEASE_TAG}" 2>/dev/null | \
python3 -c "import sys,json; print(json.load(sys.stdin).get('id',''))" 2>/dev/null || true)
if [ -n "$RELEASE_ID" ] && [ "$RELEASE_ID" != "None" ]; then
BODY="## ${VERSION} ($(date +%Y-%m-%d))\n\nChecksum files attached as \`*.sha256\` assets."
curl -sf -X PATCH -H "Authorization: token ${{ secrets.GA_TOKEN }}" \
-H "Content-Type: application/json" \
"${API_BASE}/releases/${RELEASE_ID}" \
-d "{\"body\":\"${BODY}\"}" > /dev/null 2>&1
fi
}
echo "Release body updated" >> $GITHUB_STEP_SUMMARY echo "Release body updated" >> $GITHUB_STEP_SUMMARY
# -- STEP 9: Mirror to GitHub (stable only) -------------------------------- # -- STEP 9: Mirror to GitHub (stable only) --------------------------------
- name: "Step 9: Mirror release to GitHub" - name: "Step 9: Mirror release to GitHub"
if: >- if: >-
steps.version.outputs.skip != 'true' && steps.version.outputs.skip != 'true' &&
secrets.GH_MIRROR_TOKEN != '' secrets.GH_TOKEN != ''
continue-on-error: true continue-on-error: true
run: | run: |
VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" VERSION="${{ steps.version.outputs.version }}"
RELEASE_TAG="${{ steps.version.outputs.release_tag }}" RELEASE_TAG="${{ steps.version.outputs.release_tag }}"
GH_REPO="${{ vars.GH_MIRROR_REPO || github.repository }}" GH_REPO="${{ vars.GH_MIRROR_REPO || github.repository }}"
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
php /tmp/moko-platform-api/cli/release_mirror.php \ php /tmp/moko-platform-api/cli/release_mirror.php \
--version "$VERSION" --tag "$RELEASE_TAG" \ --version "$VERSION" --tag "$RELEASE_TAG" \
--token "${{ secrets.MOKOGITEA_TOKEN }}" --api-base "$API_BASE" \ --token "${{ secrets.GA_TOKEN }}" --api-base "$API_BASE" \
--gh-token "${{ secrets.GH_MIRROR_TOKEN }}" --gh-repo "$GH_REPO" \ --gh-token "${{ secrets.GH_TOKEN }}" --gh-repo "$GH_REPO" \
--branch main 2>&1 || true --branch main 2>&1 || true
echo "GitHub mirror updated" >> $GITHUB_STEP_SUMMARY echo "GitHub mirror updated" >> $GITHUB_STEP_SUMMARY
@@ -429,14 +415,14 @@ jobs:
- name: "Step 10: Push main to GitHub mirror" - name: "Step 10: Push main to GitHub mirror"
if: >- if: >-
steps.version.outputs.skip != 'true' && steps.version.outputs.skip != 'true' &&
secrets.GH_MIRROR_TOKEN != '' secrets.GH_TOKEN != ''
continue-on-error: true continue-on-error: true
run: | run: |
GH_REPO="${{ vars.GH_MIRROR_REPO || github.repository }}" GH_REPO="${{ vars.GH_MIRROR_REPO || github.repository }}"
GH_ORG=$(echo "$GH_REPO" | cut -d/ -f1) GH_ORG=$(echo "$GH_REPO" | cut -d/ -f1)
GH_NAME=$(echo "$GH_REPO" | cut -d/ -f2) GH_NAME=$(echo "$GH_REPO" | cut -d/ -f2)
git remote add github "https://x-access-token:${{ secrets.GH_MIRROR_TOKEN }}@github.com/${GH_ORG}/${GH_NAME}.git" 2>/dev/null || \ git remote add github "https://x-access-token:${{ secrets.GH_TOKEN }}@github.com/${GH_ORG}/${GH_NAME}.git" 2>/dev/null || \
git remote set-url github "https://x-access-token:${{ secrets.GH_MIRROR_TOKEN }}@github.com/${GH_ORG}/${GH_NAME}.git" git remote set-url github "https://x-access-token:${{ secrets.GH_TOKEN }}@github.com/${GH_ORG}/${GH_NAME}.git"
git fetch origin main --depth=1 git fetch origin main --depth=1
git push github origin/main:refs/heads/main --force 2>/dev/null \ git push github origin/main:refs/heads/main --force 2>/dev/null \
&& echo "main branch pushed to GitHub mirror" \ && echo "main branch pushed to GitHub mirror" \
@@ -447,12 +433,12 @@ jobs:
- name: "Delete lesser pre-release channels" - name: "Delete lesser pre-release channels"
continue-on-error: true continue-on-error: true
run: | run: |
VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" VERSION="${{ steps.version.outputs.version }}"
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
php /tmp/moko-platform-api/cli/release_cascade.php \ php /tmp/moko-platform-api/cli/release_cascade.php \
--stability stable \ --stability stable \
--version "${VERSION}" \ --version "${VERSION}" \
--token "${{ secrets.MOKOGITEA_TOKEN }}" \ --token "${{ secrets.GA_TOKEN }}" \
--api-base "${API_BASE}" 2>/dev/null || true --api-base "${API_BASE}" 2>/dev/null || true
- name: "Step 11: Delete and recreate dev branch from main" - name: "Step 11: Delete and recreate dev branch from main"
@@ -460,7 +446,7 @@ jobs:
continue-on-error: true continue-on-error: true
run: | run: |
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
TOKEN="${{ secrets.MOKOGITEA_TOKEN }}" TOKEN="${{ secrets.GA_TOKEN }}"
# Delete dev branch # Delete dev branch
curl -sf -X DELETE -H "Authorization: token ${TOKEN}" \ curl -sf -X DELETE -H "Authorization: token ${TOKEN}" \
@@ -474,25 +460,6 @@ jobs:
echo "Dev branch reset from main (keeps dev ahead after release)" >> $GITHUB_STEP_SUMMARY echo "Dev branch reset from main (keeps dev ahead after release)" >> $GITHUB_STEP_SUMMARY
- name: "Step 12: Create version branch from main"
if: steps.version.outputs.skip != 'true'
continue-on-error: true
run: |
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
TOKEN="${{ secrets.MOKOGITEA_TOKEN }}"
VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}"
BRANCH_NAME="version/${VERSION}"
MAIN_SHA=$(git rev-parse HEAD)
# Delete old version branch if it exists (same version re-release)
curl -sf -X DELETE -H "Authorization: token ${TOKEN}" "${API_BASE}/branches/${BRANCH_NAME}" 2>/dev/null && echo "Deleted old ${BRANCH_NAME}"
# Create version/XX.YY.ZZ from main
curl -sf -X POST -H "Authorization: token ${TOKEN}" -H "Content-Type: application/json" "${API_BASE}/branches" -d "{\"new_branch_name\":\"${BRANCH_NAME}\",\"old_branch_name\":\"main\"}" 2>/dev/null && echo "Created ${BRANCH_NAME} from main (${MAIN_SHA})" || echo "WARNING: ${BRANCH_NAME} creation failed"
echo "Version branch created: ${BRANCH_NAME} (${MAIN_SHA})" >> $GITHUB_STEP_SUMMARY
# -- Dolibarr post-release: Reset dev version ----------------------------- # -- Dolibarr post-release: Reset dev version -----------------------------
- name: "Post-release: Reset dev version" - name: "Post-release: Reset dev version"
@@ -501,14 +468,14 @@ jobs:
run: | run: |
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
php /tmp/moko-platform-api/cli/version_reset_dev.php \ php /tmp/moko-platform-api/cli/version_reset_dev.php \
--token "${{ secrets.MOKOGITEA_TOKEN }}" --api-base "${API_BASE}" \ --token "${{ secrets.GA_TOKEN }}" --api-base "${API_BASE}" \
--branch dev --path . 2>&1 || true --branch dev --path . 2>&1 || true
# -- Summary -------------------------------------------------------------- # -- Summary --------------------------------------------------------------
- name: Pipeline Summary - name: Pipeline Summary
if: always() if: always()
run: | run: |
VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" VERSION="${{ steps.version.outputs.version }}"
PLATFORM="${{ steps.platform.outputs.platform }}" PLATFORM="${{ steps.platform.outputs.platform }}"
if [ "${{ steps.version.outputs.skip }}" = "true" ]; then if [ "${{ steps.version.outputs.skip }}" = "true" ]; then
echo "## Release Skipped" >> $GITHUB_STEP_SUMMARY echo "## Release Skipped" >> $GITHUB_STEP_SUMMARY
+1 -1
View File
@@ -143,7 +143,7 @@ jobs:
- name: Update updates.xml - name: Update updates.xml
if: success() if: success()
env: env:
GITEA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }} GITEA_TOKEN: ${{ secrets.GA_TOKEN }}
TAG: ${{ steps.config.outputs.tag }} TAG: ${{ steps.config.outputs.tag }}
INSTANCE_URL: ${{ steps.config.outputs.instance_url }} INSTANCE_URL: ${{ steps.config.outputs.instance_url }}
DEPLOY_ENV: ${{ github.event.inputs.environment }} DEPLOY_ENV: ${{ github.event.inputs.environment }}
+1 -1
View File
@@ -28,7 +28,7 @@ jobs:
steps: steps:
- name: Create branch and comment - name: Create branch and comment
run: | run: |
TOKEN="${{ secrets.MOKOGITEA_TOKEN }}" TOKEN="${{ secrets.GA_TOKEN }}"
API="${GITEA_URL}/api/v1/repos/${{ github.repository }}" API="${GITEA_URL}/api/v1/repos/${{ github.repository }}"
ISSUE_NUM="${{ github.event.issue.number }}" ISSUE_NUM="${{ github.event.issue.number }}"
ISSUE_TITLE="${{ github.event.issue.title }}" ISSUE_TITLE="${{ github.event.issue.title }}"
+2 -2
View File
@@ -108,7 +108,7 @@ jobs:
- name: Create RC release - name: Create RC release
if: steps.guard.outputs.skip != 'true' if: steps.guard.outputs.skip != 'true'
env: env:
GITEA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }} GITEA_TOKEN: ${{ secrets.GA_TOKEN }}
RC_TAG: ${{ steps.version.outputs.tag }} RC_TAG: ${{ steps.version.outputs.tag }}
RC_VERSION: ${{ steps.version.outputs.version }} RC_VERSION: ${{ steps.version.outputs.version }}
PR_TITLE: ${{ github.event.pull_request.title }} PR_TITLE: ${{ github.event.pull_request.title }}
@@ -155,7 +155,7 @@ jobs:
- name: Commit updates.xml - name: Commit updates.xml
if: steps.guard.outputs.skip != 'true' if: steps.guard.outputs.skip != 'true'
env: env:
GITEA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }} GITEA_TOKEN: ${{ secrets.GA_TOKEN }}
HEAD_REF: ${{ github.event.pull_request.head.ref }} HEAD_REF: ${{ github.event.pull_request.head.ref }}
PR_NUM: ${{ github.event.pull_request.number }} PR_NUM: ${{ github.event.pull_request.number }}
run: | run: |
+126 -46
View File
@@ -50,23 +50,30 @@ jobs:
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
token: ${{ secrets.MOKOGITEA_TOKEN }} token: ${{ secrets.GA_TOKEN }}
- name: Setup moko-platform tools - name: Setup tools
env:
MOKO_CLONE_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting
run: | run: |
if ! command -v composer &> /dev/null; then # Update moko-platform CLI tools if available; install PHP if missing
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 if command -v moko-platform-update &> /dev/null; then
moko-platform-update
elif [ -d "/opt/moko-platform" ]; then
cd /opt/moko-platform && git pull origin main --quiet 2>/dev/null || true
else
if ! command -v php &> /dev/null; then
sudo apt-get update -qq
sudo apt-get install -y -qq php-cli php-mbstring php-xml php-zip php-curl >/dev/null 2>&1
fi fi
# Always fetch latest CLI tools — never use stale cache from previous runs
rm -rf /tmp/moko-platform-api
git clone --depth 1 --branch main --quiet \ git clone --depth 1 --branch main --quiet \
"https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/moko-platform.git" \ "https://x-access-token:${{ secrets.GA_TOKEN }}@git.mokoconsulting.tech/MokoConsulting/moko-platform.git" \
/tmp/moko-platform-api /tmp/moko-platform-api
cd /tmp/moko-platform-api && composer install --no-dev --no-interaction --quiet fi
# Set MOKO_CLI to whichever path exists
if [ -d "/opt/moko-platform/cli" ]; then
echo "MOKO_CLI=/opt/moko-platform/cli" >> "$GITHUB_ENV"
else
echo "MOKO_CLI=/tmp/moko-platform-api/cli" >> "$GITHUB_ENV" echo "MOKO_CLI=/tmp/moko-platform-api/cli" >> "$GITHUB_ENV"
fi
- name: Detect platform - name: Detect platform
id: platform id: platform
@@ -89,24 +96,16 @@ jobs:
VERSION=$(php ${MOKO_CLI}/version_read.php --path . 2>/dev/null) VERSION=$(php ${MOKO_CLI}/version_read.php --path . 2>/dev/null)
[ -z "$VERSION" ] && VERSION="00.00.01" [ -z "$VERSION" ] && VERSION="00.00.01"
# Strip any existing suffix from version before applying stability
VERSION=$(echo "$VERSION" | sed 's/-\(dev\|alpha\|beta\|rc\)$//')
php ${MOKO_CLI}/version_set_platform.php \ php ${MOKO_CLI}/version_set_platform.php \
--path . --version "$VERSION" --branch "${{ github.ref_name }}" --stability "$STABILITY" 2>/dev/null || true --path . --version "$VERSION" --branch "${{ github.ref_name }}" 2>/dev/null || true
# Verify version consistency across all files # Verify version consistency across all files
php ${MOKO_CLI}/version_check.php --path . --fix 2>/dev/null || true php ${MOKO_CLI}/version_check.php --path . --fix 2>/dev/null || true
# Update VERSION variable with suffix
if [ -n "$SUFFIX" ]; then
VERSION="${VERSION}${SUFFIX}"
fi
# Commit version bump # Commit version bump
git config --local user.email "gitea-actions[bot]@mokoconsulting.tech" git config --local user.email "gitea-actions[bot]@mokoconsulting.tech"
git config --local user.name "gitea-actions[bot]" 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 remote set-url origin "https://jmiller:${{ secrets.GA_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git"
git add -A git add -A
git diff --cached --quiet || { git diff --cached --quiet || {
git commit -m "chore(version): pre-release bump to ${VERSION} [skip ci]" git commit -m "chore(version): pre-release bump to ${VERSION} [skip ci]"
@@ -122,7 +121,7 @@ jobs:
EXT_ELEMENT=$(grep '^ext_element=' "$GITHUB_OUTPUT" | tail -1 | cut -d= -f2) EXT_ELEMENT=$(grep '^ext_element=' "$GITHUB_OUTPUT" | tail -1 | cut -d= -f2)
ZIP_NAME=$(grep '^zip_name=' "$GITHUB_OUTPUT" | tail -1 | cut -d= -f2) ZIP_NAME=$(grep '^zip_name=' "$GITHUB_OUTPUT" | tail -1 | cut -d= -f2)
[ -z "$EXT_ELEMENT" ] && EXT_ELEMENT=$(echo "${GITEA_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -') [ -z "$EXT_ELEMENT" ] && EXT_ELEMENT=$(echo "${GITEA_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -')
[ -z "$ZIP_NAME" ] && ZIP_NAME="${EXT_ELEMENT}-${VERSION}.zip" [ -z "$ZIP_NAME" ] && ZIP_NAME="${EXT_ELEMENT}-${VERSION}${SUFFIX}.zip"
echo "version=${VERSION}" >> "$GITHUB_OUTPUT" echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
echo "stability=${STABILITY}" >> "$GITHUB_OUTPUT" echo "stability=${STABILITY}" >> "$GITHUB_OUTPUT"
@@ -130,50 +129,131 @@ jobs:
echo "tag=${TAG}" >> "$GITHUB_OUTPUT" echo "tag=${TAG}" >> "$GITHUB_OUTPUT"
echo "zip_name=${ZIP_NAME}" >> "$GITHUB_OUTPUT" echo "zip_name=${ZIP_NAME}" >> "$GITHUB_OUTPUT"
echo "ext_element=${EXT_ELEMENT}" >> "$GITHUB_OUTPUT" echo "ext_element=${EXT_ELEMENT}" >> "$GITHUB_OUTPUT"
echo "manifest=${MANIFEST}" >> "$GITHUB_OUTPUT"
echo "=== Pre-Release: ${EXT_ELEMENT} ${VERSION}${SUFFIX} ===" echo "=== Pre-Release: ${EXT_ELEMENT} ${VERSION}${SUFFIX} ==="
- name: Create release - name: Build package
run: |
SOURCE_DIR="src"
[ ! -d "$SOURCE_DIR" ] && SOURCE_DIR="htdocs"
if [ ! -d "$SOURCE_DIR" ]; then
echo "::error::No src/ or htdocs/ directory"
exit 1
fi
MANIFEST="${{ steps.meta.outputs.manifest }}"
EXT_TYPE=""
if [ -n "$MANIFEST" ]; then
EXT_TYPE=$(sed -n 's/.*<extension[^>]*type="\([^"]*\)".*/\1/p' "$MANIFEST" | head -1)
fi
EXCLUDES="sftp-config* .ftpignore *.ppk *.pem *.key .env* *.local .build-trigger"
mkdir -p build/package
if [ "$EXT_TYPE" = "package" ] && [ -d "${SOURCE_DIR}/packages" ]; then
echo "=== Building Joomla PACKAGE (multi-extension) ==="
for ext_dir in "${SOURCE_DIR}"/packages/*/; do
[ ! -d "$ext_dir" ] && continue
EXT_NAME=$(basename "$ext_dir")
echo " Packaging sub-extension: ${EXT_NAME}"
cd "$ext_dir"
zip -r "../../build/package/${EXT_NAME}.zip" . -x $EXCLUDES
cd "$OLDPWD"
done
for f in "${SOURCE_DIR}"/*.xml "${SOURCE_DIR}"/*.php; do
[ -f "$f" ] && cp "$f" build/package/
done
else
echo "=== Building standard extension ==="
rsync -a \
--exclude='sftp-config*' \
--exclude='.ftpignore' \
--exclude='*.ppk' \
--exclude='*.pem' \
--exclude='*.key' \
--exclude='.env*' \
--exclude='*.local' \
--exclude='.build-trigger' \
"${SOURCE_DIR}/" build/package/
fi
- name: Create ZIP
id: zip
run: |
ZIP_NAME="${{ steps.meta.outputs.zip_name }}"
cd build/package
zip -r "../${ZIP_NAME}" .
cd ..
SHA256=$(sha256sum "${ZIP_NAME}" | cut -d' ' -f1)
echo "sha256=${SHA256}" >> "$GITHUB_OUTPUT"
echo "ZIP: ${ZIP_NAME} (SHA: ${SHA256:0:16}...)"
- name: Create or replace Gitea release
id: release id: release
run: | run: |
TAG="${{ steps.meta.outputs.tag }}" TAG="${{ steps.meta.outputs.tag }}"
VERSION="${{ steps.meta.outputs.version }}" VERSION="${{ steps.meta.outputs.version }}"
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" STABILITY="${{ steps.meta.outputs.stability }}"
php ${MOKO_CLI}/release_create.php \ SHA256="${{ steps.zip.outputs.sha256 }}"
--path . --version "$VERSION" --tag "$TAG" \ ZIP_NAME="${{ steps.meta.outputs.zip_name }}"
--token "${{ secrets.MOKOGITEA_TOKEN }}" --api-base "$API_BASE" \ EXT_ELEMENT="${{ steps.meta.outputs.ext_element }}"
--repo "${GITEA_REPO}" --branch dev --prerelease TOKEN="${{ secrets.GA_TOKEN }}"
API="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
BRANCH=$(git branch --show-current)
- name: Build package and upload BODY="## ${VERSION} ($(date +%Y-%m-%d))
id: package **Channel:** ${STABILITY}
run: | **SHA-256:** \`${SHA256}\`"
VERSION="${{ steps.meta.outputs.version }}"
TAG="${{ steps.meta.outputs.tag }}" # Delete existing release
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" EXISTING_ID=$(curl -sS -H "Authorization: token ${TOKEN}" \
php ${MOKO_CLI}/release_package.php \ "${API}/releases/tags/${TAG}" | jq -r '.id // empty' 2>/dev/null)
--path . --version "$VERSION" --tag "$TAG" \ if [ -n "$EXISTING_ID" ]; then
--token "${{ secrets.MOKOGITEA_TOKEN }}" --api-base "$API_BASE" \ curl -sS -X DELETE -H "Authorization: token ${TOKEN}" \
--repo "${GITEA_REPO}" --output /tmp || true "${API}/releases/${EXISTING_ID}" 2>/dev/null || true
curl -sS -X DELETE -H "Authorization: token ${TOKEN}" \
"${API}/tags/${TAG}" 2>/dev/null || true
fi
# Create release
RELEASE_ID=$(curl -sS -X POST -H "Authorization: token ${TOKEN}" \
-H "Content-Type: application/json" \
"${API}/releases" \
-d "$(jq -n \
--arg tag "$TAG" \
--arg target "$BRANCH" \
--arg name "${EXT_ELEMENT} ${VERSION} (${STABILITY})" \
--arg body "$BODY" \
'{tag_name: $tag, target_commitish: $target, name: $name, body: $body, prerelease: true}'
)" | jq -r '.id')
echo "release_id=${RELEASE_ID}" >> "$GITHUB_OUTPUT"
# Upload ZIP
curl -sS -X POST -H "Authorization: token ${TOKEN}" \
-H "Content-Type: application/octet-stream" \
"${API}/releases/${RELEASE_ID}/assets?name=${ZIP_NAME}" \
--data-binary "@build/${ZIP_NAME}"
echo "Released: ${EXT_ELEMENT} ${VERSION} (${STABILITY})"
- name: Update updates.xml - name: Update updates.xml
if: steps.platform.outputs.platform == 'joomla' if: steps.platform.outputs.platform == 'joomla'
run: | run: |
VERSION="${{ steps.meta.outputs.version }}" VERSION="${{ steps.meta.outputs.version }}"
STABILITY="${{ steps.meta.outputs.stability }}" STABILITY="${{ steps.meta.outputs.stability }}"
SHA256="${{ steps.package.outputs.sha256_zip }}"
if [ ! -f "updates.xml" ]; then if [ ! -f "updates.xml" ]; then
echo "No updates.xml -- skipping" echo "No updates.xml -- skipping"
exit 0 exit 0
fi fi
SHA_FLAG=""
[ -n "$SHA256" ] && SHA_FLAG="--sha ${SHA256}"
php ${MOKO_CLI}/updates_xml_build.php \ php ${MOKO_CLI}/updates_xml_build.php \
--path . --version "${VERSION}" --stability "${STABILITY}" \ --path . --version "${VERSION}" --stability "${STABILITY}" \
--gitea-url "${GITEA_URL}" --org "${GITEA_ORG}" --repo "${GITEA_REPO}" \ --gitea-url "${GITEA_URL}" --org "${GITEA_ORG}" --repo "${GITEA_REPO}"
${SHA_FLAG}
# Commit and push # Commit and push
if ! git diff --quiet updates.xml 2>/dev/null; then if ! git diff --quiet updates.xml 2>/dev/null; then
@@ -209,7 +289,7 @@ jobs:
continue-on-error: true continue-on-error: true
run: | run: |
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
TOKEN="${{ secrets.MOKOGITEA_TOKEN }}" TOKEN="${{ secrets.GA_TOKEN }}"
php ${MOKO_CLI}/release_cascade.php \ php ${MOKO_CLI}/release_cascade.php \
--stability "${{ steps.meta.outputs.stability }}" \ --stability "${{ steps.meta.outputs.stability }}" \
@@ -222,7 +302,7 @@ jobs:
VERSION="${{ steps.meta.outputs.version }}" VERSION="${{ steps.meta.outputs.version }}"
STABILITY="${{ steps.meta.outputs.stability }}" STABILITY="${{ steps.meta.outputs.stability }}"
ZIP_NAME="${{ steps.meta.outputs.zip_name }}" ZIP_NAME="${{ steps.meta.outputs.zip_name }}"
SHA256="${{ steps.package.outputs.sha256_zip }}" SHA256="${{ steps.zip.outputs.sha256 }}"
echo "## Pre-Release Complete" >> $GITHUB_STEP_SUMMARY echo "## Pre-Release Complete" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY
echo "| Field | Value |" >> $GITHUB_STEP_SUMMARY echo "| Field | Value |" >> $GITHUB_STEP_SUMMARY
+465 -114
View File
@@ -4,16 +4,18 @@
# #
# FILE INFORMATION # FILE INFORMATION
# DEFGROUP: Gitea.Workflow # DEFGROUP: Gitea.Workflow
# INGROUP: moko-platform.Universal # INGROUP: MokoStandards.Universal
# REPO: https://git.mokoconsulting.tech/MokoConsulting/moko-platform # REPO: https://git.mokoconsulting.tech/MokoConsulting/moko-platform
# PATH: /templates/workflows/update-server.yml # PATH: /templates/workflows/update-server.yml
# VERSION: 05.00.00 # VERSION: 04.07.00
# BRIEF: Pre-release build + update server XML for dev/alpha/beta/rc branches # BRIEF: Update server XML feed with stable/rc/beta/alpha/dev entries (universal)
# #
# Thin wrapper around moko-platform CLI tools. # Writes updates.xml with multiple <update> entries:
# Builds packages, updates updates.xml, and optionally deploys via SFTP. # - <tag>stable</tag> on push to main (from auto-release)
# - <tag>rc</tag> on push to rc/**
# - <tag>development</tag> on push to dev or dev/**
# #
# Joomla filters update entries by the user's "Minimum Stability" setting. # Joomla filters by user's "Minimum Stability" setting.
name: "Update Server" name: "Update Server"
@@ -64,7 +66,7 @@ permissions:
jobs: jobs:
update-xml: update-xml:
name: Update Server name: Update updates.xml
runs-on: release runs-on: release
if: >- if: >-
github.event.pull_request.merged == true || github.event_name == 'workflow_dispatch' || github.event_name == 'push' github.event.pull_request.merged == true || github.event_name == 'workflow_dispatch' || github.event_name == 'push'
@@ -73,48 +75,50 @@ jobs:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
token: ${{ secrets.MOKOGITEA_TOKEN }} token: ${{ secrets.GA_TOKEN }}
fetch-depth: 0 fetch-depth: 0
- name: Setup moko-platform tools - name: Setup moko-platform tools
env: env:
MOKO_CLONE_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }} MOKO_CLONE_TOKEN: ${{ secrets.GA_TOKEN }}
MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting
COMPOSER_AUTH: '{"http-basic":{"git.mokoconsulting.tech":{"username":"token","password":"${{ secrets.MOKOGITEA_TOKEN }}"}}}' COMPOSER_AUTH: '{"http-basic":{"git.mokoconsulting.tech":{"username":"token","password":"${{ secrets.GA_TOKEN }}"}}}'
run: | run: |
if ! command -v composer &> /dev/null; then if ! command -v composer &> /dev/null; then
sudo apt-get update -qq && sudo apt-get install -y -qq php-cli php-mbstring php-xml php-zip php-curl composer >/dev/null 2>&1 sudo apt-get update -qq && sudo apt-get install -y -qq php-cli php-mbstring php-xml php-zip php-curl composer >/dev/null 2>&1
fi fi
# Always fetch latest CLI tools — never use stale cache from previous runs if [ -d "/tmp/moko-platform" ]; then
rm -rf /tmp/moko-platform echo "moko-platform already available — skipping clone"
else
git clone --depth 1 --branch main --quiet \ git clone --depth 1 --branch main --quiet \
"https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/moko-platform.git" \ "https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/moko-platform.git" \
/tmp/moko-platform 2>/dev/null || true /tmp/moko-platform 2>/dev/null || true
fi
if [ -d "/tmp/moko-platform" ] && [ -f "/tmp/moko-platform/composer.json" ]; then if [ -d "/tmp/moko-platform" ] && [ -f "/tmp/moko-platform/composer.json" ]; then
cd /tmp/moko-platform && composer install --no-dev --no-interaction --quiet 2>/dev/null || true cd /tmp/moko-platform && composer install --no-dev --no-interaction --quiet 2>/dev/null || true
fi fi
echo "MOKO_CLI=/tmp/moko-platform/cli" >> "$GITHUB_ENV"
- name: Detect platform - name: Generate updates.xml entry
id: platform id: update
run: php ${MOKO_CLI}/manifest_read.php --path . --github-output
- name: Resolve stability and bump version
id: meta
run: | run: |
BRANCH="${{ github.ref_name }}" BRANCH="${{ github.ref_name }}"
REPO="${{ github.repository }}"
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
VERSION=$(php /tmp/moko-platform/cli/version_read.php --path . 2>/dev/null || echo "0.0.0")
# Configure git for bot pushes # Auto-bump patch on all branches (dev, alpha, beta, rc)
git config --local user.email "gitea-actions[bot]@mokoconsulting.tech" git config --local user.email "gitea-actions[bot]@mokoconsulting.tech"
git config --local user.name "gitea-actions[bot]" 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" BUMPED=$(php /tmp/moko-platform/cli/version_bump.php --path . 2>/dev/null || true)
if [ -n "$BUMPED" ]; then
VERSION=$(php /tmp/moko-platform/cli/version_read.php --path . 2>/dev/null || echo "$VERSION")
git add -A
git commit -m "chore(version): auto-bump patch ${VERSION} [skip ci]" \
--author="gitea-actions[bot] <gitea-actions[bot]@mokoconsulting.tech>" 2>/dev/null || true
git push 2>/dev/null || true
fi
# Auto-bump patch version # Determine stability from branch or input
php ${MOKO_CLI}/version_bump.php --path . 2>/dev/null || true
VERSION=$(php ${MOKO_CLI}/version_read.php --path . 2>/dev/null || echo "0.0.0")
# Determine stability from branch or manual input
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
STABILITY="${{ inputs.stability }}" STABILITY="${{ inputs.stability }}"
elif [[ "$BRANCH" == rc/* ]]; then elif [[ "$BRANCH" == rc/* ]]; then
@@ -123,96 +127,263 @@ jobs:
STABILITY="beta" STABILITY="beta"
elif [[ "$BRANCH" == alpha/* ]]; then elif [[ "$BRANCH" == alpha/* ]]; then
STABILITY="alpha" STABILITY="alpha"
else elif [[ "$BRANCH" == dev/* ]] || [[ "$BRANCH" == "dev" ]]; then
STABILITY="development" STABILITY="development"
else
STABILITY="stable"
fi fi
# Version suffix per stability stream echo "stability=${STABILITY}" >> "$GITHUB_OUTPUT"
# Parse manifest (portable — no grep -P)
MANIFEST=$(find . -maxdepth 3 -name "*.xml" ! -path "./.git/*" ! -path "./build/*" -exec grep -l '<extension' {} \; 2>/dev/null | head -1)
if [ -z "$MANIFEST" ]; then
echo "No Joomla manifest found — skipping"
exit 0
fi
# Extract fields using sed (works on all runners)
EXT_NAME=$(sed -n 's/.*<name>\([^<]*\)<\/name>.*/\1/p' "$MANIFEST" | head -1)
EXT_TYPE=$(sed -n 's/.*<extension[^>]*type="\([^"]*\)".*/\1/p' "$MANIFEST" | head -1)
EXT_ELEMENT=$(sed -n 's/.*<element>\([^<]*\)<\/element>.*/\1/p' "$MANIFEST" | head -1)
EXT_CLIENT=$(sed -n 's/.*<extension[^>]*client="\([^"]*\)".*/\1/p' "$MANIFEST" | head -1)
EXT_FOLDER=$(sed -n 's/.*<extension[^>]*group="\([^"]*\)".*/\1/p' "$MANIFEST" | head -1)
EXT_VERSION=$(sed -n 's/.*<version>\([^<]*\)<\/version>.*/\1/p' "$MANIFEST" | head -1)
TARGET_PLATFORM=$(sed -n 's/.*\(<targetplatform[^/]*\/>\).*/\1/p' "$MANIFEST" | head -1)
PHP_MINIMUM=$(sed -n 's/.*<php_minimum>\([^<]*\)<\/php_minimum>.*/\1/p' "$MANIFEST" | head -1)
# Fallbacks
[ -z "$EXT_NAME" ] && EXT_NAME="${{ github.event.repository.name }}"
[ -z "$EXT_TYPE" ] && EXT_TYPE="component"
# Derive element if not in manifest: try XML filename, then repo name
if [ -z "$EXT_ELEMENT" ]; then
EXT_ELEMENT=$(basename "$MANIFEST" .xml | tr '[:upper:]' '[:lower:]')
case "$EXT_ELEMENT" in
templatedetails|manifest|*.xml) EXT_ELEMENT=$(echo "${{ github.event.repository.name }}" | tr '[:upper:]' '[:lower:]' | tr -d ' -') ;;
esac
fi
# Use manifest version if README version is empty
[ "$VERSION" = "0.0.0" ] && [ -n "$EXT_VERSION" ] && VERSION="$EXT_VERSION"
[ -z "$TARGET_PLATFORM" ] && TARGET_PLATFORM=$(printf '<targetplatform name="joomla" version="((5.[0-9])|(6.[0-9]))" %s>' "/")
# Joomla requires <client> on ALL extension types for update matching
if [ -n "$EXT_CLIENT" ]; then
CLIENT_TAG="<client>${EXT_CLIENT}</client>"
else
CLIENT_TAG="<client>site</client>"
fi
FOLDER_TAG=""
[ -n "$EXT_FOLDER" ] && [ "$EXT_TYPE" = "plugin" ] && FOLDER_TAG="<folder>${EXT_FOLDER}</folder>"
PHP_TAG=""
[ -n "$PHP_MINIMUM" ] && PHP_TAG="<php_minimum>${PHP_MINIMUM}</php_minimum>"
# Version suffix for non-stable
DISPLAY_VERSION="$VERSION"
case "$STABILITY" in case "$STABILITY" in
development) SUFFIX="-dev"; TAG="development" ;; development) DISPLAY_VERSION="${VERSION}-dev" ;;
alpha) SUFFIX="-alpha"; TAG="alpha" ;; alpha) DISPLAY_VERSION="${VERSION}-alpha" ;;
beta) SUFFIX="-beta"; TAG="beta" ;; beta) DISPLAY_VERSION="${VERSION}-beta" ;;
rc) SUFFIX="-rc"; TAG="release-candidate" ;; rc) DISPLAY_VERSION="${VERSION}-rc" ;;
*) SUFFIX=""; TAG="stable" ;;
esac esac
# Propagate version with stability suffix to all manifest files MAJOR=$(echo "$VERSION" | awk -F. '{print $1}')
php ${MOKO_CLI}/version_set_platform.php \
--path . --version "$VERSION" --branch "$BRANCH" --stability "$STABILITY" 2>/dev/null || true
php ${MOKO_CLI}/version_check.php --path . --fix 2>/dev/null || true
# Re-read version (now includes suffix from version_set_platform) # Each stability level has its own release tag
if [ -n "$SUFFIX" ]; then case "$STABILITY" in
VERSION="${VERSION}${SUFFIX}" development) RELEASE_TAG="development" ;;
alpha) RELEASE_TAG="alpha" ;;
beta) RELEASE_TAG="beta" ;;
rc) RELEASE_TAG="release-candidate" ;;
*) RELEASE_TAG="v${MAJOR}" ;;
esac
PACKAGE_NAME="${EXT_ELEMENT}-${DISPLAY_VERSION}.zip"
DOWNLOAD_URL="${GITEA_URL}/${GITEA_ORG}/${GITEA_REPO}/releases/download/${RELEASE_TAG}/${PACKAGE_NAME}"
INFO_URL="${GITEA_URL}/${GITEA_ORG}/${GITEA_REPO}"
# -- Build install packages (ZIP + tar.gz) --------------------
SOURCE_DIR="src"
[ ! -d "$SOURCE_DIR" ] && SOURCE_DIR="htdocs"
if [ -d "$SOURCE_DIR" ]; then
EXCLUDES=".ftpignore sftp-config* *.ppk *.pem *.key .env*"
TAR_NAME="${EXT_ELEMENT}-${DISPLAY_VERSION}.tar.gz"
cd "$SOURCE_DIR"
zip -r "/tmp/${PACKAGE_NAME}" . -x $EXCLUDES
cd ..
tar -czf "/tmp/${TAR_NAME}" -C "$SOURCE_DIR" \
--exclude='.ftpignore' --exclude='sftp-config*' \
--exclude='*.ppk' --exclude='*.pem' --exclude='*.key' --exclude='.env*' .
SHA256=$(sha256sum "/tmp/${PACKAGE_NAME}" | cut -d' ' -f1)
# Ensure release exists on Gitea
RELEASE_JSON=$(curl -sf -H "Authorization: token ${{ secrets.GA_TOKEN }}" \
"${API_BASE}/releases/tags/${RELEASE_TAG}" 2>/dev/null || true)
RELEASE_ID=$(echo "$RELEASE_JSON" | python3 -c "import sys,json; print(json.load(sys.stdin).get('id',''))" 2>/dev/null || true)
if [ -z "$RELEASE_ID" ]; then
# Create release
RELEASE_JSON=$(curl -sf -X POST -H "Authorization: token ${{ secrets.GA_TOKEN }}" \
-H "Content-Type: application/json" \
"${API_BASE}/releases" \
-d "$(python3 -c "import json; print(json.dumps({
'tag_name': '${RELEASE_TAG}',
'name': '${RELEASE_TAG} (${DISPLAY_VERSION})',
'body': '${STABILITY} release',
'prerelease': True,
'target_commitish': 'main'
}))")" 2>/dev/null || true)
RELEASE_ID=$(echo "$RELEASE_JSON" | python3 -c "import sys,json; print(json.load(sys.stdin).get('id',''))" 2>/dev/null || true)
fi fi
echo "version=${VERSION}" >> "$GITHUB_OUTPUT" if [ -n "$RELEASE_ID" ]; then
echo "stability=${STABILITY}" >> "$GITHUB_OUTPUT" # Delete existing assets with same name before uploading
echo "suffix=${SUFFIX}" >> "$GITHUB_OUTPUT" ASSETS=$(curl -sf -H "Authorization: token ${{ secrets.GA_TOKEN }}" \
echo "tag=${TAG}" >> "$GITHUB_OUTPUT" "${API_BASE}/releases/${RELEASE_ID}/assets" 2>/dev/null || echo "[]")
echo "display_version=${VERSION}" >> "$GITHUB_OUTPUT" for ASSET_FILE in "$PACKAGE_NAME" "$TAR_NAME"; do
ASSET_ID=$(echo "$ASSETS" | python3 -c "
import sys,json
assets = json.load(sys.stdin)
for a in assets:
if a['name'] == '${ASSET_FILE}':
print(a['id']); break
" 2>/dev/null || true)
if [ -n "$ASSET_ID" ]; then
curl -sf -X DELETE -H "Authorization: token ${{ secrets.GA_TOKEN }}" \
"${API_BASE}/releases/${RELEASE_ID}/assets/${ASSET_ID}" 2>/dev/null || true
fi
done
# Commit version bump if changed # Upload both formats
git add -A curl -sf -X POST -H "Authorization: token ${{ secrets.GA_TOKEN }}" \
-H "Content-Type: application/octet-stream" \
--data-binary @"/tmp/${PACKAGE_NAME}" \
"${API_BASE}/releases/${RELEASE_ID}/assets?name=${PACKAGE_NAME}" > /dev/null 2>&1 || true
curl -sf -X POST -H "Authorization: token ${{ secrets.GA_TOKEN }}" \
-H "Content-Type: application/octet-stream" \
--data-binary @"/tmp/${TAR_NAME}" \
"${API_BASE}/releases/${RELEASE_ID}/assets?name=${TAR_NAME}" > /dev/null 2>&1 || true
fi
echo "Packages: ${PACKAGE_NAME} + ${TAR_NAME} (SHA: ${SHA256})" >> $GITHUB_STEP_SUMMARY
else
SHA256=""
fi
# -- Build the new entry (canonical format matching release.yml) --
NEW_ENTRY=""
NEW_ENTRY="${NEW_ENTRY} <update>\n"
NEW_ENTRY="${NEW_ENTRY} <name>${EXT_NAME}</name>\n"
NEW_ENTRY="${NEW_ENTRY} <description>${EXT_NAME} ${STABILITY} build.</description>\n"
NEW_ENTRY="${NEW_ENTRY} <element>${EXT_ELEMENT}</element>\n"
NEW_ENTRY="${NEW_ENTRY} <type>${EXT_TYPE}</type>\n"
[ -n "$CLIENT_TAG" ] && NEW_ENTRY="${NEW_ENTRY} ${CLIENT_TAG}\n"
[ -n "$FOLDER_TAG" ] && NEW_ENTRY="${NEW_ENTRY} ${FOLDER_TAG}\n"
NEW_ENTRY="${NEW_ENTRY} <version>${VERSION}</version>\n"
NEW_ENTRY="${NEW_ENTRY} <creationDate>$(date +%Y-%m-%d)</creationDate>\n"
NEW_ENTRY="${NEW_ENTRY} <infourl title='${EXT_NAME}'>https://git.mokoconsulting.tech/${GITEA_ORG}/${GITEA_REPO}/releases/tag/${RELEASE_TAG}</infourl>\n"
NEW_ENTRY="${NEW_ENTRY} <downloads>\n"
NEW_ENTRY="${NEW_ENTRY} <downloadurl type='full' format='zip'>${DOWNLOAD_URL}</downloadurl>\n"
NEW_ENTRY="${NEW_ENTRY} </downloads>\n"
[ -n "$SHA256" ] && NEW_ENTRY="${NEW_ENTRY} <sha256>${SHA256}</sha256>\n"
NEW_ENTRY="${NEW_ENTRY} <tags><tag>${STABILITY}</tag></tags>\n"
NEW_ENTRY="${NEW_ENTRY} <maintainer>Moko Consulting</maintainer>\n"
NEW_ENTRY="${NEW_ENTRY} <maintainerurl>https://mokoconsulting.tech</maintainerurl>\n"
NEW_ENTRY="${NEW_ENTRY} <targetplatform name='joomla' version='(5|6).*'/>\n"
[ -n "$PHP_MINIMUM" ] && NEW_ENTRY="${NEW_ENTRY} <php_minimum>${PHP_MINIMUM}</php_minimum>\n"
NEW_ENTRY="${NEW_ENTRY} </update>"
# -- Write new entry to temp file --------------------------------
printf '%b' "$NEW_ENTRY" > /tmp/new_entry.xml
# -- Merge into updates.xml ----------------------------------------
# Cascade: stable→all | rc→rc+lower | beta→beta+lower | alpha→alpha+dev | dev→dev
CASCADE_MAP="stable:development,alpha,beta,rc,stable rc:development,alpha,beta,rc beta:development,alpha,beta alpha:development,alpha development:development"
TARGETS=""
for entry in $CASCADE_MAP; do
key="${entry%%:*}"
vals="${entry#*:}"
if [ "$key" = "${STABILITY}" ]; then
TARGETS="$vals"
break
fi
done
[ -z "$TARGETS" ] && TARGETS="${STABILITY}"
echo "Cascade: ${STABILITY} → ${TARGETS}"
# Create updates.xml if missing
if [ ! -f "updates.xml" ]; then
printf '%s\n' "<?xml version='1.0' encoding='UTF-8'?>" > updates.xml
printf '%s\n' "<!-- Copyright (C) $(date +%Y) Moko Consulting -->" >> updates.xml
printf '%s\n' "<updates>" >> updates.xml
printf '%s\n' "</updates>" >> updates.xml
fi
# Update existing blocks or create missing ones
export PY_TARGETS="$TARGETS" PY_VERSION="$VERSION" PY_DATE="$(date +%Y-%m-%d)"
python3 << 'PYEOF'
import re, os
targets = os.environ["PY_TARGETS"].split(",")
version = os.environ["PY_VERSION"]
date = os.environ["PY_DATE"]
with open("updates.xml") as f:
content = f.read()
with open("/tmp/new_entry.xml") as f:
new_entry_template = f.read()
for tag in targets:
tag = tag.strip()
# Build entry with this tag's name
new_entry = re.sub(r"<tag>[^<]*</tag>", f"<tag>{tag}</tag>", new_entry_template)
# Try to find existing block (handles both single-line and multi-line <tags>)
block_pattern = r"(<update>(?:(?!</update>).)*?<tag>" + re.escape(tag) + r"</tag>.*?</update>)"
match = re.search(block_pattern, content, re.DOTALL)
if match:
# Update in place — replace entire block
content = content.replace(match.group(1), new_entry.strip())
print(f" UPDATED: <tag>{tag}</tag> → {version}")
else:
# Create — insert before </updates>
content = content.replace("</updates>", "\n" + new_entry.strip() + "\n\n</updates>")
print(f" CREATED: <tag>{tag}</tag> → {version}")
# Clean up excessive blank lines
content = re.sub(r"\n{3,}", "\n\n", content)
with open("updates.xml", "w") as f:
f.write(content)
PYEOF
# Commit
git config --local user.email "gitea-actions[bot]@mokoconsulting.tech"
git config --local user.name "gitea-actions[bot]"
git add updates.xml
git diff --cached --quiet || { git diff --cached --quiet || {
git commit -m "chore(version): auto-bump ${VERSION} [skip ci]" \ git commit -m "chore: update updates.xml (${STABILITY}: ${DISPLAY_VERSION}) [skip ci]" \
--author="gitea-actions[bot] <gitea-actions[bot]@mokoconsulting.tech>" --author="gitea-actions[bot] <gitea-actions[bot]@mokoconsulting.tech>"
git push git push
} }
- name: Create release and upload package # -- Sync updates.xml to main (for non-main branches) ----------------------
id: package
run: |
VERSION="${{ steps.meta.outputs.version }}"
TAG="${{ steps.meta.outputs.tag }}"
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
# Create or update Gitea release
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
# Build package and upload
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
- name: Update updates.xml
if: steps.platform.outputs.platform == 'joomla'
run: |
VERSION="${{ steps.meta.outputs.version }}"
STABILITY="${{ steps.meta.outputs.stability }}"
SHA256="${{ steps.package.outputs.sha256_zip }}"
if [ ! -f "updates.xml" ]; then
echo "No updates.xml — skipping"
exit 0
fi
SHA_FLAG=""
[ -n "$SHA256" ] && SHA_FLAG="--sha ${SHA256}"
php ${MOKO_CLI}/updates_xml_build.php \
--path . --version "${VERSION}" --stability "${STABILITY}" \
--gitea-url "${GITEA_URL}" --org "${GITEA_ORG}" --repo "${GITEA_REPO}" \
${SHA_FLAG}
# Commit and push updates.xml
git add updates.xml
git diff --cached --quiet || {
git commit -m "chore: update ${STABILITY} channel ${VERSION} [skip ci]"
git push
}
- name: Sync updates.xml to main - name: Sync updates.xml to main
if: github.ref_name != 'main' && steps.platform.outputs.platform == 'joomla' if: github.ref_name != 'main'
run: | run: |
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
GITEA_TOKEN="${{ secrets.MOKOGITEA_TOKEN }}" GA_TOKEN="${{ secrets.GA_TOKEN }}"
FILE_SHA=$(curl -sf -H "Authorization: token ${GITEA_TOKEN}" \ FILE_SHA=$(curl -sf -H "Authorization: token ${GA_TOKEN}" \
"${API_BASE}/contents/updates.xml?ref=main" | python3 -c "import sys,json; print(json.load(sys.stdin).get('sha',''))" 2>/dev/null || true) "${API_BASE}/contents/updates.xml?ref=main" | python3 -c "import sys,json; print(json.load(sys.stdin).get('sha',''))" 2>/dev/null || true)
if [ -n "$FILE_SHA" ] && [ -f "updates.xml" ]; then if [ -n "$FILE_SHA" ] && [ -f "updates.xml" ]; then
@@ -223,22 +394,27 @@ jobs:
payload = json.dumps({ payload = json.dumps({
'content': content, 'content': content,
'sha': '${FILE_SHA}', 'sha': '${FILE_SHA}',
'message': 'chore: sync updates.xml from ${{ steps.meta.outputs.stability }} [skip ci]', 'message': 'chore: sync updates.xml from ${STABILITY} [skip ci]',
'branch': 'main' 'branch': 'main'
}).encode() }).encode()
req = urllib.request.Request( req = urllib.request.Request(
'${API_BASE}/contents/updates.xml', '${API_BASE}/contents/updates.xml',
data=payload, method='PUT', data=payload, method='PUT',
headers={ headers={
'Authorization': 'token ${GITEA_TOKEN}', 'Authorization': 'token ${GA_TOKEN}',
'Content-Type': 'application/json' 'Content-Type': 'application/json'
}) })
try: try:
urllib.request.urlopen(req) urllib.request.urlopen(req)
print('updates.xml synced to main') print('updates.xml synced to main')
except Exception as e: except Exception as e:
print(f'WARNING: sync to main failed: {e}', file=sys.stderr) print(f'ERROR: failed to sync updates.xml to main: {e}', file=sys.stderr)
" sys.exit(1)
" \
&& echo "updates.xml synced to main (${STABILITY})" >> $GITHUB_STEP_SUMMARY \
|| echo "::error::failed to sync updates.xml to main" >> $GITHUB_STEP_SUMMARY
else
echo "::error::could not get updates.xml SHA from main — file may not exist on main yet" >> $GITHUB_STEP_SUMMARY
fi fi
- name: SFTP deploy to dev server - name: SFTP deploy to dev server
@@ -252,11 +428,12 @@ jobs:
DEV_KEY: ${{ secrets.DEV_FTP_KEY }} DEV_KEY: ${{ secrets.DEV_FTP_KEY }}
DEV_PASS: ${{ secrets.DEV_FTP_PASSWORD }} DEV_PASS: ${{ secrets.DEV_FTP_PASSWORD }}
run: | run: |
# Permission check: admin or maintain role required # -- Permission check: admin or maintain role required --------
ACTOR="${{ github.actor }}" ACTOR="${{ github.actor }}"
REPO="${{ github.repository }}"
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
PERMISSION=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \ PERMISSION=$(curl -sf -H "Authorization: token ${{ secrets.GA_TOKEN }}" \
"${API_BASE}/collaborators/${ACTOR}/permission" 2>/dev/null | \ "${API_BASE}/collaborators/${ACTOR}/permission" 2>/dev/null | \
python3 -c "import sys,json; print(json.load(sys.stdin).get('permission','read'))" 2>/dev/null || echo "read") python3 -c "import sys,json; print(json.load(sys.stdin).get('permission','read'))" 2>/dev/null || echo "read")
case "$PERMISSION" in case "$PERMISSION" in
@@ -286,24 +463,198 @@ jobs:
printf ',"password":"%s"}' "$DEV_PASS" >> /tmp/sftp-config.json printf ',"password":"%s"}' "$DEV_PASS" >> /tmp/sftp-config.json
fi fi
PLATFORM=$(php ${MOKO_CLI}/platform_detect.php --path . 2>/dev/null || true) PLATFORM=$(php /tmp/moko-platform/cli/platform_detect.php --path . 2>/dev/null || true)
if [ "$PLATFORM" = "waas-component" ] && [ -f "${MOKO_CLI}/../deploy/deploy-joomla.php" ]; then if [ "$PLATFORM" = "waas-component" ] && [ -f "/tmp/moko-platform/deploy/deploy-joomla.php" ]; then
php ${MOKO_CLI}/../deploy/deploy-joomla.php --path . --src-dir "$SOURCE_DIR" --config /tmp/sftp-config.json php /tmp/moko-platform/deploy/deploy-joomla.php --path . --src-dir "$SOURCE_DIR" --config /tmp/sftp-config.json
elif [ -f "${MOKO_CLI}/../deploy/deploy-sftp.php" ]; then elif [ -f "/tmp/moko-platform/deploy/deploy-sftp.php" ]; then
php ${MOKO_CLI}/../deploy/deploy-sftp.php --path . --src-dir "$SOURCE_DIR" --config /tmp/sftp-config.json php /tmp/moko-platform/deploy/deploy-sftp.php --path . --src-dir "$SOURCE_DIR" --config /tmp/sftp-config.json
fi fi
rm -f /tmp/deploy_key /tmp/sftp-config.json rm -f /tmp/deploy_key /tmp/sftp-config.json
echo "SFTP deploy to dev complete" >> $GITHUB_STEP_SUMMARY echo "SFTP deploy to dev complete" >> $GITHUB_STEP_SUMMARY
- name: Validate updates.xml integrity
run: |
ERRORS=0
if [ ! -f "updates.xml" ]; then
echo "::error::updates.xml not found"
exit 1
fi
# Well-formed XML
if ! python3 -c "import xml.etree.ElementTree as ET; ET.parse('updates.xml')" 2>/dev/null; then
echo "::error::updates.xml is not valid XML"
ERRORS=$((ERRORS+1))
fi
python3 << 'PYEOF'
import xml.etree.ElementTree as ET, sys, re, os
tree = ET.parse("updates.xml")
root = tree.getroot()
updates = root.findall("update")
errors = 0
warnings = 0
seen_tags = set()
# All 5 channels MUST be present
REQUIRED_CHANNELS = {"stable", "rc", "beta", "alpha", "dev"}
VALID_TAGS = REQUIRED_CHANNELS | {"development"} # accept legacy alias
REPO = os.environ.get("GITEA_REPO", "")
ORG = os.environ.get("GITEA_ORG", "MokoConsulting")
REPO_BASE = f"https://git.mokoconsulting.tech/{ORG}/"
# Gitea release tag names per channel (Moko standard)
RELEASE_TAG_MAP = {
"stable": "stable",
"rc": "release-candidate",
"beta": "beta",
"alpha": "alpha",
"dev": "development",
"development": "development",
}
# Joomla update XML required fields per
# https://docs.joomla.org/Deploying_an_Update_Server
REQUIRED_FIELDS = ["name", "element", "type", "version", "infourl"]
for i, u in enumerate(updates):
tag_el = u.find("tags/tag")
tag = tag_el.text.strip() if tag_el is not None and tag_el.text else None
label = f"Entry {i+1} (<tag>{tag or '?'}</tag>)"
# -- Required Joomla fields --
for field in REQUIRED_FIELDS:
el = u.find(field)
if el is None or not (el.text or "").strip():
print(f"::error::{label}: missing required <{field}>")
errors += 1
# -- <downloads><downloadurl> --
dl = u.find("downloads/downloadurl")
if dl is None or not (dl.text or "").strip():
print(f"::error::{label}: missing <downloads><downloadurl>")
errors += 1
else:
dl_url = dl.text.strip()
# Must point to org repo
if REPO_BASE not in dl_url:
print(f"::error::{label}: download URL not under {REPO_BASE}: {dl_url}")
errors += 1
# Must end in .zip
if not dl_url.endswith(".zip"):
print(f"::error::{label}: download URL must end in .zip: {dl_url}")
errors += 1
# Must use correct Gitea release tag in path
if tag and tag in RELEASE_TAG_MAP:
expected_tag = RELEASE_TAG_MAP[tag]
if f"/download/{expected_tag}/" not in dl_url:
print(f"::error::{label}: download URL should contain /download/{expected_tag}/ but got: {dl_url}")
errors += 1
# -- <client> (required for Joomla to match update) --
client = u.find("client")
if client is None or not (client.text or "").strip():
print(f"::error::{label}: missing <client> (required for Joomla update matching)")
errors += 1
# -- <targetplatform> --
tp = u.find("targetplatform")
if tp is None:
print(f"::error::{label}: missing <targetplatform>")
errors += 1
else:
tp_name = tp.get("name", "")
tp_ver = tp.get("version", "")
if tp_name != "joomla":
print(f"::error::{label}: targetplatform name should be 'joomla', got '{tp_name}'")
errors += 1
if not tp_ver:
print(f"::error::{label}: targetplatform missing version regex")
errors += 1
elif "5" not in tp_ver or "6" not in tp_ver:
print(f"::warning::{label}: targetplatform version may not cover Joomla 5+6: {tp_ver}")
warnings += 1
# -- <type> must be valid Joomla type --
type_el = u.find("type")
if type_el is not None and type_el.text:
valid_types = {"component", "module", "plugin", "template", "library", "package", "file"}
if type_el.text.strip() not in valid_types:
print(f"::error::{label}: invalid type '{type_el.text}' (expected: {valid_types})")
errors += 1
# -- <version> format (XX.YY.ZZ with optional suffix) --
ver_el = u.find("version")
if ver_el is not None and ver_el.text:
if not re.match(r"^\d{2}\.\d{2}\.\d{2}(-\w+)?$", ver_el.text.strip()):
print(f"::warning::{label}: version '{ver_el.text}' does not match XX.YY.ZZ format")
warnings += 1
# -- <maintainer> and <maintainerurl> --
for field in ["maintainer", "maintainerurl"]:
el = u.find(field)
if el is None or not (el.text or "").strip():
print(f"::warning::{label}: missing <{field}>")
warnings += 1
# -- Valid stability tag --
if tag is None:
print(f"::error::{label}: missing <tags><tag>")
errors += 1
elif tag not in VALID_TAGS:
print(f"::error::{label}: invalid tag '{tag}' (expected: {VALID_TAGS})")
errors += 1
# -- Duplicate tag check --
norm_tag = "dev" if tag == "development" else tag
if norm_tag in seen_tags:
print(f"::error::{label}: duplicate channel '{tag}'")
errors += 1
if norm_tag:
seen_tags.add(norm_tag)
# -- All 5 channels must exist --
missing = REQUIRED_CHANNELS - seen_tags
if missing:
print(f"::error::Missing required update channels: {', '.join(sorted(missing))}")
errors += 1
# -- Version ordering: higher stability must not exceed dev version --
channel_versions = {}
for u in updates:
tag_el = u.find("tags/tag")
ver_el = u.find("version")
if tag_el is not None and ver_el is not None and tag_el.text and ver_el.text:
norm = "dev" if tag_el.text.strip() == "development" else tag_el.text.strip()
# Strip suffix for comparison (01.00.18-dev -> 01.00.18)
base_ver = re.sub(r"-\w+$", "", ver_el.text.strip())
channel_versions[norm] = base_ver
# Cascade check: dev >= alpha >= beta >= rc >= stable
ORDER = ["dev", "alpha", "beta", "rc", "stable"]
for j in range(1, len(ORDER)):
current = ORDER[j]
previous = ORDER[j - 1]
if current in channel_versions and previous in channel_versions:
if channel_versions[current] > channel_versions[previous]:
print(f"::error::{current} version ({channel_versions[current]}) is ahead of {previous} ({channel_versions[previous]})")
errors += 1
# -- Summary --
print(f"\nupdates.xml validation: {len(updates)} entries, {errors} error(s), {warnings} warning(s)")
if errors > 0:
sys.exit(1)
PYEOF
- name: Summary - name: Summary
if: always() if: always()
run: | run: |
VERSION="${{ steps.meta.outputs.version }}" echo "## Joomla Update Server" >> $GITHUB_STEP_SUMMARY
STABILITY="${{ steps.meta.outputs.stability }}"
DISPLAY="${{ steps.meta.outputs.display_version }}"
echo "## Update Server" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY
echo "| Field | Value |" >> $GITHUB_STEP_SUMMARY echo "| Field | Value |" >> $GITHUB_STEP_SUMMARY
echo "|-------|-------|" >> $GITHUB_STEP_SUMMARY echo "|-------|-------|" >> $GITHUB_STEP_SUMMARY
echo "| Stability | \`${STABILITY}\` |" >> $GITHUB_STEP_SUMMARY echo "| Stability | \`${STABILITY}\` |" >> $GITHUB_STEP_SUMMARY
echo "| Version | \`${DISPLAY}\` |" >> $GITHUB_STEP_SUMMARY echo "| Version | \`${DISPLAY_VERSION}\` |" >> $GITHUB_STEP_SUMMARY
echo "| Element | \`${EXT_ELEMENT}\` |" >> $GITHUB_STEP_SUMMARY
echo "| Download | [ZIP](${DOWNLOAD_URL}) |" >> $GITHUB_STEP_SUMMARY
+1 -1
View File
@@ -23,7 +23,7 @@ jobs:
steps: steps:
- name: Sync upstream bugs - name: Sync upstream bugs
env: env:
GH_TOKEN: ${{ secrets.GH_MIRROR_TOKEN }} GH_TOKEN: ${{ secrets.GH_TOKEN }}
MOKOGITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} MOKOGITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
MOKOGITEA_URL: https://git.mokoconsulting.tech MOKOGITEA_URL: https://git.mokoconsulting.tech
MOKOGITEA_REPO: MokoConsulting/MokoGitea MOKOGITEA_REPO: MokoConsulting/MokoGitea
-5
View File
@@ -36,17 +36,14 @@ const (
appSubUrlVar = "{{.SwaggerAppSubUrl}}" appSubUrlVar = "{{.SwaggerAppSubUrl}}"
appVerVar = "{{.SwaggerAppVer}}" appVerVar = "{{.SwaggerAppVer}}"
appNameVar = "{{.SwaggerAppName}}"
appSubUrlPlaceholder = "GITEA_APP_SUB_URL_PLACEHOLDER" appSubUrlPlaceholder = "GITEA_APP_SUB_URL_PLACEHOLDER"
appVerPlaceholder = "0.0.0-gitea-placeholder" appVerPlaceholder = "0.0.0-gitea-placeholder"
appNamePlaceholder = "GiteaAppNamePlaceholder"
) )
var ( var (
appSubUrlRe = regexp.MustCompile(regexp.QuoteMeta(appSubUrlVar)) appSubUrlRe = regexp.MustCompile(regexp.QuoteMeta(appSubUrlVar))
appVerRe = regexp.MustCompile(regexp.QuoteMeta(appVerVar)) appVerRe = regexp.MustCompile(regexp.QuoteMeta(appVerVar))
appNameRe = regexp.MustCompile(regexp.QuoteMeta(appNameVar))
enumScanDirs = []string{ enumScanDirs = []string{
"modules/structs", "modules/structs",
@@ -73,7 +70,6 @@ func main() {
cleaned := appSubUrlRe.ReplaceAll(data, []byte(appSubUrlPlaceholder)) cleaned := appSubUrlRe.ReplaceAll(data, []byte(appSubUrlPlaceholder))
cleaned = appVerRe.ReplaceAll(cleaned, []byte(appVerPlaceholder)) cleaned = appVerRe.ReplaceAll(cleaned, []byte(appVerPlaceholder))
cleaned = appNameRe.ReplaceAll(cleaned, []byte(appNamePlaceholder))
oas3, err := openapi3gen.Convert(cleaned, astEnumMap) oas3, err := openapi3gen.Convert(cleaned, astEnumMap)
if err != nil { if err != nil {
@@ -91,7 +87,6 @@ func main() {
result := strings.ReplaceAll(string(out), appSubUrlPlaceholder, appSubUrlVar) result := strings.ReplaceAll(string(out), appSubUrlPlaceholder, appSubUrlVar)
result = strings.ReplaceAll(result, appVerPlaceholder, appVerVar) result = strings.ReplaceAll(result, appVerPlaceholder, appVerVar)
result = strings.ReplaceAll(result, appNamePlaceholder, appNameVar)
result = strings.TrimSpace(result) result = strings.TrimSpace(result)
if err := os.WriteFile(openapi3OutPath, []byte(result), 0o644); err != nil { if err := os.WriteFile(openapi3OutPath, []byte(result), 0o644); err != nil {
-17
View File
@@ -8,8 +8,6 @@ import (
"strings" "strings"
"testing" "testing"
"git.mokoconsulting.tech/MokoConsulting/MokoGitea/modules/setting"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@@ -68,21 +66,6 @@ func TestLocaleStore(t *testing.T) {
assert.Equal(t, "&lt;no-such&gt;", string(res)) assert.Equal(t, "&lt;no-such&gt;", string(res))
} }
func TestLocaleAppNameSubstitution(t *testing.T) {
setting.AppName = "TestApp"
ls := NewLocaleStore()
assert.NoError(t, ls.AddLocaleByJSON("lang1", "Lang1", []byte(`{"greeting":"Welcome to ${APP_NAME}","plain":"No placeholder here"}`), nil))
lang1, _ := ls.Locale("lang1")
assert.Equal(t, "Welcome to TestApp", lang1.TrString("greeting"))
assert.Equal(t, "No placeholder here", lang1.TrString("plain"))
// Verify it responds to runtime AppName changes
setting.AppName = "ChangedApp"
assert.Equal(t, "Welcome to ChangedApp", lang1.TrString("greeting"))
}
func TestLocaleStoreMoreSource(t *testing.T) { func TestLocaleStoreMoreSource(t *testing.T) {
testData1 := []byte(` testData1 := []byte(`
{ {
-5
View File
@@ -9,11 +9,9 @@ import (
"html" "html"
"html/template" "html/template"
"slices" "slices"
"strings"
"git.mokoconsulting.tech/MokoConsulting/MokoGitea/modules/json" "git.mokoconsulting.tech/MokoConsulting/MokoGitea/modules/json"
"git.mokoconsulting.tech/MokoConsulting/MokoGitea/modules/log" "git.mokoconsulting.tech/MokoConsulting/MokoGitea/modules/log"
"git.mokoconsulting.tech/MokoConsulting/MokoGitea/modules/setting"
) )
// This file implements the static LocaleStore that will not watch for changes // This file implements the static LocaleStore that will not watch for changes
@@ -144,9 +142,6 @@ func (l *locale) TrString(trKey string, trArgs ...any) string {
if format == "" { // still missing, use the key itself if format == "" { // still missing, use the key itself
format = html.EscapeString(trKey) format = html.EscapeString(trKey)
} }
if strings.Contains(format, "${APP_NAME}") {
format = strings.ReplaceAll(format, "${APP_NAME}", setting.AppName)
}
msg, err := Format(format, trArgs...) msg, err := Format(format, trArgs...)
if err != nil { if err != nil {
log.Error("Error whilst formatting %q in %s: %v", trKey, l.langName, err) log.Error("Error whilst formatting %q in %s: %v", trKey, l.langName, err)
+52 -52
View File
@@ -25,7 +25,7 @@
"enable_javascript": "This website requires JavaScript.", "enable_javascript": "This website requires JavaScript.",
"toc": "Table of Contents", "toc": "Table of Contents",
"licenses": "Licenses", "licenses": "Licenses",
"return_to_gitea": "Return to ${APP_NAME}", "return_to_gitea": "Return to MokoGitea",
"more_items": "More items", "more_items": "More items",
"username": "Username", "username": "Username",
"email": "Email Address", "email": "Email Address",
@@ -222,7 +222,7 @@
"filter.string.asc": "AZ", "filter.string.asc": "AZ",
"filter.string.desc": "ZA", "filter.string.desc": "ZA",
"error.occurred": "An error occurred", "error.occurred": "An error occurred",
"error.report_message": "If you believe that this is a ${APP_NAME} bug, please search for issues on <a href=\"%s\" target=\"_blank\">GitHub</a> or open a new issue if necessary.", "error.report_message": "If you believe that this is a MokoGitea bug, please search for issues on <a href=\"%s\" target=\"_blank\">GitHub</a> or open a new issue if necessary.",
"error.not_found": "The target couldn't be found.", "error.not_found": "The target couldn't be found.",
"error.permission_denied": "Permission denied.", "error.permission_denied": "Permission denied.",
"error.network_error": "Network error", "error.network_error": "Network error",
@@ -230,16 +230,16 @@
"startpage.install": "Easy to install", "startpage.install": "Easy to install",
"startpage.install_desc": "Simply <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%[1]s\">run the binary</a> for your platform, ship it with <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%[2]s\">Docker</a>, or get it <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%[3]s\">packaged</a>.", "startpage.install_desc": "Simply <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%[1]s\">run the binary</a> for your platform, ship it with <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%[2]s\">Docker</a>, or get it <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%[3]s\">packaged</a>.",
"startpage.platform": "Cross-platform", "startpage.platform": "Cross-platform",
"startpage.platform_desc": "${APP_NAME} runs anywhere <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%s\">Go</a> can compile for: Windows, macOS, Linux, ARM, etc. Choose the one you love!", "startpage.platform_desc": "MokoGitea runs anywhere <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%s\">Go</a> can compile for: Windows, macOS, Linux, ARM, etc. Choose the one you love!",
"startpage.lightweight": "Lightweight", "startpage.lightweight": "Lightweight",
"startpage.lightweight_desc": "${APP_NAME} has low minimal requirements and can run on an inexpensive Raspberry Pi. Save your machine energy!", "startpage.lightweight_desc": "MokoGitea has low minimal requirements and can run on an inexpensive Raspberry Pi. Save your machine energy!",
"startpage.license": "Open Source", "startpage.license": "Open Source",
"startpage.license_desc": "Go get <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%[1]s\">%[2]s</a>! Join us by <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%[3]s\">contributing</a> to make this project even better. Don't hesitate to contribute!", "startpage.license_desc": "Go get <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%[1]s\">%[2]s</a>! Join us by <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%[3]s\">contributing</a> to make this project even better. Don't hesitate to contribute!",
"install.install": "Installation", "install.install": "Installation",
"install.installing_desc": "Installing now, please wait…", "install.installing_desc": "Installing now, please wait…",
"install.title": "Initial Configuration", "install.title": "Initial Configuration",
"install.docker_helper": "If you run ${APP_NAME} inside Docker, please read the <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%s\">documentation</a> before changing any settings.", "install.docker_helper": "If you run MokoGitea inside Docker, please read the <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%s\">documentation</a> before changing any settings.",
"install.require_db_desc": "${APP_NAME} requires MySQL, PostgreSQL, MSSQL, SQLite3 or TiDB (MySQL protocol).", "install.require_db_desc": "MokoGitea requires MySQL, PostgreSQL, MSSQL, SQLite3 or TiDB (MySQL protocol).",
"install.db_title": "Database Settings", "install.db_title": "Database Settings",
"install.db_type": "Database Type", "install.db_type": "Database Type",
"install.host": "Host", "install.host": "Host",
@@ -250,12 +250,12 @@
"install.db_schema_helper": "Leave blank for database default (\"public\").", "install.db_schema_helper": "Leave blank for database default (\"public\").",
"install.ssl_mode": "SSL", "install.ssl_mode": "SSL",
"install.path": "Path", "install.path": "Path",
"install.sqlite_helper": "File path for the SQLite3 database.<br>Enter an absolute path if you run ${APP_NAME} as a service.", "install.sqlite_helper": "File path for the SQLite3 database.<br>Enter an absolute path if you run MokoGitea as a service.",
"install.reinstall_error": "You are trying to install into an existing ${APP_NAME} database", "install.reinstall_error": "You are trying to install into an existing MokoGitea database",
"install.reinstall_confirm_message": "Re-installing with an existing ${APP_NAME} database can cause multiple problems. In most cases, you should use your existing \"app.ini\" to run ${APP_NAME}. If you know what you are doing, confirm the following:", "install.reinstall_confirm_message": "Re-installing with an existing MokoGitea database can cause multiple problems. In most cases, you should use your existing \"app.ini\" to run MokoGitea. If you know what you are doing, confirm the following:",
"install.reinstall_confirm_check_1": "The data encrypted by the SECRET_KEY in app.ini may be lost: users may not be able to log in with 2FA/OTP and mirrors may not function correctly. By checking this box, you confirm that the current app.ini file contains the correct SECRET_KEY.", "install.reinstall_confirm_check_1": "The data encrypted by the SECRET_KEY in app.ini may be lost: users may not be able to log in with 2FA/OTP and mirrors may not function correctly. By checking this box, you confirm that the current app.ini file contains the correct SECRET_KEY.",
"install.reinstall_confirm_check_2": "The repositories and settings may need to be resynchronized. By checking this box, you confirm that you will resynchronize the hooks for the repositories and authorized_keys file manually. You confirm that you will ensure that repository and mirror settings are correct.", "install.reinstall_confirm_check_2": "The repositories and settings may need to be resynchronized. By checking this box, you confirm that you will resynchronize the hooks for the repositories and authorized_keys file manually. You confirm that you will ensure that repository and mirror settings are correct.",
"install.reinstall_confirm_check_3": "You confirm that you are absolutely sure that this ${APP_NAME} is running with the correct app.ini location and that you are sure that you have to re-install. You confirm that you acknowledge the above risks.", "install.reinstall_confirm_check_3": "You confirm that you are absolutely sure that this MokoGitea is running with the correct app.ini location and that you are sure that you have to re-install. You confirm that you acknowledge the above risks.",
"install.err_empty_db_path": "The SQLite3 database path cannot be empty.", "install.err_empty_db_path": "The SQLite3 database path cannot be empty.",
"install.no_admin_and_disable_registration": "You cannot disable user self-registration without creating an administrator account.", "install.no_admin_and_disable_registration": "You cannot disable user self-registration without creating an administrator account.",
"install.err_empty_admin_password": "The administrator password cannot be empty.", "install.err_empty_admin_password": "The administrator password cannot be empty.",
@@ -271,14 +271,14 @@
"install.lfs_path": "Git LFS Root Path", "install.lfs_path": "Git LFS Root Path",
"install.lfs_path_helper": "Files tracked by Git LFS will be stored in this directory. Leave empty to disable.", "install.lfs_path_helper": "Files tracked by Git LFS will be stored in this directory. Leave empty to disable.",
"install.run_user": "Run As Username", "install.run_user": "Run As Username",
"install.run_user_helper": "The operating system username that ${APP_NAME} runs as, it must have write access to the data paths. This value is auto-detected and cannot be changed here. To use a different user, restart ${APP_NAME} under that account.", "install.run_user_helper": "The operating system username that MokoGitea runs as, it must have write access to the data paths. This value is auto-detected and cannot be changed here. To use a different user, restart MokoGitea under that account.",
"install.domain": "Server Domain", "install.domain": "Server Domain",
"install.domain_helper": "Domain or host address for the server.", "install.domain_helper": "Domain or host address for the server.",
"install.ssh_port": "SSH Server Port", "install.ssh_port": "SSH Server Port",
"install.ssh_port_helper": "Port number your SSH server listens on. Leave empty to disable.", "install.ssh_port_helper": "Port number your SSH server listens on. Leave empty to disable.",
"install.http_port": "${APP_NAME} HTTP Listen Port", "install.http_port": "MokoGitea HTTP Listen Port",
"install.http_port_helper": "Port number the ${APP_NAME} web server will listen on.", "install.http_port_helper": "Port number the MokoGitea web server will listen on.",
"install.app_url": "${APP_NAME} Base URL", "install.app_url": "MokoGitea Base URL",
"install.app_url_helper": "Base address for HTTP(S) clone URLs and email notifications.", "install.app_url_helper": "Base address for HTTP(S) clone URLs and email notifications.",
"install.log_root_path": "Log Path", "install.log_root_path": "Log Path",
"install.log_root_path_helper": "Log files will be written to this directory.", "install.log_root_path_helper": "Log files will be written to this directory.",
@@ -288,7 +288,7 @@
"install.smtp_port": "SMTP Port", "install.smtp_port": "SMTP Port",
"install.smtp_from": "Send Email As", "install.smtp_from": "Send Email As",
"install.smtp_from_invalid": "The \"Send Email As\" address is invalid", "install.smtp_from_invalid": "The \"Send Email As\" address is invalid",
"install.smtp_from_helper": "Email address ${APP_NAME} will use. Enter a plain email address or use the \"Name\" <email@example.com> format.", "install.smtp_from_helper": "Email address MokoGitea will use. Enter a plain email address or use the \"Name\" <email@example.com> format.",
"install.mailer_user": "SMTP Username", "install.mailer_user": "SMTP Username",
"install.mailer_password": "SMTP Password", "install.mailer_password": "SMTP Password",
"install.register_confirm": "Require Email Confirmation to Register", "install.register_confirm": "Require Email Confirmation to Register",
@@ -311,7 +311,7 @@
"install.admin_password": "Password", "install.admin_password": "Password",
"install.confirm_password": "Confirm Password", "install.confirm_password": "Confirm Password",
"install.admin_email": "Email Address", "install.admin_email": "Email Address",
"install.install_btn_confirm": "Install ${APP_NAME}", "install.install_btn_confirm": "Install MokoGitea",
"install.test_git_failed": "Could not test 'git' command: %v", "install.test_git_failed": "Could not test 'git' command: %v",
"install.invalid_db_setting": "The database settings are invalid: %v", "install.invalid_db_setting": "The database settings are invalid: %v",
"install.invalid_db_table": "The database table \"%s\" is invalid: %v", "install.invalid_db_table": "The database table \"%s\" is invalid: %v",
@@ -385,7 +385,7 @@
"auth.forgot_password_title": "Forgot Password", "auth.forgot_password_title": "Forgot Password",
"auth.forgot_password": "Forgot password?", "auth.forgot_password": "Forgot password?",
"auth.need_account": "Need an account?", "auth.need_account": "Need an account?",
"auth.sign_up_tip": "You are registering the first account in the system, which has administrator privileges. Please carefully remember your username and password. If you forget the username or password, please refer to the ${APP_NAME} documentation to recover the account.", "auth.sign_up_tip": "You are registering the first account in the system, which has administrator privileges. Please carefully remember your username and password. If you forget the username or password, please refer to the MokoGitea documentation to recover the account.",
"auth.sign_up_now": "Register now.", "auth.sign_up_now": "Register now.",
"auth.sign_up_successful": "Account was successfully created. Welcome!", "auth.sign_up_successful": "Account was successfully created. Welcome!",
"auth.confirmation_mail_sent_prompt_ex": "A new confirmation email has been sent to <b>%s</b>. Please check your inbox within the next %s to complete the registration process. If your registration email address is incorrect, you can sign in again and change it.", "auth.confirmation_mail_sent_prompt_ex": "A new confirmation email has been sent to <b>%s</b>. Please check your inbox within the next %s to complete the registration process. If your registration email address is incorrect, you can sign in again and change it.",
@@ -409,7 +409,7 @@
"auth.reset_password_helper": "Recover Account", "auth.reset_password_helper": "Recover Account",
"auth.reset_password_wrong_user": "You are signed in as %s, but the account recovery link is meant for %s", "auth.reset_password_wrong_user": "You are signed in as %s, but the account recovery link is meant for %s",
"auth.password_too_short": "Password length cannot be less than %d characters.", "auth.password_too_short": "Password length cannot be less than %d characters.",
"auth.non_local_account": "Non-local users cannot update their password through the ${APP_NAME} web interface.", "auth.non_local_account": "Non-local users cannot update their password through the MokoGitea web interface.",
"auth.verify": "Verify", "auth.verify": "Verify",
"auth.scratch_code": "Scratch code", "auth.scratch_code": "Scratch code",
"auth.use_scratch_code": "Use a scratch code", "auth.use_scratch_code": "Use a scratch code",
@@ -726,7 +726,7 @@
"settings.retype_new_password": "Confirm New Password", "settings.retype_new_password": "Confirm New Password",
"settings.password_incorrect": "The current password is incorrect.", "settings.password_incorrect": "The current password is incorrect.",
"settings.change_password_success": "Your password has been updated. Sign in using your new password from now on.", "settings.change_password_success": "Your password has been updated. Sign in using your new password from now on.",
"settings.password_change_disabled": "Non-local users cannot update their password through the ${APP_NAME} web interface.", "settings.password_change_disabled": "Non-local users cannot update their password through the MokoGitea web interface.",
"settings.emails": "Email Addresses", "settings.emails": "Email Addresses",
"settings.manage_emails": "Manage Email Addresses", "settings.manage_emails": "Manage Email Addresses",
"settings.manage_themes": "Select default theme", "settings.manage_themes": "Select default theme",
@@ -734,7 +734,7 @@
"settings.email_desc": "Your primary email address will be used for notifications, password recovery and, provided that it is not hidden, web-based Git operations.", "settings.email_desc": "Your primary email address will be used for notifications, password recovery and, provided that it is not hidden, web-based Git operations.",
"settings.theme_desc": "This will be your default theme across the site.", "settings.theme_desc": "This will be your default theme across the site.",
"settings.theme_colorblindness_help": "Color blindness Theme Support", "settings.theme_colorblindness_help": "Color blindness Theme Support",
"settings.theme_colorblindness_prompt": "${APP_NAME} only has a few themes with basic color blindness support, which only have a few colors defined. The work is still in progress. More improvements could be made by defining more colors in the theme CSS files.", "settings.theme_colorblindness_prompt": "MokoGitea only has a few themes with basic color blindness support, which only have a few colors defined. The work is still in progress. More improvements could be made by defining more colors in the theme CSS files.",
"settings.primary": "Primary", "settings.primary": "Primary",
"settings.activated": "Activated", "settings.activated": "Activated",
"settings.requires_activation": "Requires activation", "settings.requires_activation": "Requires activation",
@@ -843,7 +843,7 @@
"settings.unbind_success": "The social account has been removed successfully.", "settings.unbind_success": "The social account has been removed successfully.",
"settings.manage_access_token": "Manage Access Tokens", "settings.manage_access_token": "Manage Access Tokens",
"settings.generate_new_token": "Generate New Token", "settings.generate_new_token": "Generate New Token",
"settings.tokens_desc": "These tokens grant access to your account using the ${APP_NAME} API.", "settings.tokens_desc": "These tokens grant access to your account using the Gitea API.",
"settings.token_name": "Token Name", "settings.token_name": "Token Name",
"settings.generate_token": "Generate Token", "settings.generate_token": "Generate Token",
"settings.generate_token_success": "Your new token has been generated. Copy it now as it will not be shown again.", "settings.generate_token_success": "Your new token has been generated. Copy it now as it will not be shown again.",
@@ -869,7 +869,7 @@
"settings.permissions_list": "Permissions:", "settings.permissions_list": "Permissions:",
"settings.manage_oauth2_applications": "Manage OAuth2 Applications", "settings.manage_oauth2_applications": "Manage OAuth2 Applications",
"settings.edit_oauth2_application": "Edit OAuth2 Application", "settings.edit_oauth2_application": "Edit OAuth2 Application",
"settings.oauth2_applications_desc": "OAuth2 applications enable your third-party application to securely authenticate users at this ${APP_NAME} instance.", "settings.oauth2_applications_desc": "OAuth2 applications enable your third-party application to securely authenticate users at this MokoGitea instance.",
"settings.remove_oauth2_application": "Remove OAuth2 Application", "settings.remove_oauth2_application": "Remove OAuth2 Application",
"settings.remove_oauth2_application_desc": "Removing an OAuth2 application will revoke access to all signed access tokens. Continue?", "settings.remove_oauth2_application_desc": "Removing an OAuth2 application will revoke access to all signed access tokens. Continue?",
"settings.remove_oauth2_application_success": "The application has been deleted.", "settings.remove_oauth2_application_success": "The application has been deleted.",
@@ -890,9 +890,9 @@
"settings.oauth2_application_edit": "Edit", "settings.oauth2_application_edit": "Edit",
"settings.oauth2_application_create_description": "OAuth2 applications give your third-party application access to user accounts on this instance.", "settings.oauth2_application_create_description": "OAuth2 applications give your third-party application access to user accounts on this instance.",
"settings.oauth2_application_remove_description": "Removing an OAuth2 application will prevent it from accessing authorized user accounts on this instance. Continue?", "settings.oauth2_application_remove_description": "Removing an OAuth2 application will prevent it from accessing authorized user accounts on this instance. Continue?",
"settings.oauth2_application_locked": "${APP_NAME} pre-registers some OAuth2 applications on startup if enabled in config. To prevent unexpected behavior, these can neither be edited nor removed. Please refer to the OAuth2 documentation for more information.", "settings.oauth2_application_locked": "MokoGitea pre-registers some OAuth2 applications on startup if enabled in config. To prevent unexpected behavior, these can neither be edited nor removed. Please refer to the OAuth2 documentation for more information.",
"settings.authorized_oauth2_applications": "Authorized OAuth2 Applications", "settings.authorized_oauth2_applications": "Authorized OAuth2 Applications",
"settings.authorized_oauth2_applications_description": "You have granted access to your personal ${APP_NAME} account to these third-party applications. Please revoke access for applications you no longer need.", "settings.authorized_oauth2_applications_description": "You have granted access to your personal MokoGitea account to these third-party applications. Please revoke access for applications you no longer need.",
"settings.revoke_key": "Revoke", "settings.revoke_key": "Revoke",
"settings.revoke_oauth2_grant": "Revoke Access", "settings.revoke_oauth2_grant": "Revoke Access",
"settings.revoke_oauth2_grant_description": "Revoking access for this third-party application will prevent this application from accessing your data. Are you sure?", "settings.revoke_oauth2_grant_description": "Revoking access for this third-party application will prevent this application from accessing your data. Are you sure?",
@@ -923,11 +923,11 @@
"settings.webauthn_key_loss_warning": "If you lose your security keys, you will lose access to your account.", "settings.webauthn_key_loss_warning": "If you lose your security keys, you will lose access to your account.",
"settings.webauthn_alternative_tip": "You may want to configure an additional authentication method.", "settings.webauthn_alternative_tip": "You may want to configure an additional authentication method.",
"settings.manage_account_links": "Manage Linked Accounts", "settings.manage_account_links": "Manage Linked Accounts",
"settings.manage_account_links_desc": "These external accounts are linked to your ${APP_NAME} account.", "settings.manage_account_links_desc": "These external accounts are linked to your MokoGitea account.",
"settings.account_links_not_available": "No external accounts are currently linked to your ${APP_NAME} account.", "settings.account_links_not_available": "No external accounts are currently linked to your MokoGitea account.",
"settings.link_account": "Link Account", "settings.link_account": "Link Account",
"settings.remove_account_link": "Remove Linked Account", "settings.remove_account_link": "Remove Linked Account",
"settings.remove_account_link_desc": "Removing a linked account will revoke its access to your ${APP_NAME} account. Continue?", "settings.remove_account_link_desc": "Removing a linked account will revoke its access to your MokoGitea account. Continue?",
"settings.remove_account_link_success": "The linked account has been removed.", "settings.remove_account_link_success": "The linked account has been removed.",
"settings.hooks.desc": "Add webhooks which will be triggered for <strong>all repositories</strong> that you own.", "settings.hooks.desc": "Add webhooks which will be triggered for <strong>all repositories</strong> that you own.",
"settings.orgs_none": "You are not a member of any organizations.", "settings.orgs_none": "You are not a member of any organizations.",
@@ -943,7 +943,7 @@
"settings.email_notifications.disable": "Disable Email Notifications", "settings.email_notifications.disable": "Disable Email Notifications",
"settings.email_notifications.submit": "Set Email Preference", "settings.email_notifications.submit": "Set Email Preference",
"settings.email_notifications.andyourown": "And Your Own Notifications", "settings.email_notifications.andyourown": "And Your Own Notifications",
"settings.email_notifications.actions.desc": "Notifications for workflow runs on repositories set up with <a target=\"_blank\" href=\"%s\">${APP_NAME} Actions</a>.", "settings.email_notifications.actions.desc": "Notifications for workflow runs on repositories set up with <a target=\"_blank\" href=\"%s\">Gitea Actions</a>.",
"settings.email_notifications.actions.failure_only": "Only notify for failed workflow runs", "settings.email_notifications.actions.failure_only": "Only notify for failed workflow runs",
"settings.visibility": "User visibility", "settings.visibility": "User visibility",
"settings.visibility.public": "Public", "settings.visibility.public": "Public",
@@ -1125,7 +1125,7 @@
"repo.migrate.github.description": "Migrate data from github.com or other GitHub instances.", "repo.migrate.github.description": "Migrate data from github.com or other GitHub instances.",
"repo.migrate.git.description": "Migrate a repository only from any Git service.", "repo.migrate.git.description": "Migrate a repository only from any Git service.",
"repo.migrate.gitlab.description": "Migrate data from gitlab.com or other GitLab instances.", "repo.migrate.gitlab.description": "Migrate data from gitlab.com or other GitLab instances.",
"repo.migrate.gitea.description": "Migrate data from other ${APP_NAME} instances.", "repo.migrate.gitea.description": "Migrate data from gitea.com or other Gitea instances.",
"repo.migrate.gogs.description": "Migrate data from notabug.org or other Gogs instances.", "repo.migrate.gogs.description": "Migrate data from notabug.org or other Gogs instances.",
"repo.migrate.onedev.description": "Migrate data from code.onedev.io or other OneDev instances.", "repo.migrate.onedev.description": "Migrate data from code.onedev.io or other OneDev instances.",
"repo.migrate.codebase.description": "Migrate data from codebasehq.com.", "repo.migrate.codebase.description": "Migrate data from codebasehq.com.",
@@ -1891,7 +1891,7 @@
"repo.pulls.cmd_instruction_checkout_title": "Checkout", "repo.pulls.cmd_instruction_checkout_title": "Checkout",
"repo.pulls.cmd_instruction_checkout_desc": "From your project repository, check out a new branch and test the changes.", "repo.pulls.cmd_instruction_checkout_desc": "From your project repository, check out a new branch and test the changes.",
"repo.pulls.cmd_instruction_merge_title": "Merge", "repo.pulls.cmd_instruction_merge_title": "Merge",
"repo.pulls.cmd_instruction_merge_desc": "Merge the changes and update on ${APP_NAME}.", "repo.pulls.cmd_instruction_merge_desc": "Merge the changes and update on MokoGitea.",
"repo.pulls.cmd_instruction_merge_warning": "Warning: This operation cannot merge pull request because \"autodetect manual merge\" is not enabled.", "repo.pulls.cmd_instruction_merge_warning": "Warning: This operation cannot merge pull request because \"autodetect manual merge\" is not enabled.",
"repo.pulls.clear_merge_message": "Clear merge message", "repo.pulls.clear_merge_message": "Clear merge message",
"repo.pulls.clear_merge_message_hint": "Clearing the merge message will only remove the commit message content and keep generated git trailers such as \"Co-Authored-By…\".", "repo.pulls.clear_merge_message_hint": "Clearing the merge message will only remove the commit message content and keep generated git trailers such as \"Co-Authored-By…\".",
@@ -2199,11 +2199,11 @@
"repo.settings.trust_model.collaborator.long": "Collaborator: Trust signatures by collaborators", "repo.settings.trust_model.collaborator.long": "Collaborator: Trust signatures by collaborators",
"repo.settings.trust_model.collaborator.desc": "Valid signatures by collaborators of this repository will be marked \"trusted\", whether they match the committer or not. Otherwise, valid signatures will be marked \"untrusted\" if the signature matches the committer and \"unmatched\" if not.", "repo.settings.trust_model.collaborator.desc": "Valid signatures by collaborators of this repository will be marked \"trusted\", whether they match the committer or not. Otherwise, valid signatures will be marked \"untrusted\" if the signature matches the committer and \"unmatched\" if not.",
"repo.settings.trust_model.committer": "Committer", "repo.settings.trust_model.committer": "Committer",
"repo.settings.trust_model.committer.long": "Committer: Trust signatures that match committers. This matches GitHub's behavior and will force commits signed by ${APP_NAME} to have ${APP_NAME} as the committer.", "repo.settings.trust_model.committer.long": "Committer: Trust signatures that match committers. This matches GitHub's behavior and will force commits signed by MokoGitea to have MokoGitea as the committer.",
"repo.settings.trust_model.committer.desc": "Valid signatures will only be marked \"trusted\" if they match the committer, otherwise they will be marked \"unmatched\". This forces ${APP_NAME} to be the committer on signed commits, with the actual committer marked as Co-authored-by: and Co-committed-by: trailer in the commit. The default ${APP_NAME} key must match a user in the database.", "repo.settings.trust_model.committer.desc": "Valid signatures will only be marked \"trusted\" if they match the committer, otherwise they will be marked \"unmatched\". This forces MokoGitea to be the committer on signed commits, with the actual committer marked as Co-authored-by: and Co-committed-by: trailer in the commit. The default MokoGitea key must match a user in the database.",
"repo.settings.trust_model.collaboratorcommitter": "Collaborator+Committer", "repo.settings.trust_model.collaboratorcommitter": "Collaborator+Committer",
"repo.settings.trust_model.collaboratorcommitter.long": "Collaborator+Committer: Trust signatures by collaborators which match the committer", "repo.settings.trust_model.collaboratorcommitter.long": "Collaborator+Committer: Trust signatures by collaborators which match the committer",
"repo.settings.trust_model.collaboratorcommitter.desc": "Valid signatures by collaborators of this repository will be marked \"trusted\" if they match the committer. Otherwise, valid signatures will be marked \"untrusted\" if the signature matches the committer and \"unmatched\" otherwise. This will force ${APP_NAME} to be marked as the committer on signed commits, with the actual committer marked as Co-Authored-By: and Co-Committed-By: trailer in the commit. The default ${APP_NAME} key must match a user in the database.", "repo.settings.trust_model.collaboratorcommitter.desc": "Valid signatures by collaborators of this repository will be marked \"trusted\" if they match the committer. Otherwise, valid signatures will be marked \"untrusted\" if the signature matches the committer and \"unmatched\" otherwise. This will force MokoGitea to be marked as the committer on signed commits, with the actual committer marked as Co-Authored-By: and Co-Committed-By: trailer in the commit. The default MokoGitea key must match a user in the database.",
"repo.settings.wiki_delete": "Delete Wiki Data", "repo.settings.wiki_delete": "Delete Wiki Data",
"repo.settings.wiki_delete_desc": "Deleting repository wiki data is permanent and cannot be undone.", "repo.settings.wiki_delete_desc": "Deleting repository wiki data is permanent and cannot be undone.",
"repo.settings.wiki_delete_notices_1": "- This will permanently delete and disable the repository wiki for %s.", "repo.settings.wiki_delete_notices_1": "- This will permanently delete and disable the repository wiki for %s.",
@@ -2240,7 +2240,7 @@
"repo.settings.remove_team_success": "The team's access to the repository has been removed.", "repo.settings.remove_team_success": "The team's access to the repository has been removed.",
"repo.settings.add_webhook": "Add Webhook", "repo.settings.add_webhook": "Add Webhook",
"repo.settings.add_webhook.invalid_channel_name": "Webhook channel name cannot be empty and cannot contain only a # character.", "repo.settings.add_webhook.invalid_channel_name": "Webhook channel name cannot be empty and cannot contain only a # character.",
"repo.settings.hooks_desc": "Webhooks automatically make HTTP POST requests to a server when certain ${APP_NAME} events trigger. Read more in the <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%s\">webhooks guide</a>.", "repo.settings.hooks_desc": "Webhooks automatically make HTTP POST requests to a server when certain MokoGitea events trigger. Read more in the <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%s\">webhooks guide</a>.",
"repo.settings.webhook_deletion": "Remove Webhook", "repo.settings.webhook_deletion": "Remove Webhook",
"repo.settings.webhook_deletion_desc": "Removing a webhook deletes its settings and delivery history. Continue?", "repo.settings.webhook_deletion_desc": "Removing a webhook deletes its settings and delivery history. Continue?",
"repo.settings.webhook_deletion_success": "The webhook has been removed.", "repo.settings.webhook_deletion_success": "The webhook has been removed.",
@@ -2258,7 +2258,7 @@
"repo.settings.githooks_desc": "Git Hooks are powered by Git itself. You can edit hook files below to set up custom operations.", "repo.settings.githooks_desc": "Git Hooks are powered by Git itself. You can edit hook files below to set up custom operations.",
"repo.settings.githook_edit_desc": "If the hook is inactive, sample content will be presented. Leaving content to an empty value will disable this hook.", "repo.settings.githook_edit_desc": "If the hook is inactive, sample content will be presented. Leaving content to an empty value will disable this hook.",
"repo.settings.update_githook": "Update Hook", "repo.settings.update_githook": "Update Hook",
"repo.settings.add_webhook_desc": "${APP_NAME} will send <code>POST</code> requests with a specified content type to the target URL. Read more in the <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%s\">webhooks guide</a>.", "repo.settings.add_webhook_desc": "MokoGitea will send <code>POST</code> requests with a specified content type to the target URL. Read more in the <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%s\">webhooks guide</a>.",
"repo.settings.payload_url": "Target URL", "repo.settings.payload_url": "Target URL",
"repo.settings.http_method": "HTTP Method", "repo.settings.http_method": "HTTP Method",
"repo.settings.content_type": "POST Content Type", "repo.settings.content_type": "POST Content Type",
@@ -2326,9 +2326,9 @@
"repo.settings.event_pull_request_merge": "Pull Request Merge", "repo.settings.event_pull_request_merge": "Pull Request Merge",
"repo.settings.event_header_workflow": "Workflow Events", "repo.settings.event_header_workflow": "Workflow Events",
"repo.settings.event_workflow_run": "Workflow Run", "repo.settings.event_workflow_run": "Workflow Run",
"repo.settings.event_workflow_run_desc": "${APP_NAME} Actions Workflow run queued, waiting, in progress, or completed.", "repo.settings.event_workflow_run_desc": "Gitea Actions Workflow run queued, waiting, in progress, or completed.",
"repo.settings.event_workflow_job": "Workflow Jobs", "repo.settings.event_workflow_job": "Workflow Jobs",
"repo.settings.event_workflow_job_desc": "${APP_NAME} Actions Workflow job queued, waiting, in progress, or completed.", "repo.settings.event_workflow_job_desc": "Gitea Actions Workflow job queued, waiting, in progress, or completed.",
"repo.settings.event_package": "Package", "repo.settings.event_package": "Package",
"repo.settings.event_package_desc": "Package created or deleted in a repository.", "repo.settings.event_package_desc": "Package created or deleted in a repository.",
"repo.settings.branch_filter": "Branch filter", "repo.settings.branch_filter": "Branch filter",
@@ -2349,7 +2349,7 @@
"repo.settings.slack_domain": "Domain", "repo.settings.slack_domain": "Domain",
"repo.settings.slack_channel": "Channel", "repo.settings.slack_channel": "Channel",
"repo.settings.add_web_hook_desc": "Integrate <a target=\"_blank\" rel=\"noreferrer\" href=\"%s\">%s</a> into your repository.", "repo.settings.add_web_hook_desc": "Integrate <a target=\"_blank\" rel=\"noreferrer\" href=\"%s\">%s</a> into your repository.",
"repo.settings.web_hook_name_gitea": "${APP_NAME}", "repo.settings.web_hook_name_gitea": "MokoGitea",
"repo.settings.web_hook_name_gogs": "Gogs", "repo.settings.web_hook_name_gogs": "Gogs",
"repo.settings.web_hook_name_slack": "Slack", "repo.settings.web_hook_name_slack": "Slack",
"repo.settings.web_hook_name_discord": "Discord", "repo.settings.web_hook_name_discord": "Discord",
@@ -2634,7 +2634,7 @@
"repo.release.delete_release": "Delete Release", "repo.release.delete_release": "Delete Release",
"repo.release.delete_tag": "Delete Tag", "repo.release.delete_tag": "Delete Tag",
"repo.release.deletion": "Delete Release", "repo.release.deletion": "Delete Release",
"repo.release.deletion_desc": "Deleting a release only removes it from ${APP_NAME}. It will not affect the Git tag, the contents of your repository or its history. Continue?", "repo.release.deletion_desc": "Deleting a release only removes it from MokoGitea. It will not affect the Git tag, the contents of your repository or its history. Continue?",
"repo.release.deletion_success": "The release has been deleted.", "repo.release.deletion_success": "The release has been deleted.",
"repo.release.deletion_tag_desc": "Will delete this tag from repository. Repository contents and history remain unchanged. Continue?", "repo.release.deletion_tag_desc": "Will delete this tag from repository. Repository contents and history remain unchanged. Continue?",
"repo.release.deletion_tag_success": "The tag has been deleted.", "repo.release.deletion_tag_success": "The tag has been deleted.",
@@ -2913,7 +2913,7 @@
"admin.last_page": "Last", "admin.last_page": "Last",
"admin.total": "Total: %d", "admin.total": "Total: %d",
"admin.settings": "Admin Settings", "admin.settings": "Admin Settings",
"admin.dashboard.new_version_hint": "${APP_NAME} %s is now available, you are running %s. Check <a target=\"_blank\" rel=\"noreferrer\" href=\"%s\">the blog</a> for more details.", "admin.dashboard.new_version_hint": "MokoGitea %s is now available, you are running %s. Check <a target=\"_blank\" rel=\"noreferrer\" href=\"%s\">the blog</a> for more details.",
"admin.dashboard.statistic": "Summary", "admin.dashboard.statistic": "Summary",
"admin.dashboard.maintenance_operations": "Maintenance Operations", "admin.dashboard.maintenance_operations": "Maintenance Operations",
"admin.dashboard.system_status": "System Status", "admin.dashboard.system_status": "System Status",
@@ -2949,8 +2949,8 @@
"admin.dashboard.deleted_branches_cleanup": "Clean up deleted branches", "admin.dashboard.deleted_branches_cleanup": "Clean up deleted branches",
"admin.dashboard.update_migration_poster_id": "Update migration poster IDs", "admin.dashboard.update_migration_poster_id": "Update migration poster IDs",
"admin.dashboard.git_gc_repos": "Garbage-collect all repositories", "admin.dashboard.git_gc_repos": "Garbage-collect all repositories",
"admin.dashboard.resync_all_sshkeys": "Update the '.ssh/authorized_keys' file with ${APP_NAME} SSH keys", "admin.dashboard.resync_all_sshkeys": "Update the '.ssh/authorized_keys' file with MokoGitea SSH keys",
"admin.dashboard.resync_all_sshprincipals": "Update the '.ssh/authorized_principals' file with ${APP_NAME} SSH principals", "admin.dashboard.resync_all_sshprincipals": "Update the '.ssh/authorized_principals' file with MokoGitea SSH principals",
"admin.dashboard.resync_all_hooks": "Resynchronize git hooks of all repositories (pre-receive, update, post-receive, proc-receive, ...)", "admin.dashboard.resync_all_hooks": "Resynchronize git hooks of all repositories (pre-receive, update, post-receive, proc-receive, ...)",
"admin.dashboard.reinit_missing_repos": "Reinitialize all missing Git repositories for which records exist", "admin.dashboard.reinit_missing_repos": "Reinitialize all missing Git repositories for which records exist",
"admin.dashboard.sync_external_users": "Synchronize external user data", "admin.dashboard.sync_external_users": "Synchronize external user data",
@@ -3030,7 +3030,7 @@
"admin.users.is_admin": "Is Administrator", "admin.users.is_admin": "Is Administrator",
"admin.users.is_restricted": "Is Restricted", "admin.users.is_restricted": "Is Restricted",
"admin.users.allow_git_hook": "May Create Git Hooks", "admin.users.allow_git_hook": "May Create Git Hooks",
"admin.users.allow_git_hook_tooltip": "Git Hooks are executed as the OS user running ${APP_NAME} and will have the same level of host access. As a result, users with this special Git Hook privilege can access and modify all ${APP_NAME} repositories as well as the database used by ${APP_NAME}. Consequently they are also able to gain ${APP_NAME} administrator privileges.", "admin.users.allow_git_hook_tooltip": "Git Hooks are executed as the OS user running MokoGitea and will have the same level of host access. As a result, users with this special Git Hook privilege can access and modify all MokoGitea repositories as well as the database used by MokoGitea. Consequently they are also able to gain MokoGitea administrator privileges.",
"admin.users.allow_import_local": "May Import Local Repositories", "admin.users.allow_import_local": "May Import Local Repositories",
"admin.users.allow_create_organization": "May Create Organizations", "admin.users.allow_create_organization": "May Create Organizations",
"admin.users.update_profile": "Update User Account", "admin.users.update_profile": "Update User Account",
@@ -3100,11 +3100,11 @@
"admin.packages.size": "Size", "admin.packages.size": "Size",
"admin.packages.published": "Published", "admin.packages.published": "Published",
"admin.defaulthooks": "Default Webhooks", "admin.defaulthooks": "Default Webhooks",
"admin.defaulthooks.desc": "Webhooks automatically make HTTP POST requests to a server when certain ${APP_NAME} events trigger. Webhooks defined here are defaults and will be copied into all new repositories. Read more in the <a target=\"_blank\" rel=\"noopener\" href=\"%s\">webhooks guide</a>.", "admin.defaulthooks.desc": "Webhooks automatically make HTTP POST requests to a server when certain MokoGitea events trigger. Webhooks defined here are defaults and will be copied into all new repositories. Read more in the <a target=\"_blank\" rel=\"noopener\" href=\"%s\">webhooks guide</a>.",
"admin.defaulthooks.add_webhook": "Add Default Webhook", "admin.defaulthooks.add_webhook": "Add Default Webhook",
"admin.defaulthooks.update_webhook": "Update Default Webhook", "admin.defaulthooks.update_webhook": "Update Default Webhook",
"admin.systemhooks": "System Webhooks", "admin.systemhooks": "System Webhooks",
"admin.systemhooks.desc": "Webhooks automatically make HTTP POST requests to a server when certain ${APP_NAME} events trigger. Webhooks defined here will act on all repositories on the system, so please consider any performance implications this may have. Read more in the <a target=\"_blank\" rel=\"noopener\" href=\"%s\">webhooks guide</a>.", "admin.systemhooks.desc": "Webhooks automatically make HTTP POST requests to a server when certain MokoGitea events trigger. Webhooks defined here will act on all repositories on the system, so please consider any performance implications this may have. Read more in the <a target=\"_blank\" rel=\"noopener\" href=\"%s\">webhooks guide</a>.",
"admin.systemhooks.add_webhook": "Add System Webhook", "admin.systemhooks.add_webhook": "Add System Webhook",
"admin.systemhooks.update_webhook": "Update System Webhook", "admin.systemhooks.update_webhook": "Update System Webhook",
"admin.auths.auth_manage_panel": "Authentication Source Management", "admin.auths.auth_manage_panel": "Authentication Source Management",
@@ -3125,7 +3125,7 @@
"admin.auths.user_base": "User Search Base", "admin.auths.user_base": "User Search Base",
"admin.auths.user_dn": "User DN", "admin.auths.user_dn": "User DN",
"admin.auths.attribute_username": "Username Attribute", "admin.auths.attribute_username": "Username Attribute",
"admin.auths.attribute_username_placeholder": "Leave empty to use the username entered in ${APP_NAME}.", "admin.auths.attribute_username_placeholder": "Leave empty to use the username entered in MokoGitea.",
"admin.auths.attribute_name": "First Name Attribute", "admin.auths.attribute_name": "First Name Attribute",
"admin.auths.attribute_surname": "Surname Attribute", "admin.auths.attribute_surname": "Surname Attribute",
"admin.auths.attribute_mail": "Email Attribute", "admin.auths.attribute_mail": "Email Attribute",
@@ -3232,7 +3232,7 @@
"admin.auths.invalid_openIdConnectAutoDiscoveryURL": "Invalid Auto Discovery URL (this must be a valid URL starting with http:// or https://)", "admin.auths.invalid_openIdConnectAutoDiscoveryURL": "Invalid Auto Discovery URL (this must be a valid URL starting with http:// or https://)",
"admin.config.server_config": "Server Configuration", "admin.config.server_config": "Server Configuration",
"admin.config.app_name": "Site Title", "admin.config.app_name": "Site Title",
"admin.config.app_ver": "${APP_NAME} Version", "admin.config.app_ver": "MokoGitea Version",
"admin.config.custom_conf": "Configuration File Path", "admin.config.custom_conf": "Configuration File Path",
"admin.config.custom_file_root_path": "Custom File Root Path", "admin.config.custom_file_root_path": "Custom File Root Path",
"admin.config.disable_router_log": "Disable Router Log", "admin.config.disable_router_log": "Disable Router Log",
@@ -3272,7 +3272,7 @@
"admin.config.service_config": "Service Configuration", "admin.config.service_config": "Service Configuration",
"admin.config.register_email_confirm": "Require Email Confirmation to Register", "admin.config.register_email_confirm": "Require Email Confirmation to Register",
"admin.config.disable_register": "Disable Self-Registration", "admin.config.disable_register": "Disable Self-Registration",
"admin.config.allow_only_internal_registration": "Allow Registration Only Through ${APP_NAME} itself", "admin.config.allow_only_internal_registration": "Allow Registration Only Through MokoGitea itself",
"admin.config.allow_only_external_registration": "Allow Registration Only Through External Services", "admin.config.allow_only_external_registration": "Allow Registration Only Through External Services",
"admin.config.enable_openid_signup": "Enable OpenID Self-Registration", "admin.config.enable_openid_signup": "Enable OpenID Self-Registration",
"admin.config.enable_openid_signin": "Enable OpenID Sign-In", "admin.config.enable_openid_signin": "Enable OpenID Sign-In",
@@ -3414,11 +3414,11 @@
"admin.self_check.no_problem_found": "No problem found yet.", "admin.self_check.no_problem_found": "No problem found yet.",
"admin.self_check.startup_warnings": "Startup warnings:", "admin.self_check.startup_warnings": "Startup warnings:",
"admin.self_check.database_collation_mismatch": "Expect database to use collation: %s", "admin.self_check.database_collation_mismatch": "Expect database to use collation: %s",
"admin.self_check.database_collation_case_insensitive": "Database is using collation %s, which is a case-insensitive collation. Although ${APP_NAME} could work with it, there might be some rare cases which don't work as expected.", "admin.self_check.database_collation_case_insensitive": "Database is using collation %s, which is a case-insensitive collation. Although MokoGitea could work with it, there might be some rare cases which don't work as expected.",
"admin.self_check.database_inconsistent_collation_columns": "Database is using collation %s, but these columns are using mismatched collations. This might cause some unexpected problems.", "admin.self_check.database_inconsistent_collation_columns": "Database is using collation %s, but these columns are using mismatched collations. This might cause some unexpected problems.",
"admin.self_check.database_fix_mysql": "For MySQL/MariaDB users, you could use the \"gitea doctor convert\" command to fix the collation problems, or you could also fix the problem manually with \"ALTER ... COLLATE ...\" SQL queries.", "admin.self_check.database_fix_mysql": "For MySQL/MariaDB users, you could use the \"gitea doctor convert\" command to fix the collation problems, or you could also fix the problem manually with \"ALTER ... COLLATE ...\" SQL queries.",
"admin.self_check.database_fix_mssql": "For MSSQL users, you could only fix the problem manually with \"ALTER ... COLLATE ...\" SQL queries at the moment.", "admin.self_check.database_fix_mssql": "For MSSQL users, you could only fix the problem manually with \"ALTER ... COLLATE ...\" SQL queries at the moment.",
"admin.self_check.location_origin_mismatch": "Current URL (%[1]s) doesn't match the URL seen by ${APP_NAME} (%[2]s). If you are using a reverse proxy, please make sure the \"Host\" and \"X-Forwarded-Proto\" headers are set correctly.", "admin.self_check.location_origin_mismatch": "Current URL (%[1]s) doesn't match the URL seen by MokoGitea (%[2]s). If you are using a reverse proxy, please make sure the \"Host\" and \"X-Forwarded-Proto\" headers are set correctly.",
"action.create_repo": "created repository <a href=\"%s\">%s</a>", "action.create_repo": "created repository <a href=\"%s\">%s</a>",
"action.rename_repo": "renamed repository from <code>%[1]s</code> to <a href=\"%[2]s\">%[3]s</a>", "action.rename_repo": "renamed repository from <code>%[1]s</code> to <a href=\"%[2]s\">%[3]s</a>",
"action.commit_repo": "pushed to <a href=\"%[2]s\">%[3]s</a> at <a href=\"%[1]s\">%[4]s</a>", "action.commit_repo": "pushed to <a href=\"%[2]s\">%[3]s</a> at <a href=\"%[1]s\">%[4]s</a>",
@@ -3771,8 +3771,8 @@
"actions.runs.status_no_select": "All status", "actions.runs.status_no_select": "All status",
"actions.runs.no_results": "No results matched.", "actions.runs.no_results": "No results matched.",
"actions.runs.no_workflows": "There are no workflows yet.", "actions.runs.no_workflows": "There are no workflows yet.",
"actions.runs.no_workflows.quick_start": "Don't know how to start with ${APP_NAME} Actions? See <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%s\">the quick start guide</a>.", "actions.runs.no_workflows.quick_start": "Don't know how to start with Gitea Actions? See <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%s\">the quick start guide</a>.",
"actions.runs.no_workflows.documentation": "For more information on ${APP_NAME} Actions, see <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%s\">the documentation</a>.", "actions.runs.no_workflows.documentation": "For more information on Gitea Actions, see <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%s\">the documentation</a>.",
"actions.runs.no_runs": "The workflow has no runs yet.", "actions.runs.no_runs": "The workflow has no runs yet.",
"actions.runs.empty_commit_message": "(empty commit message)", "actions.runs.empty_commit_message": "(empty commit message)",
"actions.runs.expire_log_message": "Logs have been purged because they were too old.", "actions.runs.expire_log_message": "Logs have been purged because they were too old.",
+3 -3
View File
@@ -147,11 +147,11 @@ func httpBase(ctx *context.Context, optGitService ...string) *serviceHandler {
if !ctx.IsSigned { if !ctx.IsSigned {
// TODO: support digit auth - which would be Authorization header with digit // TODO: support digit auth - which would be Authorization header with digit
if setting.OAuth2.Enabled { if setting.OAuth2.Enabled {
// `Basic realm="<AppName>"` tells the GCM to use builtin OAuth2 application: https://github.com/git-ecosystem/git-credential-manager/pull/1442 // `Basic realm="Gitea"` tells the GCM to use builtin OAuth2 application: https://github.com/git-ecosystem/git-credential-manager/pull/1442
ctx.Resp.Header().Set("WWW-Authenticate", fmt.Sprintf(`Basic realm="%s"`, setting.AppName)) ctx.Resp.Header().Set("WWW-Authenticate", `Basic realm="Gitea"`)
} else { } else {
// If OAuth2 is disabled, then use another realm to avoid GCM OAuth2 attempt // If OAuth2 is disabled, then use another realm to avoid GCM OAuth2 attempt
ctx.Resp.Header().Set("WWW-Authenticate", fmt.Sprintf(`Basic realm="%s (Basic Auth)"`, setting.AppName)) ctx.Resp.Header().Set("WWW-Authenticate", `Basic realm="Gitea (Basic Auth)"`)
} }
ctx.HTTPError(http.StatusUnauthorized) ctx.HTTPError(http.StatusUnauthorized)
return nil return nil
-2
View File
@@ -13,7 +13,6 @@ import (
// SwaggerV1Json render swagger v1 json // SwaggerV1Json render swagger v1 json
func SwaggerV1Json(ctx *context.Context) { func SwaggerV1Json(ctx *context.Context) {
ctx.Data["SwaggerAppVer"] = template.HTML(template.JSEscapeString(setting.AppVer)) ctx.Data["SwaggerAppVer"] = template.HTML(template.JSEscapeString(setting.AppVer))
ctx.Data["SwaggerAppName"] = template.HTML(template.JSEscapeString(setting.AppName))
ctx.Data["SwaggerAppSubUrl"] = setting.AppSubURL // it is JS-safe ctx.Data["SwaggerAppSubUrl"] = setting.AppSubURL // it is JS-safe
ctx.JSONTemplate("swagger/v1_json") ctx.JSONTemplate("swagger/v1_json")
} }
@@ -21,7 +20,6 @@ func SwaggerV1Json(ctx *context.Context) {
// OpenAPI3Json render OpenAPI 3.0 json (auto-converted from Swagger 2.0) // OpenAPI3Json render OpenAPI 3.0 json (auto-converted from Swagger 2.0)
func OpenAPI3Json(ctx *context.Context) { func OpenAPI3Json(ctx *context.Context) {
ctx.Data["SwaggerAppVer"] = template.HTML(template.JSEscapeString(setting.AppVer)) ctx.Data["SwaggerAppVer"] = template.HTML(template.JSEscapeString(setting.AppVer))
ctx.Data["SwaggerAppName"] = template.HTML(template.JSEscapeString(setting.AppName))
ctx.Data["SwaggerAppSubUrl"] = setting.AppSubURL // it is JS-safe ctx.Data["SwaggerAppSubUrl"] = setting.AppSubURL // it is JS-safe
ctx.JSONTemplate("swagger/v1_openapi3_json") ctx.JSONTemplate("swagger/v1_openapi3_json")
} }
+1 -1
View File
@@ -2,7 +2,7 @@
<div class="admin-setting-content"> <div class="admin-setting-content">
{{if .NeedUpdate}} {{if .NeedUpdate}}
<div class="ui positive message"> <div class="ui positive message">
<div class="header">{{svg "octicon-info"}} {{AppName}} Update Available</div> <div class="header">{{svg "octicon-info"}} MokoGitea Update Available</div>
<p>A new version <strong>{{.LatestVersion}}</strong> is available{{if .UpdateChannel}} ({{.UpdateChannel}} channel){{end}}. <p>A new version <strong>{{.LatestVersion}}</strong> is available{{if .UpdateChannel}} ({{.UpdateChannel}} channel){{end}}.
{{if .ReleaseURL}}<a href="{{.ReleaseURL}}" target="_blank" rel="noopener noreferrer">View release notes</a>{{end}}</p> {{if .ReleaseURL}}<a href="{{.ReleaseURL}}" target="_blank" rel="noopener noreferrer">View release notes</a>{{end}}</p>
{{if .DockerImage}}<p><code>docker pull {{.DockerImage}}</code></p>{{end}} {{if .DockerImage}}<p><code>docker pull {{.DockerImage}}</code></p>{{end}}
+1 -1
View File
@@ -1,7 +1,7 @@
<footer class="page-footer" role="group" aria-label="{{ctx.Locale.Tr "aria.footer"}}"> <footer class="page-footer" role="group" aria-label="{{ctx.Locale.Tr "aria.footer"}}">
<div class="left-links" role="contentinfo" aria-label="{{ctx.Locale.Tr "aria.footer.software"}}"> <div class="left-links" role="contentinfo" aria-label="{{ctx.Locale.Tr "aria.footer.software"}}">
{{if ShowFooterPoweredBy}} {{if ShowFooterPoweredBy}}
<a target="_blank" href="https://git.mokoconsulting.tech/MokoConsulting/MokoGitea">{{ctx.Locale.Tr "powered_by" AppName}}</a> <a target="_blank" href="https://git.mokoconsulting.tech/MokoConsulting/MokoGitea">{{ctx.Locale.Tr "powered_by" "MokoGitea"}}</a>
{{end}} {{end}}
{{if (or .ShowFooterVersion .PageIsAdmin)}} {{if (or .ShowFooterVersion .PageIsAdmin)}}
<span> <span>
+1 -1
View File
@@ -2,7 +2,7 @@
<html lang="en"> <html lang="en">
<head> <head>
{{ctx.HeadMetaContentSecurityPolicy}} {{ctx.HeadMetaContentSecurityPolicy}}
<title>{{AppName}} API</title> <title>Gitea API</title>
<link rel="stylesheet" href="{{ctx.CurrentWebTheme.PublicAssetURI}}"> <link rel="stylesheet" href="{{ctx.CurrentWebTheme.PublicAssetURI}}">
{{/* HINT: SWAGGER-CSS-IMPORT: import swagger styles ahead to avoid UI flicker (e.g.: the swagger-back-link element) */}} {{/* HINT: SWAGGER-CSS-IMPORT: import swagger styles ahead to avoid UI flicker (e.g.: the swagger-back-link element) */}}
<link rel="stylesheet" href="{{AssetURI "css/swagger.css"}}"> <link rel="stylesheet" href="{{AssetURI "css/swagger.css"}}">
+2 -2
View File
@@ -11,8 +11,8 @@
], ],
"swagger": "2.0", "swagger": "2.0",
"info": { "info": {
"description": "This documentation describes the {{.SwaggerAppName}} API.", "description": "This documentation describes the Gitea API.",
"title": "{{.SwaggerAppName}} API", "title": "Gitea API",
"license": { "license": {
"name": "MIT", "name": "MIT",
"url": "http://opensource.org/licenses/MIT" "url": "http://opensource.org/licenses/MIT"
+2 -2
View File
@@ -10588,12 +10588,12 @@
} }
}, },
"info": { "info": {
"description": "This documentation describes the {{.SwaggerAppName}} API.", "description": "This documentation describes the Gitea API.",
"license": { "license": {
"name": "MIT", "name": "MIT",
"url": "http://opensource.org/licenses/MIT" "url": "http://opensource.org/licenses/MIT"
}, },
"title": "{{.SwaggerAppName}} API", "title": "Gitea API",
"version": "{{.SwaggerAppVer}}" "version": "{{.SwaggerAppVer}}"
}, },
"openapi": "3.0.3", "openapi": "3.0.3",