diff --git a/.gitignore b/.gitignore index 9af51941..1f90377a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,8 @@ +# ============================================================ +# Local task tracking (not version controlled) +# ============================================================ +TODO.md + # ============================================================ # Environment and secrets # ============================================================ @@ -13,120 +18,51 @@ conf/conf.php conf/conf*.php secrets/ *.secrets.* -*.key -*.pem -*.p12 -*.pfx -auth.json # ============================================================ # Logs, dumps and databases # ============================================================ +*.db +*.db-journal *.dump *.log *.pid *.seed + # ============================================================ # OS / Editor / IDE cruft # ============================================================ - -# macOS .DS_Store -.DS_Store? -._* -.Spotlight-V100 -.Trashes -Icon? - -# Windows Thumbs.db +desktop.ini Thumbs.db:encryptable ehthumbs.db ehthumbs_vista.db -desktop.ini $RECYCLE.BIN/ System Volume Information/ *.lnk - -# Microsoft Office lock files (temp files created while a doc is open) -~$* - -# JetBrains IDEs +Icon? .idea/ - -# Eclipse / generic Java IDEs .settings/ -.project -.buildpath -.classpath - -# VS Code — personal settings; commit tasks/extensions/example settings only +.claude/ +.gemini/ .vscode/* !.vscode/tasks.json !.vscode/settings.json.example !.vscode/extensions.json *.code-workspace - -# Sublime Text *.sublime* - -# Vim / Emacs swap files +.project +.buildpath +.classpath +*.bak *.swp *.swo -*~ - -# Generic temp / backup -*.bak *.tmp *.old *.orig -# ============================================================ -# AI coding tools (local/session data — never commit) -# ============================================================ - -# Claude Code — entire local state dir (settings, history, cache) -# Project instructions go in .github/CLAUDE.md, not here -.claude/ - -# Anthropic CLI -.anthropic/ - -# Cursor IDE — personal MCP config and local state -# Shared team rules can live in .cursor/rules/ if desired -.cursor/ -.cursorignore - -# Aider -.aider.conf.yml -.aider.tags.cache.v3/ -.aider.chat.history.md -.aider.input.history - -# Continue.dev -.continue/ - -# Codeium / Windsurf -.codeium/ -.windsurf/ - -# Tabnine -.tabnine/ - -# GitHub Copilot (workspace-local overrides) -.copilot-ignore - -# Gemini Code Assist / Google IDX -.gemini/ -.idx/ - -# ============================================================ -# Runtime / generated data -# ============================================================ -# Checkpoint files written by bulk_sync.php and other long-running scripts -.checkpoints/ - # ============================================================ # Dev scripts and scratch # ============================================================ @@ -137,13 +73,18 @@ todo* # ============================================================ # SFTP / sync tools # ============================================================ -# Runtime directories — never committed; create locally from templates/scripts/deploy/ -scripts/sftp-config/ -scripts/keys/ -# Catch stray key or config files placed outside the above directories -*.ppk -sftp-* -!docs/visual/sftp-deployment.md +sftp-config*.json +sftp-config.json.template +sftp-settings.json + +# ============================================================ +# Sublime SFTP / FTP sync +# ============================================================ +*.sublime-project +*.sublime-workspace +*.sublime-settings +.libsass.json +*.ffs* # ============================================================ # Replit / cloud IDE @@ -162,8 +103,6 @@ replit.md *.zip artifacts/ release/ -!logs/release/ -!templates/scripts/release/ releases/ # ============================================================ @@ -175,10 +114,12 @@ releases/ build/ dist/ out/ -site/ +/site/ *.map *.css.map *.js.map +*.min.css +*.min.js *.tsbuildinfo # ============================================================ @@ -191,7 +132,6 @@ coverage.xml htmlcov/ junit.xml reports/ -!docs/reports/ test-results/ tests/_output/ .github/local/ @@ -215,20 +155,18 @@ package-lock.json # PHP / Composer tooling # ============================================================ vendor/ +!src/media/vendor/ composer.lock *.phar codeception.phar .phpunit.result.cache -.phpunit.cache/ .php_cs.cache .php-cs-fixer.cache .phpstan.cache -.phpstan/ .phplint-cache phpmd-cache/ .psalm/ .rector/ -.php_rector.cache # ============================================================ # Python @@ -243,7 +181,7 @@ __pycache__/ *.egg *.egg-info/ .installed.cfg -MANIFEST +/MANIFEST develop-eggs/ downloads/ eggs/ @@ -265,808 +203,11 @@ venv/ *.coverage hypothesis/ +profile.ps1 +.mcp.json + # ============================================================ # Local wiki clone (not version controlled) # ============================================================ wiki/ - -# ============================================================ -# Dolibarr (base + runtime) -# ============================================================ -documents/ -dolibarr_documents/ -custom/ -uploads/ -thumbs/ -data/ -cache/ -temp/ -tmp/ -logs/*.log -logs/**/*.log -!logs/README.md -!logs/**/.gitkeep -htdocs/documents/ -htdocs/custom/ -htdocs/cache/ -htdocs/tmp/ -htdocs/logs/ -modulebuilder.txt - -# ============================================================ -# Joomla Core -# ============================================================ -/.htaccess -/administrator/cache/* -/administrator/components/com_actionlogs/* -/administrator/components/com_admin/* -/administrator/components/com_ajax/* -/administrator/components/com_associations/* -/administrator/components/com_banners/* -/administrator/components/com_cache/* -/administrator/components/com_categories/* -/administrator/components/com_checkin/* -/administrator/components/com_config/* -/administrator/components/com_contact/* -/administrator/components/com_content/* -/administrator/components/com_contenthistory/* -/administrator/components/com_cpanel/* -/administrator/components/com_fields/* -/administrator/components/com_finder/* -/administrator/components/com_installer/* -/administrator/components/com_joomlaupdate/* -/administrator/components/com_languages/* -/administrator/components/com_login/* -/administrator/components/com_media/* -/administrator/components/com_menus/* -/administrator/components/com_messages/* -/administrator/components/com_modules/* -/administrator/components/com_newsfeeds/* -/administrator/components/com_plugins/* -/administrator/components/com_postinstall/* -/administrator/components/com_privacy/* -/administrator/components/com_redirect/* -/administrator/components/com_search/* -/administrator/components/com_tags/* -/administrator/components/com_templates/* -/administrator/components/com_users/* -/administrator/help/* -/administrator/includes/* -/administrator/index.php -/administrator/language/en-GB/en-GB.com_actionlogs.ini -/administrator/language/en-GB/en-GB.com_actionlogs.sys.ini -/administrator/language/en-GB/en-GB.com_admin.ini -/administrator/language/en-GB/en-GB.com_admin.sys.ini -/administrator/language/en-GB/en-GB.com_ajax.ini -/administrator/language/en-GB/en-GB.com_ajax.sys.ini -/administrator/language/en-GB/en-GB.com_associations.ini -/administrator/language/en-GB/en-GB.com_associations.sys.ini -/administrator/language/en-GB/en-GB.com_banners.ini -/administrator/language/en-GB/en-GB.com_banners.sys.ini -/administrator/language/en-GB/en-GB.com_cache.ini -/administrator/language/en-GB/en-GB.com_cache.sys.ini -/administrator/language/en-GB/en-GB.com_categories.ini -/administrator/language/en-GB/en-GB.com_categories.sys.ini -/administrator/language/en-GB/en-GB.com_checkin.ini -/administrator/language/en-GB/en-GB.com_checkin.sys.ini -/administrator/language/en-GB/en-GB.com_config.ini -/administrator/language/en-GB/en-GB.com_config.sys.ini -/administrator/language/en-GB/en-GB.com_contact.ini -/administrator/language/en-GB/en-GB.com_contact.sys.ini -/administrator/language/en-GB/en-GB.com_content.ini -/administrator/language/en-GB/en-GB.com_content.sys.ini -/administrator/language/en-GB/en-GB.com_contenthistory.ini -/administrator/language/en-GB/en-GB.com_contenthistory.sys.ini -/administrator/language/en-GB/en-GB.com_cpanel.ini -/administrator/language/en-GB/en-GB.com_cpanel.sys.ini -/administrator/language/en-GB/en-GB.com_fields.ini -/administrator/language/en-GB/en-GB.com_fields.sys.ini -/administrator/language/en-GB/en-GB.com_finder.ini -/administrator/language/en-GB/en-GB.com_finder.sys.ini -/administrator/language/en-GB/en-GB.com_installer.ini -/administrator/language/en-GB/en-GB.com_installer.sys.ini -/administrator/language/en-GB/en-GB.com_joomlaupdate.ini -/administrator/language/en-GB/en-GB.com_joomlaupdate.sys.ini -/administrator/language/en-GB/en-GB.com_languages.ini -/administrator/language/en-GB/en-GB.com_languages.sys.ini -/administrator/language/en-GB/en-GB.com_login.ini -/administrator/language/en-GB/en-GB.com_login.sys.ini -/administrator/language/en-GB/en-GB.com_mailto.sys.ini -/administrator/language/en-GB/en-GB.com_media.ini -/administrator/language/en-GB/en-GB.com_media.sys.ini -/administrator/language/en-GB/en-GB.com_menus.ini -/administrator/language/en-GB/en-GB.com_menus.sys.ini -/administrator/language/en-GB/en-GB.com_messages.ini -/administrator/language/en-GB/en-GB.com_messages.sys.ini -/administrator/language/en-GB/en-GB.com_modules.ini -/administrator/language/en-GB/en-GB.com_modules.sys.ini -/administrator/language/en-GB/en-GB.com_newsfeeds.ini -/administrator/language/en-GB/en-GB.com_newsfeeds.sys.ini -/administrator/language/en-GB/en-GB.com_plugins.ini -/administrator/language/en-GB/en-GB.com_plugins.sys.ini -/administrator/language/en-GB/en-GB.com_postinstall.ini -/administrator/language/en-GB/en-GB.com_postinstall.sys.ini -/administrator/language/en-GB/en-GB.com_privacy.ini -/administrator/language/en-GB/en-GB.com_privacy.sys.ini -/administrator/language/en-GB/en-GB.com_redirect.ini -/administrator/language/en-GB/en-GB.com_redirect.sys.ini -/administrator/language/en-GB/en-GB.com_search.ini -/administrator/language/en-GB/en-GB.com_search.sys.ini -/administrator/language/en-GB/en-GB.com_tags.ini -/administrator/language/en-GB/en-GB.com_tags.sys.ini -/administrator/language/en-GB/en-GB.com_templates.ini -/administrator/language/en-GB/en-GB.com_templates.sys.ini -/administrator/language/en-GB/en-GB.com_users.ini -/administrator/language/en-GB/en-GB.com_users.sys.ini -/administrator/language/en-GB/en-GB.com_weblinks.ini -/administrator/language/en-GB/en-GB.com_weblinks.sys.ini -/administrator/language/en-GB/en-GB.com_wrapper.ini -/administrator/language/en-GB/en-GB.com_wrapper.sys.ini -/administrator/language/en-GB/en-GB.ini -/administrator/language/en-GB/en-GB.lib_joomla.ini -/administrator/language/en-GB/en-GB.localise.php -/administrator/language/en-GB/en-GB.mod_custom.ini -/administrator/language/en-GB/en-GB.mod_custom.sys.ini -/administrator/language/en-GB/en-GB.mod_feed.ini -/administrator/language/en-GB/en-GB.mod_feed.sys.ini -/administrator/language/en-GB/en-GB.mod_latest.ini -/administrator/language/en-GB/en-GB.mod_latest.sys.ini -/administrator/language/en-GB/en-GB.mod_latestactions.ini -/administrator/language/en-GB/en-GB.mod_latestactions.sys.ini -/administrator/language/en-GB/en-GB.mod_logged.ini -/administrator/language/en-GB/en-GB.mod_logged.sys.ini -/administrator/language/en-GB/en-GB.mod_login.ini -/administrator/language/en-GB/en-GB.mod_login.sys.ini -/administrator/language/en-GB/en-GB.mod_menu.ini -/administrator/language/en-GB/en-GB.mod_menu.sys.ini -/administrator/language/en-GB/en-GB.mod_multilangstatus.ini -/administrator/language/en-GB/en-GB.mod_multilangstatus.sys.ini -/administrator/language/en-GB/en-GB.mod_online.ini -/administrator/language/en-GB/en-GB.mod_online.sys.ini -/administrator/language/en-GB/en-GB.mod_popular.ini -/administrator/language/en-GB/en-GB.mod_popular.sys.ini -/administrator/language/en-GB/en-GB.mod_privacy_dashboard.ini -/administrator/language/en-GB/en-GB.mod_privacy_dashboard.sys.ini -/administrator/language/en-GB/en-GB.mod_quickicon.ini -/administrator/language/en-GB/en-GB.mod_quickicon.sys.ini -/administrator/language/en-GB/en-GB.mod_sampledata.ini -/administrator/language/en-GB/en-GB.mod_sampledata.sys.ini -/administrator/language/en-GB/en-GB.mod_stats_admin.ini -/administrator/language/en-GB/en-GB.mod_stats_admin.sys.ini -/administrator/language/en-GB/en-GB.mod_status.ini -/administrator/language/en-GB/en-GB.mod_status.sys.ini -/administrator/language/en-GB/en-GB.mod_submenu.ini -/administrator/language/en-GB/en-GB.mod_submenu.sys.ini -/administrator/language/en-GB/en-GB.mod_title.ini -/administrator/language/en-GB/en-GB.mod_title.sys.ini -/administrator/language/en-GB/en-GB.mod_toolbar.ini -/administrator/language/en-GB/en-GB.mod_toolbar.sys.ini -/administrator/language/en-GB/en-GB.mod_unread.ini -/administrator/language/en-GB/en-GB.mod_unread.sys.ini -/administrator/language/en-GB/en-GB.mod_version.ini -/administrator/language/en-GB/en-GB.mod_version.sys.ini -/administrator/language/en-GB/en-GB.plg_actionlog_joomla.ini -/administrator/language/en-GB/en-GB.plg_actionlog_joomla.sys.ini -/administrator/language/en-GB/en-GB.plg_authentication_cookie.ini -/administrator/language/en-GB/en-GB.plg_authentication_cookie.sys.ini -/administrator/language/en-GB/en-GB.plg_authentication_example.ini -/administrator/language/en-GB/en-GB.plg_authentication_example.sys.ini -/administrator/language/en-GB/en-GB.plg_authentication_gmail.ini -/administrator/language/en-GB/en-GB.plg_authentication_gmail.sys.ini -/administrator/language/en-GB/en-GB.plg_authentication_joomla.ini -/administrator/language/en-GB/en-GB.plg_authentication_joomla.sys.ini -/administrator/language/en-GB/en-GB.plg_authentication_ldap.ini -/administrator/language/en-GB/en-GB.plg_authentication_ldap.sys.ini -/administrator/language/en-GB/en-GB.plg_captcha_recaptcha.ini -/administrator/language/en-GB/en-GB.plg_captcha_recaptcha.sys.ini -/administrator/language/en-GB/en-GB.plg_captcha_recaptcha_invisible.ini -/administrator/language/en-GB/en-GB.plg_captcha_recaptcha_invisible.sys.ini -/administrator/language/en-GB/en-GB.plg_content_confirmconsent.ini -/administrator/language/en-GB/en-GB.plg_content_confirmconsent.sys.ini -/administrator/language/en-GB/en-GB.plg_content_contact.ini -/administrator/language/en-GB/en-GB.plg_content_contact.sys.ini -/administrator/language/en-GB/en-GB.plg_content_emailcloak.ini -/administrator/language/en-GB/en-GB.plg_content_emailcloak.sys.ini -/administrator/language/en-GB/en-GB.plg_content_fields.ini -/administrator/language/en-GB/en-GB.plg_content_fields.sys.ini -/administrator/language/en-GB/en-GB.plg_content_finder.ini -/administrator/language/en-GB/en-GB.plg_content_finder.sys.ini -/administrator/language/en-GB/en-GB.plg_content_geshi.ini -/administrator/language/en-GB/en-GB.plg_content_geshi.sys.ini -/administrator/language/en-GB/en-GB.plg_content_joomla.ini -/administrator/language/en-GB/en-GB.plg_content_joomla.sys.ini -/administrator/language/en-GB/en-GB.plg_content_loadmodule.ini -/administrator/language/en-GB/en-GB.plg_content_loadmodule.sys.ini -/administrator/language/en-GB/en-GB.plg_content_pagebreak.ini -/administrator/language/en-GB/en-GB.plg_content_pagebreak.sys.ini -/administrator/language/en-GB/en-GB.plg_content_pagenavigation.ini -/administrator/language/en-GB/en-GB.plg_content_pagenavigation.sys.ini -/administrator/language/en-GB/en-GB.plg_content_vote.ini -/administrator/language/en-GB/en-GB.plg_content_vote.sys.ini -/administrator/language/en-GB/en-GB.plg_editors-xtd_article.ini -/administrator/language/en-GB/en-GB.plg_editors-xtd_article.sys.ini -/administrator/language/en-GB/en-GB.plg_editors-xtd_contact.ini -/administrator/language/en-GB/en-GB.plg_editors-xtd_contact.sys.ini -/administrator/language/en-GB/en-GB.plg_editors-xtd_fields.ini -/administrator/language/en-GB/en-GB.plg_editors-xtd_fields.sys.ini -/administrator/language/en-GB/en-GB.plg_editors-xtd_image.ini -/administrator/language/en-GB/en-GB.plg_editors-xtd_image.sys.ini -/administrator/language/en-GB/en-GB.plg_editors-xtd_menu.ini -/administrator/language/en-GB/en-GB.plg_editors-xtd_menu.sys.ini -/administrator/language/en-GB/en-GB.plg_editors-xtd_module.ini -/administrator/language/en-GB/en-GB.plg_editors-xtd_module.sys.ini -/administrator/language/en-GB/en-GB.plg_editors-xtd_pagebreak.ini -/administrator/language/en-GB/en-GB.plg_editors-xtd_pagebreak.sys.ini -/administrator/language/en-GB/en-GB.plg_editors-xtd_readmore.ini -/administrator/language/en-GB/en-GB.plg_editors-xtd_readmore.sys.ini -/administrator/language/en-GB/en-GB.plg_editors_codemirror.ini -/administrator/language/en-GB/en-GB.plg_editors_codemirror.sys.ini -/administrator/language/en-GB/en-GB.plg_editors_none.ini -/administrator/language/en-GB/en-GB.plg_editors_none.sys.ini -/administrator/language/en-GB/en-GB.plg_editors_tinymce.ini -/administrator/language/en-GB/en-GB.plg_editors_tinymce.sys.ini -/administrator/language/en-GB/en-GB.plg_extension_joomla.ini -/administrator/language/en-GB/en-GB.plg_extension_joomla.sys.ini -/administrator/language/en-GB/en-GB.plg_fields_calendar.ini -/administrator/language/en-GB/en-GB.plg_fields_calendar.sys.ini -/administrator/language/en-GB/en-GB.plg_fields_checkboxes.ini -/administrator/language/en-GB/en-GB.plg_fields_checkboxes.sys.ini -/administrator/language/en-GB/en-GB.plg_fields_color.ini -/administrator/language/en-GB/en-GB.plg_fields_color.sys.ini -/administrator/language/en-GB/en-GB.plg_fields_editor.ini -/administrator/language/en-GB/en-GB.plg_fields_editor.sys.ini -/administrator/language/en-GB/en-GB.plg_fields_image.ini -/administrator/language/en-GB/en-GB.plg_fields_image.sys.ini -/administrator/language/en-GB/en-GB.plg_fields_imagelist.ini -/administrator/language/en-GB/en-GB.plg_fields_imagelist.sys.ini -/administrator/language/en-GB/en-GB.plg_fields_integer.ini -/administrator/language/en-GB/en-GB.plg_fields_integer.sys.ini -/administrator/language/en-GB/en-GB.plg_fields_list.ini -/administrator/language/en-GB/en-GB.plg_fields_list.sys.ini -/administrator/language/en-GB/en-GB.plg_fields_media.ini -/administrator/language/en-GB/en-GB.plg_fields_media.sys.ini -/administrator/language/en-GB/en-GB.plg_fields_radio.ini -/administrator/language/en-GB/en-GB.plg_fields_radio.sys.ini -/administrator/language/en-GB/en-GB.plg_fields_repeatable.ini -/administrator/language/en-GB/en-GB.plg_fields_repeatable.sys.ini -/administrator/language/en-GB/en-GB.plg_fields_sql.ini -/administrator/language/en-GB/en-GB.plg_fields_sql.sys.ini -/administrator/language/en-GB/en-GB.plg_fields_text.ini -/administrator/language/en-GB/en-GB.plg_fields_text.sys.ini -/administrator/language/en-GB/en-GB.plg_fields_textarea.ini -/administrator/language/en-GB/en-GB.plg_fields_textarea.sys.ini -/administrator/language/en-GB/en-GB.plg_fields_url.ini -/administrator/language/en-GB/en-GB.plg_fields_url.sys.ini -/administrator/language/en-GB/en-GB.plg_fields_user.ini -/administrator/language/en-GB/en-GB.plg_fields_user.sys.ini -/administrator/language/en-GB/en-GB.plg_fields_usergrouplist.ini -/administrator/language/en-GB/en-GB.plg_fields_usergrouplist.sys.ini -/administrator/language/en-GB/en-GB.plg_finder_categories.ini -/administrator/language/en-GB/en-GB.plg_finder_categories.sys.ini -/administrator/language/en-GB/en-GB.plg_finder_contacts.ini -/administrator/language/en-GB/en-GB.plg_finder_contacts.sys.ini -/administrator/language/en-GB/en-GB.plg_finder_content.ini -/administrator/language/en-GB/en-GB.plg_finder_content.sys.ini -/administrator/language/en-GB/en-GB.plg_finder_newsfeeds.ini -/administrator/language/en-GB/en-GB.plg_finder_newsfeeds.sys.ini -/administrator/language/en-GB/en-GB.plg_finder_tags.ini -/administrator/language/en-GB/en-GB.plg_finder_tags.sys.ini -/administrator/language/en-GB/en-GB.plg_finder_weblinks.ini -/administrator/language/en-GB/en-GB.plg_finder_weblinks.sys.ini -/administrator/language/en-GB/en-GB.plg_installer_folderinstaller.ini -/administrator/language/en-GB/en-GB.plg_installer_folderinstaller.sys.ini -/administrator/language/en-GB/en-GB.plg_installer_packageinstaller.ini -/administrator/language/en-GB/en-GB.plg_installer_packageinstaller.sys.ini -/administrator/language/en-GB/en-GB.plg_installer_urlinstaller.ini -/administrator/language/en-GB/en-GB.plg_installer_urlinstaller.sys.ini -/administrator/language/en-GB/en-GB.plg_installer_webinstaller.ini -/administrator/language/en-GB/en-GB.plg_installer_webinstaller.sys.ini -/administrator/language/en-GB/en-GB.plg_privacy_actionlogs.ini -/administrator/language/en-GB/en-GB.plg_privacy_actionlogs.sys.ini -/administrator/language/en-GB/en-GB.plg_privacy_consents.ini -/administrator/language/en-GB/en-GB.plg_privacy_consents.sys.ini -/administrator/language/en-GB/en-GB.plg_privacy_contact.ini -/administrator/language/en-GB/en-GB.plg_privacy_contact.sys.ini -/administrator/language/en-GB/en-GB.plg_privacy_content.ini -/administrator/language/en-GB/en-GB.plg_privacy_content.sys.ini -/administrator/language/en-GB/en-GB.plg_privacy_message.ini -/administrator/language/en-GB/en-GB.plg_privacy_message.sys.ini -/administrator/language/en-GB/en-GB.plg_privacy_user.ini -/administrator/language/en-GB/en-GB.plg_privacy_user.sys.ini -/administrator/language/en-GB/en-GB.plg_quickicon_extensionupdate.ini -/administrator/language/en-GB/en-GB.plg_quickicon_extensionupdate.sys.ini -/administrator/language/en-GB/en-GB.plg_quickicon_joomlaupdate.ini -/administrator/language/en-GB/en-GB.plg_quickicon_joomlaupdate.sys.ini -/administrator/language/en-GB/en-GB.plg_quickicon_phpversioncheck.ini -/administrator/language/en-GB/en-GB.plg_quickicon_phpversioncheck.sys.ini -/administrator/language/en-GB/en-GB.plg_quickicon_privacycheck.ini -/administrator/language/en-GB/en-GB.plg_quickicon_privacycheck.sys.ini -/administrator/language/en-GB/en-GB.plg_sampledata_blog.ini -/administrator/language/en-GB/en-GB.plg_sampledata_blog.sys.ini -/administrator/language/en-GB/en-GB.plg_search_categories.ini -/administrator/language/en-GB/en-GB.plg_search_categories.sys.ini -/administrator/language/en-GB/en-GB.plg_search_contacts.ini -/administrator/language/en-GB/en-GB.plg_search_contacts.sys.ini -/administrator/language/en-GB/en-GB.plg_search_content.ini -/administrator/language/en-GB/en-GB.plg_search_content.sys.ini -/administrator/language/en-GB/en-GB.plg_search_newsfeeds.ini -/administrator/language/en-GB/en-GB.plg_search_newsfeeds.sys.ini -/administrator/language/en-GB/en-GB.plg_search_tags.ini -/administrator/language/en-GB/en-GB.plg_search_tags.sys.ini -/administrator/language/en-GB/en-GB.plg_search_weblinks.ini -/administrator/language/en-GB/en-GB.plg_search_weblinks.sys.ini -/administrator/language/en-GB/en-GB.plg_system_actionlogs.ini -/administrator/language/en-GB/en-GB.plg_system_actionlogs.sys.ini -/administrator/language/en-GB/en-GB.plg_system_cache.ini -/administrator/language/en-GB/en-GB.plg_system_cache.sys.ini -/administrator/language/en-GB/en-GB.plg_system_debug.ini -/administrator/language/en-GB/en-GB.plg_system_debug.sys.ini -/administrator/language/en-GB/en-GB.plg_system_fields.ini -/administrator/language/en-GB/en-GB.plg_system_fields.sys.ini -/administrator/language/en-GB/en-GB.plg_system_highlight.ini -/administrator/language/en-GB/en-GB.plg_system_highlight.sys.ini -/administrator/language/en-GB/en-GB.plg_system_languagecode.ini -/administrator/language/en-GB/en-GB.plg_system_languagecode.sys.ini -/administrator/language/en-GB/en-GB.plg_system_languagefilter.ini -/administrator/language/en-GB/en-GB.plg_system_languagefilter.sys.ini -/administrator/language/en-GB/en-GB.plg_system_log.ini -/administrator/language/en-GB/en-GB.plg_system_log.sys.ini -/administrator/language/en-GB/en-GB.plg_system_logout.ini -/administrator/language/en-GB/en-GB.plg_system_logout.sys.ini -/administrator/language/en-GB/en-GB.plg_system_logrotation.ini -/administrator/language/en-GB/en-GB.plg_system_logrotation.sys.ini -/administrator/language/en-GB/en-GB.plg_system_p3p.ini -/administrator/language/en-GB/en-GB.plg_system_p3p.sys.ini -/administrator/language/en-GB/en-GB.plg_system_privacyconsent.ini -/administrator/language/en-GB/en-GB.plg_system_privacyconsent.sys.ini -/administrator/language/en-GB/en-GB.plg_system_redirect.ini -/administrator/language/en-GB/en-GB.plg_system_redirect.sys.ini -/administrator/language/en-GB/en-GB.plg_system_remember.ini -/administrator/language/en-GB/en-GB.plg_system_remember.sys.ini -/administrator/language/en-GB/en-GB.plg_system_sef.ini -/administrator/language/en-GB/en-GB.plg_system_sef.sys.ini -/administrator/language/en-GB/en-GB.plg_system_sessiongc.ini -/administrator/language/en-GB/en-GB.plg_system_sessiongc.sys.ini -/administrator/language/en-GB/en-GB.plg_system_stats.ini -/administrator/language/en-GB/en-GB.plg_system_stats.sys.ini -/administrator/language/en-GB/en-GB.plg_system_updatenotification.ini -/administrator/language/en-GB/en-GB.plg_system_updatenotification.sys.ini -/administrator/language/en-GB/en-GB.plg_twofactorauth_totp.ini -/administrator/language/en-GB/en-GB.plg_twofactorauth_totp.sys.ini -/administrator/language/en-GB/en-GB.plg_twofactorauth_yubikey.ini -/administrator/language/en-GB/en-GB.plg_twofactorauth_yubikey.sys.ini -/administrator/language/en-GB/en-GB.plg_user_contactcreator.ini -/administrator/language/en-GB/en-GB.plg_user_contactcreator.sys.ini -/administrator/language/en-GB/en-GB.plg_user_joomla.ini -/administrator/language/en-GB/en-GB.plg_user_joomla.sys.ini -/administrator/language/en-GB/en-GB.plg_user_profile.ini -/administrator/language/en-GB/en-GB.plg_user_profile.sys.ini -/administrator/language/en-GB/en-GB.plg_user_terms.ini -/administrator/language/en-GB/en-GB.plg_user_terms.sys.ini -/administrator/language/en-GB/en-GB.tpl_hathor.ini -/administrator/language/en-GB/en-GB.tpl_hathor.sys.ini -/administrator/language/en-GB/en-GB.tpl_isis.ini -/administrator/language/en-GB/en-GB.tpl_isis.sys.ini -/administrator/language/en-GB/en-GB.xml -/administrator/language/en-GB/install.xml -/administrator/language/overrides/* -/administrator/language/index.html -/administrator/logs/* -/administrator/manifests/files/joomla.xml -/administrator/manifests/libraries/fof.xml -/administrator/manifests/libraries/idna_convert.xml -/administrator/manifests/libraries/joomla.xml -/administrator/manifests/libraries/phpass.xml -/administrator/manifests/libraries/phputf8.xml -/administrator/manifests/packages/pkg_en-GB.xml -/administrator/manifests/packages/index.html -/administrator/modules/mod_custom/* -/administrator/modules/mod_feed/* -/administrator/modules/mod_latest/* -/administrator/modules/mod_latestactions/* -/administrator/modules/mod_logged/* -/administrator/modules/mod_login/* -/administrator/modules/mod_menu/* -/administrator/modules/mod_multilangstatus/* -/administrator/modules/mod_online/* -/administrator/modules/mod_popular/* -/administrator/modules/mod_privacy_dashboard/* -/administrator/modules/mod_quickicon/* -/administrator/modules/mod_sampledata/* -/administrator/modules/mod_stats_admin/* -/administrator/modules/mod_status/* -/administrator/modules/mod_submenu/* -/administrator/modules/mod_title/* -/administrator/modules/mod_toolbar/* -/administrator/modules/mod_unread/* -/administrator/modules/mod_version/* -/administrator/templates/hathor/* -/administrator/templates/isis/* -/administrator/templates/system/* -/bin/* -!/bin/moko -/cache/* -/cli/* -!/cli/*.php -/components/com_ajax/* -/components/com_banners/* -/components/com_config/* -/components/com_contact/* -/components/com_content/* -/components/com_contenthistory/* -/components/com_fields/* -/components/com_finder/* -/components/com_mailto/* -/components/com_media/* -/components/com_menus/* -/components/com_modules/* -/components/com_newsfeeds/* -/components/com_privacy/* -/components/com_search/* -/components/com_tags/* -/components/com_users/* -/components/com_wrapper/* -/components/index.html -/images/banners/* -/images/headers/* -/images/sampledata/* -/images/index.html -/images/joomla* -/images/powered_by.png -/includes/* -/installation/* -/language/en-GB/en-GB.com_ajax.ini -/language/en-GB/en-GB.com_config.ini -/language/en-GB/en-GB.com_contact.ini -/language/en-GB/en-GB.com_content.ini -/language/en-GB/en-GB.com_finder.ini -/language/en-GB/en-GB.com_mailto.ini -/language/en-GB/en-GB.com_media.ini -/language/en-GB/en-GB.com_messages.ini -/language/en-GB/en-GB.com_newsfeeds.ini -/language/en-GB/en-GB.com_privacy.ini -/language/en-GB/en-GB.com_search.ini -/language/en-GB/en-GB.com_tags.ini -/language/en-GB/en-GB.com_users.ini -/language/en-GB/en-GB.com_weblinks.ini -/language/en-GB/en-GB.com_wrapper.ini -/language/en-GB/en-GB.files_joomla.sys.ini -/language/en-GB/en-GB.finder_cli.ini -/language/en-GB/en-GB.ini -/language/en-GB/en-GB.lib_fof.ini -/language/en-GB/en-GB.lib_fof.sys.ini -/language/en-GB/en-GB.lib_idna_convert.sys.ini -/language/en-GB/en-GB.lib_joomla.ini -/language/en-GB/en-GB.lib_joomla.sys.ini -/language/en-GB/en-GB.lib_phpass.sys.ini -/language/en-GB/en-GB.lib_phpmailer.sys.ini -/language/en-GB/en-GB.lib_phputf8.sys.ini -/language/en-GB/en-GB.lib_simplepie.sys.ini -/language/en-GB/en-GB.localise.php -/language/en-GB/en-GB.mod_articles_archive.ini -/language/en-GB/en-GB.mod_articles_archive.sys.ini -/language/en-GB/en-GB.mod_articles_categories.ini -/language/en-GB/en-GB.mod_articles_categories.sys.ini -/language/en-GB/en-GB.mod_articles_category.ini -/language/en-GB/en-GB.mod_articles_category.sys.ini -/language/en-GB/en-GB.mod_articles_latest.ini -/language/en-GB/en-GB.mod_articles_latest.sys.ini -/language/en-GB/en-GB.mod_articles_news.ini -/language/en-GB/en-GB.mod_articles_news.sys.ini -/language/en-GB/en-GB.mod_articles_popular.ini -/language/en-GB/en-GB.mod_articles_popular.sys.ini -/language/en-GB/en-GB.mod_banners.ini -/language/en-GB/en-GB.mod_banners.sys.ini -/language/en-GB/en-GB.mod_breadcrumbs.ini -/language/en-GB/en-GB.mod_breadcrumbs.sys.ini -/language/en-GB/en-GB.mod_custom.ini -/language/en-GB/en-GB.mod_custom.sys.ini -/language/en-GB/en-GB.mod_feed.ini -/language/en-GB/en-GB.mod_feed.sys.ini -/language/en-GB/en-GB.mod_finder.ini -/language/en-GB/en-GB.mod_finder.sys.ini -/language/en-GB/en-GB.mod_footer.ini -/language/en-GB/en-GB.mod_footer.sys.ini -/language/en-GB/en-GB.mod_languages.ini -/language/en-GB/en-GB.mod_languages.sys.ini -/language/en-GB/en-GB.mod_login.ini -/language/en-GB/en-GB.mod_login.sys.ini -/language/en-GB/en-GB.mod_menu.ini -/language/en-GB/en-GB.mod_menu.sys.ini -/language/en-GB/en-GB.mod_random_image.ini -/language/en-GB/en-GB.mod_random_image.sys.ini -/language/en-GB/en-GB.mod_related_items.ini -/language/en-GB/en-GB.mod_related_items.sys.ini -/language/en-GB/en-GB.mod_search.ini -/language/en-GB/en-GB.mod_search.sys.ini -/language/en-GB/en-GB.mod_stats.ini -/language/en-GB/en-GB.mod_stats.sys.ini -/language/en-GB/en-GB.mod_syndicate.ini -/language/en-GB/en-GB.mod_syndicate.sys.ini -/language/en-GB/en-GB.mod_tags_popular.ini -/language/en-GB/en-GB.mod_tags_popular.sys.ini -/language/en-GB/en-GB.mod_tags_similar.ini -/language/en-GB/en-GB.mod_tags_similar.sys.ini -/language/en-GB/en-GB.mod_users_latest.ini -/language/en-GB/en-GB.mod_users_latest.sys.ini -/language/en-GB/en-GB.mod_weblinks.ini -/language/en-GB/en-GB.mod_weblinks.sys.ini -/language/en-GB/en-GB.mod_whosonline.ini -/language/en-GB/en-GB.mod_whosonline.sys.ini -/language/en-GB/en-GB.mod_wrapper.ini -/language/en-GB/en-GB.mod_wrapper.sys.ini -/language/en-GB/en-GB.tpl_atomic.ini -/language/en-GB/en-GB.tpl_atomic.sys.ini -/language/en-GB/en-GB.tpl_beez3.ini -/language/en-GB/en-GB.tpl_beez3.sys.ini -/language/en-GB/en-GB.tpl_beez5.ini -/language/en-GB/en-GB.tpl_beez5.sys.ini -/language/en-GB/en-GB.tpl_beez_20.ini -/language/en-GB/en-GB.tpl_beez_20.sys.ini -/language/en-GB/en-GB.tpl_protostar.ini -/language/en-GB/en-GB.tpl_protostar.sys.ini -/language/en-GB/en-GB.xml -/language/en-GB/install.xml -/language/overrides/* -/language/index.html -/layouts/joomla/* -/layouts/libraries/* -/layouts/plugins/* -/layouts/index.html -/libraries/cms/* -/libraries/fof/* -/libraries/idna_convert/* -/libraries/joomla/* -/libraries/legacy/* -/libraries/php-encryption/* -/libraries/phpass/* -/libraries/phpmailer/* -/libraries/phputf8/* -/libraries/simplepie/* -/libraries/src/* -/libraries/vendor/* -/libraries/classmap.php -/libraries/cms.php -/libraries/import.legacy.php -/libraries/import.php -/libraries/index.html -/libraries/loader.php -/media/cms/* -/media/com_associations/* -/media/com_contact/* -/media/com_content/* -/media/com_contenthistory/* -/media/com_fields/* -/media/com_finder/* -/media/com_joomlaupdate/* -/media/com_menus/* -/media/com_modules/* -/media/com_wrapper/* -/media/contacts/* -/media/editors/* -/media/jui/* -/media/mailto/* -/media/media/* -/media/mod_languages/* -/media/mod_sampledata/* -/media/overrider/* -/media/plg_captcha_recaptcha/* -/media/plg_captcha_recaptcha_invisible/* -/media/plg_quickicon_extensionupdate/* -/media/plg_quickicon_joomlaupdate/* -/media/plg_quickicon_privacycheck/* -/media/plg_system_highlight/* -/media/plg_system_stats/* -/media/plg_twofactorauth_totp/* -/media/system/* -/media/index.html -/modules/mod_articles_archive/* -/modules/mod_articles_categories/* -/modules/mod_articles_category/* -/modules/mod_articles_latest/* -/modules/mod_articles_news/* -/modules/mod_articles_popular/* -/modules/mod_banners/* -/modules/mod_breadcrumbs/* -/modules/mod_custom/* -/modules/mod_feed/* -/modules/mod_finder/* -/modules/mod_footer/* -/modules/mod_languages/* -/modules/mod_login/* -/modules/mod_menu/* -/modules/mod_random_image/* -/modules/mod_related_items/* -/modules/mod_search/* -/modules/mod_stats/* -/modules/mod_syndicate/* -/modules/mod_tags_popular/* -/modules/mod_tags_similar/* -/modules/mod_users_latest/* -/modules/mod_whosonline/* -/modules/mod_wrapper/* -/modules/index.html -/plugins/actionlog/joomla/* -/plugins/authentication/cookie/* -/plugins/authentication/example/* -/plugins/authentication/gmail/* -/plugins/authentication/joomla/* -/plugins/authentication/ldap/* -/plugins/captcha/recaptcha/* -/plugins/captcha/recaptcha_invisible/* -/plugins/content/confirmconsent/* -/plugins/content/contact/* -/plugins/content/emailcloak/* -/plugins/content/example/* -/plugins/content/fields/* -/plugins/content/finder/* -/plugins/content/geshi/* -/plugins/content/joomla/* -/plugins/content/loadmodule/* -/plugins/content/pagebreak/* -/plugins/content/pagenavigation/* -/plugins/content/vote/* -/plugins/editors/codemirror/* -/plugins/editors/none/* -/plugins/editors/tinymce/* -/plugins/editors-xtd/article/* -/plugins/editors-xtd/contact/* -/plugins/editors-xtd/fields/* -/plugins/editors-xtd/image/* -/plugins/editors-xtd/menu/* -/plugins/editors-xtd/module/* -/plugins/editors-xtd/pagebreak/* -/plugins/editors-xtd/readmore/* -/plugins/extension/example/* -/plugins/extension/joomla/* -/plugins/fields/calendar/* -/plugins/fields/checkboxes/* -/plugins/fields/color/* -/plugins/fields/editor/* -/plugins/fields/imagelist/* -/plugins/fields/integer/* -/plugins/fields/list/* -/plugins/fields/media/* -/plugins/fields/radio/* -/plugins/fields/repeatable/* -/plugins/fields/sql/* -/plugins/fields/text/* -/plugins/fields/textarea/* -/plugins/fields/url/* -/plugins/fields/user/* -/plugins/fields/usergrouplist/* -/plugins/finder/categories/* -/plugins/finder/contacts/* -/plugins/finder/content/* -/plugins/finder/newsfeeds/* -/plugins/finder/tags/* -/plugins/installer/folderinstaller/* -/plugins/installer/packageinstaller/* -/plugins/installer/urlinstaller/* -/plugins/privacy/actionlogs/* -/plugins/privacy/consents/* -/plugins/privacy/contact/* -/plugins/privacy/content/* -/plugins/privacy/message/* -/plugins/privacy/user/* -/plugins/quickicon/extensionupdate/* -/plugins/quickicon/joomlaupdate/* -/plugins/quickicon/phpversioncheck/* -/plugins/quickicon/privacycheck/* -/plugins/quickicon/index.html -/plugins/sampledata/blog/* -/plugins/search/categories/* -/plugins/search/contacts/* -/plugins/search/content/* -/plugins/search/newsfeeds/* -/plugins/search/tags/* -/plugins/search/weblinks/* -/plugins/search/index.html -/plugins/system/actionlogs/* -/plugins/system/cache/* -/plugins/system/debug/* -/plugins/system/fields/* -/plugins/system/highlight/* -/plugins/system/languagecode/* -/plugins/system/languagefilter/* -/plugins/system/log/* -/plugins/system/logout/* -/plugins/system/logrotation/* -/plugins/system/p3p/* -/plugins/system/privacyconsent/* -/plugins/system/redirect/* -/plugins/system/remember/* -/plugins/system/sef/* -/plugins/system/sessiongc/* -/plugins/system/stats/* -/plugins/system/updatenotification/* -/plugins/system/index.html -/plugins/twofactorauth/totp/* -/plugins/twofactorauth/yubikey/* -/plugins/user/contactcreator/* -/plugins/user/example/* -/plugins/user/joomla/* -/plugins/user/profile/* -/plugins/user/terms/* -/plugins/user/index.html -/plugins/user/index.html -/plugins/index.html -/templates/beez3/* -/templates/protostar/* -/templates/system/* -/templates/index.html -/tmp/* -/configuration.php -/htaccess.txt -/index.php -/joomla.xml -/LICENSE.txt -/README.txt -/robots.txt.dist -/web.config.txt - -# ============================================================ -# Keep-empty folders helper -# ============================================================ -!.gitkeep -validation-reports/ -actionlint - -# ============================================================ -# Docker -# ============================================================ -# Local environment overrides — contain personal ports/volumes/credentials -docker-compose.override.yml -docker-compose.local.yml -.docker/ - -# ============================================================ -# Databases / SQLite -# ============================================================ -*.sqlite -*.sqlite3 -*.db -*.db3 -*.mdb -*.accdb - -# ============================================================ -# Terraform -# ============================================================ -# Local .terraform directories -**/.terraform/* - -# .tfstate files -*.tfstate -*.tfstate.* -*.tfstate.backup - -# Crash log files -crash.log -crash.*.log - -# Exclude all .tfvars files, which are likely to contain sensitive data -*.tfvars -*.tfvars.json - -# Ignore override files as they are usually used to override resources locally -override.tf -override.tf.json -*_override.tf -*_override.tf.json - -# Ignore CLI configuration files -.terraformrc -terraform.rc - -# Ignore plan files -*.tfplan -*.tfplan.* - -# Ignore lock file changes for now (uncomment to track lock file) -# Note: .terraform.lock.hcl should generally be committed for version control -# but can be ignored if you want flexibility across different platforms -# !.terraform.lock.hcl -logs/validation/*.md -profile.ps1 -.mcp.json +docs/ diff --git a/.mokogit/CLAUDE.md b/.mokogit/CLAUDE.md index 64187b5e..4f7dd11b 100644 --- a/.mokogit/CLAUDE.md +++ b/.mokogit/CLAUDE.md @@ -70,7 +70,7 @@ PHPStan runs with `--memory-limit=512M`. CI enforces PHPCS errors; PHPStan is `c - **Never commit** `.claude/`, `.mcp.json`, `TODO.md`, `*.min.css`/`*.min.js` - **Attribution**: `Authored-by: Moko Consulting` -- **Workflow directory**: `.mokogit/` (not `.gitea/` or `.github/`) +- **Workflow directory**: `.mokogit/` (not `.mokogit/` or `.github/`) - **Wiki**: documentation lives in the MokoGIT wiki, not `docs/` files - **New CLI tools**: extend `CliFramework`, not `CLIApp` (legacy) - **Standards**: [MokoCli](https://git.mokoconsulting.tech/MokoConsulting/mokocli/wiki/Home) diff --git a/.mokogit/branch-protection.yml b/.mokogit/branch-protection.yml index 9596ceaa..65fc843c 100644 --- a/.mokogit/branch-protection.yml +++ b/.mokogit/branch-protection.yml @@ -4,7 +4,7 @@ # DEFGROUP: Git.Workflow # INGROUP: mokocli.Automation # REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli -# PATH: /.gitea/workflows/branch-protection.yml +# PATH: /.mokogit/workflows/branch-protection.yml # BRIEF: Apply standardised branch protection rules to all governed repositories # # +========================================================================+ diff --git a/.mokogit/bulk-repo-sync.yml b/.mokogit/bulk-repo-sync.yml index a5ca78db..8783e842 100644 --- a/.mokogit/bulk-repo-sync.yml +++ b/.mokogit/bulk-repo-sync.yml @@ -4,7 +4,7 @@ # DEFGROUP: Git.Workflow # INGROUP: mokocli.Automation # REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli -# PATH: /.gitea/workflows/bulk-repo-sync.yml +# PATH: /.mokogit/workflows/bulk-repo-sync.yml # BRIEF: Bulk repo sync — runs from API repo, syncs standards to all governed repos name: Bulk Repository Sync diff --git a/.mokogit/pr-branch-check.yml b/.mokogit/pr-branch-check.yml index 2366cc95..b841d0a4 100644 --- a/.mokogit/pr-branch-check.yml +++ b/.mokogit/pr-branch-check.yml @@ -5,7 +5,7 @@ # DEFGROUP: mokocli.CI # INGROUP: mokocli # REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli -# PATH: /.gitea/workflows/pr-branch-check.yml +# PATH: /.mokogit/workflows/pr-branch-check.yml # BRIEF: PR branch merge policy enforcement # # Enforces branch merge policy: diff --git a/.mokogit/renovate.yml b/.mokogit/renovate.yml index daa6714d..2b3b3959 100644 --- a/.mokogit/renovate.yml +++ b/.mokogit/renovate.yml @@ -6,7 +6,7 @@ # DEFGROUP: Git.Workflow # INGROUP: mokocli.Automation # REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli -# PATH: /.gitea/workflows/renovate.yml +# PATH: /.mokogit/workflows/renovate.yml # BRIEF: Run Renovate Bot across all governed repos for dependency updates # # +========================================================================+ @@ -109,7 +109,7 @@ jobs: env: RENOVATE_TOKEN: ${{ secrets.MOKOGIT_TOKEN }} RENOVATE_PLATFORM: git - RENOVATE_ENDPOINT: ${{ env.GITEA_URL }}/api/v1 + RENOVATE_ENDPOINT: ${{ env.MOKOGIT_URL }}/api/v1 RENOVATE_GIT_AUTHOR: 'Renovate Bot ' RENOVATE_REPOSITORIES: ${{ steps.repos.outputs.repo_list }} RENOVATE_DRY_RUN: ${{ inputs.dry_run == 'true' && 'full' || 'null' }} diff --git a/.mokogit/sync-wikis.yml b/.mokogit/sync-wikis.yml index 69453815..975e124a 100644 --- a/.mokogit/sync-wikis.yml +++ b/.mokogit/sync-wikis.yml @@ -6,7 +6,7 @@ # DEFGROUP: Git.Workflow # INGROUP: mokocli.Maintenance # REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli -# PATH: /.gitea/workflows/sync-wikis.yml +# PATH: /.mokogit/workflows/sync-wikis.yml # BRIEF: Daily sync of all Git wikis to consolidated GitHub wiki repo name: Sync Wikis to GitHub @@ -32,7 +32,7 @@ jobs: - name: Sync all wikis env: GH_TOKEN: ${{ secrets.GH_PAT }} - GIT_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }} + GIT_URL: ${{ vars.MOKOGIT_URL || 'https://git.mokoconsulting.tech' }} run: | if [ -z "$GH_TOKEN" ]; then echo "::error::GH_TOKEN secret not set" diff --git a/.mokogit/workflows/auto-bump.yml b/.mokogit/workflows/auto-bump.yml index f74049c7..9230c5fb 100644 --- a/.mokogit/workflows/auto-bump.yml +++ b/.mokogit/workflows/auto-bump.yml @@ -22,7 +22,7 @@ on: env: FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true - MOKOGIT_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }} + MOKOGIT_URL: ${{ vars.MOKOGIT_URL || 'https://git.mokoconsulting.tech' }} permissions: contents: write diff --git a/.mokogit/workflows/auto-release.yml b/.mokogit/workflows/auto-release.yml index 40ad545b..23403007 100644 --- a/.mokogit/workflows/auto-release.yml +++ b/.mokogit/workflows/auto-release.yml @@ -52,9 +52,9 @@ on: env: FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true - MOKOGIT_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }} - GIT_ORG: ${{ vars.GITEA_ORG || github.repository_owner }} - GIT_REPO: ${{ vars.GITEA_REPO || github.event.repository.name }} + MOKOGIT_URL: ${{ vars.MOKOGIT_URL || 'https://git.mokoconsulting.tech' }} + GIT_ORG: ${{ vars.MOKOGIT_ORG || github.repository_owner }} + GIT_REPO: ${{ vars.MOKOGIT_REPO || github.event.repository.name }} permissions: contents: write diff --git a/.mokogit/workflows/branch-cleanup.yml b/.mokogit/workflows/branch-cleanup.yml index 183b1df9..19414494 100644 --- a/.mokogit/workflows/branch-cleanup.yml +++ b/.mokogit/workflows/branch-cleanup.yml @@ -36,7 +36,7 @@ jobs: env: MOKOGIT_TOKEN: ${{ secrets.MOKOGIT_TOKEN }} REPO: ${{ github.repository }} - API_BASE: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }} + API_BASE: ${{ vars.MOKOGIT_URL || 'https://git.mokoconsulting.tech' }} BRANCH: ${{ github.event.pull_request.head.ref }} run: | set -euo pipefail diff --git a/.mokogit/workflows/cascade-dev.yml b/.mokogit/workflows/cascade-dev.yml index b4c65e63..ddc9ebb3 100644 --- a/.mokogit/workflows/cascade-dev.yml +++ b/.mokogit/workflows/cascade-dev.yml @@ -27,7 +27,7 @@ permissions: pull-requests: write env: - MOKOGIT_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }} + MOKOGIT_URL: ${{ vars.MOKOGIT_URL || 'https://git.mokoconsulting.tech' }} # ntfy destination is configured via repo or org variables (org vars are inherited). NTFY_URL: ${{ vars.NTFY_URL || 'https://ntfy.mokoconsulting.tech' }} NTFY_TOPIC: ${{ vars.CASCADE_NTFY_TOPIC || vars.NTFY_TOPIC || 'git-releases' }} diff --git a/.mokogit/workflows/ci-issue-reporter.yml b/.mokogit/workflows/ci-issue-reporter.yml index cc6dc490..945c18db 100644 --- a/.mokogit/workflows/ci-issue-reporter.yml +++ b/.mokogit/workflows/ci-issue-reporter.yml @@ -51,14 +51,14 @@ jobs: env: MOKOGIT_TOKEN: ${{ secrets.MOKOGIT_TOKEN }} run: | - MOKOGIT_URL="${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}" + MOKOGIT_URL="${{ vars.MOKOGIT_URL || 'https://git.mokoconsulting.tech' }}" git clone --depth 1 --filter=blob:none --sparse "${MOKOGIT_URL}/MokoConsulting/mokocli.git" /tmp/mokocli cd /tmp/mokocli && git sparse-checkout set cli/ci_issue_reporter.sh - name: Report CI failure env: MOKOGIT_TOKEN: ${{ secrets.MOKOGIT_TOKEN }} - MOKOGIT_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }} + MOKOGIT_URL: ${{ vars.MOKOGIT_URL || 'https://git.mokoconsulting.tech' }} run: | chmod +x /tmp/mokocli/cli/ci_issue_reporter.sh /tmp/mokocli/cli/ci_issue_reporter.sh \ diff --git a/.mokogit/workflows/cleanup.yml b/.mokogit/workflows/cleanup.yml index 9c139315..9d97dbac 100644 --- a/.mokogit/workflows/cleanup.yml +++ b/.mokogit/workflows/cleanup.yml @@ -21,7 +21,7 @@ permissions: contents: write env: - MOKOGIT_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }} + MOKOGIT_URL: ${{ vars.MOKOGIT_URL || 'https://git.mokoconsulting.tech' }} jobs: cleanup: diff --git a/.mokogit/workflows/custom/ci-platform.yml b/.mokogit/workflows/custom/ci-platform.yml index 43e88277..474a5243 100644 --- a/.mokogit/workflows/custom/ci-platform.yml +++ b/.mokogit/workflows/custom/ci-platform.yml @@ -454,7 +454,7 @@ jobs: needs.templates.result == 'failure') env: MOKOGIT_TOKEN: ${{ secrets.MOKOGIT_TOKEN }} - MOKOGIT_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }} + MOKOGIT_URL: ${{ vars.MOKOGIT_URL || 'https://git.mokoconsulting.tech' }} run: | chmod +x automation/ci-issue-reporter.sh REPORTER="./automation/ci-issue-reporter.sh" diff --git a/.mokogit/workflows/custom/composer-publish.yml b/.mokogit/workflows/custom/composer-publish.yml index 4ecc97ce..20360ec9 100644 --- a/.mokogit/workflows/custom/composer-publish.yml +++ b/.mokogit/workflows/custom/composer-publish.yml @@ -13,7 +13,7 @@ on: workflow_dispatch: env: - MOKOGIT_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }} + MOKOGIT_URL: ${{ vars.MOKOGIT_URL || 'https://git.mokoconsulting.tech' }} jobs: publish: diff --git a/.mokogit/workflows/custom/self-update-runner.yml b/.mokogit/workflows/custom/self-update-runner.yml new file mode 100644 index 00000000..077f344a --- /dev/null +++ b/.mokogit/workflows/custom/self-update-runner.yml @@ -0,0 +1,58 @@ +# Copyright (C) 2026 Moko Consulting +# +# SPDX-License-Identifier: GPL-3.0-or-later +# +# CUSTOM WORKFLOW — lives in custom/ and is not managed by workflow sync. +# +# Keeps /opt/mokocli on the runner up to date with the latest main branch. +# Runs on schedule and when mokocli itself is released. + +name: "Custom: Self-Update Runner" + +on: + schedule: + - cron: '0 */6 * * *' + push: + branches: + - main + +env: + FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true + +jobs: + update: + name: Update /opt/mokocli on runner + runs-on: release + steps: + - name: Pull latest mokocli + run: | + TARGET="/opt/mokocli" + + if [ ! -d "${TARGET}/.git" ]; then + echo "Initial clone to ${TARGET}" + sudo rm -rf "${TARGET}" + sudo git clone --depth 1 --branch main \ + "https://x-access-token:${{ secrets.MOKOGIT_TOKEN }}@git.mokoconsulting.tech/MokoConsulting/mokocli.git" \ + "${TARGET}" + sudo chown -R "$(whoami)" "${TARGET}" + else + echo "Updating existing ${TARGET}" + cd "${TARGET}" + git fetch --depth 1 origin main + git reset --hard origin/main + fi + + - name: Install dependencies + run: | + cd /opt/mokocli + composer install --no-dev --no-interaction --quiet 2>/dev/null || true + + - name: Verify installation + run: | + if [ -f /opt/mokocli/cli/version_bump.php ] && [ -f /opt/mokocli/vendor/autoload.php ]; then + echo "mokocli updated successfully" + php /opt/mokocli/cli/version_bump.php --help 2>/dev/null | head -1 || echo "CLI available" + else + echo "::error::mokocli update failed — missing required files" + exit 1 + fi diff --git a/.mokogit/workflows/custom/sync-feature-versions.yml b/.mokogit/workflows/custom/sync-feature-versions.yml index a4f7b57b..d6692959 100644 --- a/.mokogit/workflows/custom/sync-feature-versions.yml +++ b/.mokogit/workflows/custom/sync-feature-versions.yml @@ -22,7 +22,7 @@ permissions: contents: write env: - MOKOGIT_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }} + MOKOGIT_URL: ${{ vars.MOKOGIT_URL || 'https://git.mokoconsulting.tech' }} jobs: sync: diff --git a/.mokogit/workflows/issue-branch.yml b/.mokogit/workflows/issue-branch.yml index e736ca81..67a5da22 100644 --- a/.mokogit/workflows/issue-branch.yml +++ b/.mokogit/workflows/issue-branch.yml @@ -19,7 +19,7 @@ permissions: issues: write env: - MOKOGIT_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }} + MOKOGIT_URL: ${{ vars.MOKOGIT_URL || 'https://git.mokoconsulting.tech' }} jobs: create-branch: diff --git a/.mokogit/workflows/pr-check.yml b/.mokogit/workflows/pr-check.yml index 0e3b0fb9..e4ae87e9 100644 --- a/.mokogit/workflows/pr-check.yml +++ b/.mokogit/workflows/pr-check.yml @@ -146,7 +146,7 @@ jobs: - name: Remind to update the wiki env: TOKEN: ${{ secrets.MOKOGIT_TOKEN }} - SERVER: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }} + SERVER: ${{ vars.MOKOGIT_URL || 'https://git.mokoconsulting.tech' }} REPO: ${{ github.repository }} PR: ${{ github.event.pull_request.number }} run: | @@ -581,7 +581,7 @@ jobs: MOKOGIT_TOKEN: ${{ secrets.MOKOGIT_TOKEN }} REPO: ${{ github.repository }} BRANCH: ${{ github.head_ref }} - MOKOGIT_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }} + MOKOGIT_URL: ${{ vars.MOKOGIT_URL || 'https://git.mokoconsulting.tech' }} run: | curl -s -X POST "${MOKOGIT_URL}/api/v1/repos/${REPO}/actions/workflows/pre-release.yml/dispatches" -H "Authorization: token ${MOKOGIT_TOKEN}" -H "Content-Type: application/json" -d "{\"ref\":\"${BRANCH}\",\"inputs\":{\"stability\":\"release-candidate\"}}" echo "### Pre-Release" >> $GITHUB_STEP_SUMMARY diff --git a/.mokogit/workflows/pre-release.yml b/.mokogit/workflows/pre-release.yml index f03dabac..e0e885bc 100644 --- a/.mokogit/workflows/pre-release.yml +++ b/.mokogit/workflows/pre-release.yml @@ -40,9 +40,9 @@ permissions: contents: write env: - GIT_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }} - GIT_ORG: ${{ vars.GITEA_ORG || github.repository_owner }} - GIT_REPO: ${{ vars.GITEA_REPO || github.event.repository.name }} + GIT_URL: ${{ vars.MOKOGIT_URL || 'https://git.mokoconsulting.tech' }} + GIT_ORG: ${{ vars.MOKOGIT_ORG || github.repository_owner }} + GIT_REPO: ${{ vars.MOKOGIT_REPO || github.event.repository.name }} jobs: build: diff --git a/.mokogit/workflows/rc-revert.yml b/.mokogit/workflows/rc-revert.yml index 4f10784c..88a3bbff 100644 --- a/.mokogit/workflows/rc-revert.yml +++ b/.mokogit/workflows/rc-revert.yml @@ -33,7 +33,7 @@ jobs: env: BRANCH: ${{ github.event.pull_request.head.ref }} REPO: ${{ github.repository }} - GIT_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }} + GIT_URL: ${{ vars.MOKOGIT_URL || 'https://git.mokoconsulting.tech' }} TOKEN: ${{ secrets.MOKOGIT_TOKEN }} run: | set -euo pipefail diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c0b4858b..af4549d6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -34,8 +34,7 @@ feature/* ──PR──> dev ──draft PR──> (renamed to rc) ──merge 7. **Merging to main** triggers the stable release pipeline: - Minor version bump (e.g., `02.09.xx` → `02.10.00`) - Stability suffix stripped (clean version) - - Gitea release created with ZIP/tar.gz packages - - `updates.xml` updated (Joomla extensions) + - MokoGit release created with ZIP/tar.gz packages - `dev` branch recreated from `main` ### Branch summary @@ -119,7 +118,7 @@ This ensures Joomla sites on ANY stability channel see the update (Joomla only s The version tools update all files containing version stamps: -- `.mokogitea/manifest.xml` (canonical source) +- `.mokogit/manifest.xml` (canonical source) - Joomla XML manifests (`` tag) - `README.md`, `CHANGELOG.md` (`VERSION:` pattern) - `package.json`, `pyproject.toml` diff --git a/README.md b/README.md index 023e28ec..994c35f1 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ BRIEF: Project overview and documentation PHP implementation of mokocli — enterprise standards, automation framework, workflow templates, and bulk sync tooling. -> **Primary platform**: [Gitea — git.mokoconsulting.tech](https://git.mokoconsulting.tech/MokoConsulting/MokoCli-API) +> **Primary platform**: [MokoGit — git.mokoconsulting.tech](https://git.mokoconsulting.tech/MokoConsulting/MokoCli-API) > **Backup mirror**: [GitHub](https://github.com/MokoConsulting/MokoCli-API) *(read-only mirror)* ## What Lives Here @@ -25,7 +25,7 @@ PHP implementation of mokocli — enterprise standards, automation framework, wo |-----------|---------| | `lib/Enterprise/` | 38 PHP enterprise library classes (platform adapters, sync, validation, plugins) | | `cli/` | CLI scripts (archive, create, release, sync rulesets, version management) | -| `automation/` | Bulk sync, push files, repo cleanup, Gitea migration | +| `automation/` | Bulk sync, push files, repo cleanup, MokoGit migration | | `validate/` | 18 validation scripts (health, structure, secrets, syntax, drift) | | `templates/` | **Workflow templates** and config templates synced to governed repos | | `definitions/` | Repository structure definitions (`.tf` format) | @@ -42,7 +42,7 @@ composer require mokoconsulting-tech/enterprise ### Composer Registry -This package is served from Gitea package registry. Add this to your `composer.json`: +This package is served from MokoGit package registry. Add this to your `composer.json`: ```json { @@ -72,11 +72,11 @@ vendor/bin/moko inventory -- --path . | Variable | Purpose | |----------|---------| -| `GIT_PLATFORM` | `gitea` (default) or `github` | -| `GA_TOKEN` | Gitea API / Gitea Actions token | +| `GIT_PLATFORM` | `mokogit` (default) or `github` | +| `GA_TOKEN` | MokoGit API / MokoGit Actions token | | `GH_TOKEN` | GitHub API token (for mirror sync) | -| `GITEA_URL` | Gitea instance URL (default: `https://git.mokoconsulting.tech`) | -| `GITEA_ORG` | Gitea organization (default: `MokoConsulting`) | +| `MOKOGIT_URL` | MokoGit instance URL (default: `https://git.mokoconsulting.tech`) | +| `MOKOGIT_ORG` | MokoGit organization (default: `MokoConsulting`) | ## License diff --git a/automation/bulk_joomla_template.php b/automation/bulk_joomla_template.php index 496eabda..efc58851 100644 --- a/automation/bulk_joomla_template.php +++ b/automation/bulk_joomla_template.php @@ -45,7 +45,7 @@ use MokoCli\{ * --sync: Push mokocli files to existing template repositories * --list: List all repositories tagged as joomla-template * - * Works with both GitHub and Gitea via the PlatformAdapterFactory. + * Works with both GitHub and MokoGit via the PlatformAdapterFactory. */ class BulkJoomlaTemplate extends CliFramework { @@ -66,7 +66,6 @@ class BulkJoomlaTemplate extends CliFramework $this->addArgument('--client', 'Joomla client: site or admin', 'site'); $this->addArgument('--repos', 'Target repos (comma-separated)', ''); $this->addArgument('--all', 'Sync all tagged repos', false); - $this->addArgument('--sync-updates', 'Sync updates.xml', false); $this->addArgument('--private', 'Create as private repo', false); $this->addArgument('--yes', 'Auto-confirm', false); } @@ -100,11 +99,7 @@ class BulkJoomlaTemplate extends CliFramework return $this->syncTemplates($org); } - if ($this->getArgument('--sync-updates', false)) { - return $this->syncUpdatesBetweenPlatforms($org); - } - - $this->log("❌ Specify --scaffold, --sync, --sync-updates, or --list", 'ERROR'); + $this->log("❌ Specify --scaffold, --sync, or --list", 'ERROR'); return 1; } @@ -376,7 +371,6 @@ class BulkJoomlaTemplate extends CliFramework { $files = [ 'templateDetails.xml', - 'updates.xml', 'src/index.php', 'src/error.php', 'src/offline.php', @@ -461,10 +455,7 @@ class BulkJoomlaTemplate extends CliFramework - https://git.mokoconsulting.tech/{$org}/{$name}/raw/branch/main/updates.xml - - - https://raw.githubusercontent.com/{$org}/{$name}/main/updates.xml + https://git.mokoconsulting.tech/{$org}/{$name}/updates.xml @@ -486,30 +477,6 @@ class BulkJoomlaTemplate extends CliFramework XML; $files['templateDetails.xml'] = preg_replace('/^\t\t/m', '', $files['templateDetails.xml']); - // updates.xml — dual-platform download URLs (Gitea primary, GitHub secondary) - $files['updates.xml'] = << - - {$name} - {$name} — Moko Consulting Joomla template - tpl_{$shortName} - template - 1.0.0 - - - https://git.mokoconsulting.tech/{$org}/{$name}/releases/download/v1.0.0/{$shortName}.zip - - - https://github.com/{$org}/{$name}/releases/download/v1.0.0/{$shortName}.zip - - - - 8.1 - - - XML; - $files['updates.xml'] = preg_replace('/^\t\t/m', '', $files['updates.xml']); - // src/index.php $files['src/index.php'] = <<<'PHP' tag, - * and pushes the newer one to the stale platform. - * - * Designed to be called from a CI workflow via: - * php automation/bulk_joomla_template.php --sync-updates --repos=MokoCassiopeia - */ - private function syncUpdatesBetweenPlatforms(string $org): int - { - $repos = []; - - if ($this->getArgument('--all', false)) { - $repos = $this->findTemplateRepos($org); - // Also include waas-component repos - $allRepos = $this->adapter->listOrgRepos($org, true); - foreach ($allRepos as $repo) { - try { - $topics = $this->adapter->getRepoTopics($org, $repo['name']); - if (in_array('joomla', $topics, true) || in_array('joomla-extension', $topics, true)) { - $repos[] = $repo; - } - } catch (\Exception $e) { - $this->adapter->getApiClient()->resetCircuitBreaker(); - } - } - // Deduplicate - $seen = []; - $repos = array_filter($repos, function ($r) use (&$seen) { - if (isset($seen[$r['name']])) { - return false; - } - $seen[$r['name']] = true; - return true; - }); - } else { - $reposArg = $this->getArgument('--repos', ''); - if (empty($reposArg)) { - $this->log("❌ --repos or --all required for --sync-updates", 'ERROR'); - return 1; - } - $names = array_filter(array_map('trim', explode(',', $reposArg))); - foreach ($names as $name) { - $repos[] = ['name' => $name]; - } - } - - if (empty($repos)) { - $this->log("No Joomla repositories to sync updates for", 'INFO'); - return 0; - } - - // Create both platform adapters - try { - $adapters = PlatformAdapterFactory::createBoth($this->config); - } catch (\Exception $e) { - $this->log("❌ Both platform tokens required for --sync-updates: " . $e->getMessage(), 'ERROR'); - return 1; - } - - $gitea = $adapters['gitea']; - $github = $adapters['github']; - $dryRun = $this->dryRun; - - $this->log("\nSyncing updates.xml across Gitea <-> GitHub for " . count($repos) . " repo(s)...", 'INFO'); - - $synced = 0; - $failed = 0; - - foreach ($repos as $repo) { - $name = $repo['name']; - $this->log("\n[{$name}]", 'INFO'); - - // Try both updates.xml and updates.xml filenames - $updateFile = $this->resolveUpdateFile($gitea, $github, $org, $name); - if ($updateFile === null) { - $this->log(" ⊘ No update(s).xml found on either platform", 'INFO'); - continue; - } - - $fileName = $updateFile['name']; - $source = $updateFile['source']; // 'gitea' or 'github' - $content = $updateFile['content']; - $target = $source === 'gitea' ? 'github' : 'gitea'; - $targetAdapter = $source === 'gitea' ? $github : $gitea; - - $this->log(" Source: {$source} ({$fileName})", 'INFO'); - - if ($dryRun) { - $this->log(" (dry-run) Would push {$fileName} to {$target}", 'INFO'); - $synced++; - continue; - } - - // Push to the other platform - try { - $existingSha = null; - try { - $existing = $targetAdapter->getFileContents($org, $name, $fileName); - $existingSha = $existing['sha'] ?? null; - - // Compare content — skip if identical - $existingContent = base64_decode($existing['content'] ?? ''); - if (trim($existingContent) === trim($content)) { - $this->log(" ✓ Already in sync", 'INFO'); - $synced++; - continue; - } - } catch (\Exception $e) { - $targetAdapter->getApiClient()->resetCircuitBreaker(); - } - - $targetAdapter->createOrUpdateFile( - $org, - $name, - $fileName, - $content, - "chore: sync {$fileName} from {$source}", - $existingSha - ); - $this->log(" ✓ Pushed to {$target}", 'INFO'); - $synced++; - } catch (\Exception $e) { - $this->log(" ✗ Failed to push to {$target}: " . $e->getMessage(), 'ERROR'); - $targetAdapter->getApiClient()->resetCircuitBreaker(); - $failed++; - } - } - - $this->log("\n" . str_repeat('=', 50), 'INFO'); - $this->log("Updates sync complete: {$synced} synced, {$failed} failed", 'INFO'); - - return $failed > 0 ? 1 : 0; - } - - /** - * Find the updates file on both platforms, return the one with the higher version. - * - * Checks both `updates.xml` and `updates.xml` filenames. - * Returns the content from the platform with the newer . - * Gitea wins ties (primary platform). - * - * @return array{name: string, source: string, content: string}|null - */ - private function resolveUpdateFile( - GitPlatformAdapter $gitea, - GitPlatformAdapter $github, - string $org, - string $name - ): ?array { - $candidates = ['updates.xml', 'updates.xml']; - $found = []; // platform => [name, content, version] - - foreach (['gitea' => $gitea, 'github' => $github] as $platform => $adapter) { - foreach ($candidates as $fileName) { - try { - $file = $adapter->getFileContents($org, $name, $fileName); - $content = base64_decode($file['content'] ?? ''); - - // Extract latest version from the XML - $version = '0.0.0'; - if (preg_match('/([^<]+)<\/version>/', $content, $m)) { - $version = trim($m[1]); - } - - $found[$platform] = [ - 'name' => $fileName, - 'content' => $content, - 'version' => $version, - ]; - break; // Found one — stop checking other filenames for this platform - } catch (\Exception $e) { - $adapter->getApiClient()->resetCircuitBreaker(); - } - } - } - - if (empty($found)) { - return null; - } - - // If only one platform has it, that's the source - if (count($found) === 1) { - $platform = array_key_first($found); - return [ - 'name' => $found[$platform]['name'], - 'source' => $platform, - 'content' => $found[$platform]['content'], - ]; - } - - // Both have it — pick the one with the higher version (Gitea wins ties) - $giteaVer = $found['gitea']['version']; - $githubVer = $found['github']['version']; - - $source = version_compare($githubVer, $giteaVer, '>') ? 'github' : 'gitea'; - - return [ - 'name' => $found[$source]['name'], - 'source' => $source, - 'content' => $found[$source]['content'], - ]; - } } // Execute if run directly diff --git a/automation/bulk_sync.php b/automation/bulk_sync.php index efcedd33..02d2ecfb 100755 --- a/automation/bulk_sync.php +++ b/automation/bulk_sync.php @@ -574,12 +574,12 @@ class BulkSync extends CliFramework */ private function writeStepSummary(array $results): void { - // Check both GitHub and Gitea step summary env vars + // Check both GitHub and MokoGit step summary env vars $summaryFile = getenv($this->adapter->getStepSummaryEnvVar()); if (empty($summaryFile)) { // Fallback: also check the other platform's env var $fallback = $this->adapter->getPlatformName() === 'github' - ? getenv('GITEA_STEP_SUMMARY') + ? getenv('MOKOGIT_STEP_SUMMARY') : getenv('GITHUB_STEP_SUMMARY'); $summaryFile = $fallback ?: ''; } @@ -719,7 +719,7 @@ class BulkSync extends CliFramework $score = 0; $max = 0; - // 1. Check branch protection rules (rulesets on GitHub, branch_protections on Gitea) + // 1. Check branch protection rules (rulesets on GitHub, branch_protections on MokoGit) $max += 20; try { $protections = $this->adapter->listBranchProtections($org, $name); @@ -1080,7 +1080,7 @@ class BulkSync extends CliFramework * trail of what was changed and why. */ /** - * Resolve label names to their integer IDs for the Gitea API. + * Resolve label names to their integer IDs for the MokoGit API. * Creates missing labels automatically. * * @param string $org Organization name diff --git a/automation/bulk_workflow_trigger.sh b/automation/bulk_workflow_trigger.sh index c63032d6..7ec4f8fb 100644 --- a/automation/bulk_workflow_trigger.sh +++ b/automation/bulk_workflow_trigger.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # Copyright (C) 2026 Moko Consulting # SPDX-License-Identifier: GPL-3.0-or-later -# BRIEF: Trigger a workflow across all client-waas repos in a Gitea org +# BRIEF: Trigger a workflow across all client-waas repos in a MokoGit org set -euo pipefail @@ -10,11 +10,11 @@ set -euo pipefail # --------------------------------------------------------------------------- usage() { cat </dev/null || echo "000") if [[ "$exists" == "200" ]]; then # Check if label already exists local found found=$(curl -sf \ - -H "Authorization: token ${GITEA_TOKEN}" \ + -H "Authorization: token ${MOKOGIT_TOKEN}" \ "${API}/labels" 2>/dev/null \ | grep -o "\"name\":\"${LABEL_NAME}\"" || true) if [[ -z "$found" ]]; then curl -sf -X POST \ - -H "Authorization: token ${GITEA_TOKEN}" \ + -H "Authorization: token ${MOKOGIT_TOKEN}" \ -H "Content-Type: application/json" \ "${API}/labels" \ -d "{\"name\":\"${LABEL_NAME}\",\"color\":\"${LABEL_COLOR}\",\"description\":\"Auto-created by CI issue reporter\"}" \ @@ -114,7 +114,7 @@ find_existing_issue() { local response response=$(curl -sf \ - -H "Authorization: token ${GITEA_TOKEN}" \ + -H "Authorization: token ${MOKOGIT_TOKEN}" \ "${API}/issues?type=issues&state=open&labels=${LABEL_NAME}&q=${query}&limit=5" \ 2>/dev/null || echo "[]") @@ -151,7 +151,7 @@ ${DETAILS} Fix the issue described above and push a new commit. This issue will be closed automatically when the gate passes, or can be closed manually. --- -*Auto-created by [ci-issue-reporter](${GITEA_URL}/${REPO}/src/branch/main/automation/ci-issue-reporter.sh)* +*Auto-created by [ci-issue-reporter](${MOKOGIT_URL}/${REPO}/src/branch/main/automation/ci-issue-reporter.sh)* BODY } @@ -181,7 +181,7 @@ import sys, json print(json.dumps({'body': sys.stdin.read()}))" 2>/dev/null) HTTP=$(curl -sf -o /dev/null -w '%{http_code}' -X POST \ - -H "Authorization: token ${GITEA_TOKEN}" \ + -H "Authorization: token ${MOKOGIT_TOKEN}" \ -H "Content-Type: application/json" \ "${API}/issues/${EXISTING}/comments" \ -d "${COMMENT_JSON}" 2>/dev/null || echo "000") @@ -205,7 +205,7 @@ print(json.dumps({ # Create the issue RESPONSE=$(curl -sf -X POST \ - -H "Authorization: token ${GITEA_TOKEN}" \ + -H "Authorization: token ${MOKOGIT_TOKEN}" \ -H "Content-Type: application/json" \ "${API}/issues" \ -d "${ISSUE_JSON}" 2>/dev/null || echo "{}") @@ -213,16 +213,16 @@ print(json.dumps({ ISSUE_NUM=$(echo "$RESPONSE" | grep -oP '"number":\s*\K[0-9]+' | head -1) if [[ -n "$ISSUE_NUM" ]]; then - # Apply label (separate call — more reliable across Gitea versions) + # Apply label (separate call — more reliable across MokoGit versions) LABEL_ID=$(curl -sf \ - -H "Authorization: token ${GITEA_TOKEN}" \ + -H "Authorization: token ${MOKOGIT_TOKEN}" \ "${API}/labels" 2>/dev/null \ | grep -oP "\"id\":\s*\K[0-9]+(?=[^}]*\"name\":\s*\"${LABEL_NAME}\")" \ | head -1 || true) if [[ -n "$LABEL_ID" ]]; then curl -sf -X POST \ - -H "Authorization: token ${GITEA_TOKEN}" \ + -H "Authorization: token ${MOKOGIT_TOKEN}" \ -H "Content-Type: application/json" \ "${API}/issues/${ISSUE_NUM}/labels" \ -d "{\"labels\":[${LABEL_ID}]}" \ diff --git a/automation/enforce_tags.sh b/automation/enforce_tags.sh index 9d4f329e..7ca560a0 100755 --- a/automation/enforce_tags.sh +++ b/automation/enforce_tags.sh @@ -12,8 +12,8 @@ # ============================================================================= set -euo pipefail -GITEA_URL="${GITEA_URL:-https://git.mokoconsulting.tech}" -ORG="${GITEA_ORG:-MokoConsulting}" +MOKOGIT_URL="${MOKOGIT_URL:-https://git.mokoconsulting.tech}" +ORG="${MOKOGIT_ORG:-MokoConsulting}" TOKEN="${GA_TOKEN:?GA_TOKEN required}" DRY_RUN=false FILTER_REPOS="" @@ -32,7 +32,7 @@ api() { local method="$1" path="$2" data="${3:-}" local args=(-sf -H "Authorization: token $TOKEN" -H "Content-Type: application/json" -X "$method") [[ -n "$data" ]] && args+=(-d "$data") - curl "${args[@]}" "$GITEA_URL/api/v1$path" 2>/dev/null + curl "${args[@]}" "$MOKOGIT_URL/api/v1$path" 2>/dev/null } # Get repos diff --git a/automation/enrich_manifest_xml.php b/automation/enrich_manifest_xml.php deleted file mode 100644 index 0f82a7bd..00000000 --- a/automation/enrich_manifest_xml.php +++ /dev/null @@ -1,481 +0,0 @@ -#!/usr/bin/env php - - * SPDX-License-Identifier: GPL-3.0-or-later - * - * FILE INFORMATION - * DEFGROUP: MokoPlatform.Automation - * INGROUP: MokoPlatform - * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli - * PATH: /automation/enrich_manifest_xml.php - * BRIEF: Enrich XML manifests with repo-specific build and deploy details - * - * Note: This script uses proc_open for shell commands. All arguments are escaped - * via escapeshellarg(). No user-supplied input reaches the shell unescaped. - */ - -declare(strict_types=1); - -require_once __DIR__ . '/../vendor/autoload.php'; -require_once __DIR__ . '/../lib/Enterprise/CliFramework.php'; - -use MokoCli\CliFramework; -use MokoCli\ManifestParser; - -class EnrichManifestXmlCli extends CliFramework -{ - protected function configure(): void - { - $this->setDescription('Enrich XML manifests with repo-specific build and deploy details'); - $this->addArgument('--repo', 'Filter to a single repo name', ''); - $this->addArgument('--skip', 'Comma-separated list of repos to skip', ''); - } - - protected function run(): int - { - $giteaUrl = rtrim(getenv('GITEA_URL') ?: 'https://git.mokoconsulting.tech', '/'); - $giteaOrg = getenv('GITEA_ORG') ?: 'MokoConsulting'; - $token = getenv('GA_TOKEN') ?: getenv('GH_TOKEN') ?: ''; - - $repoFilter = $this->getArgument('--repo') ?: null; - $skipStr = $this->getArgument('--skip'); - $skipRepos = $skipStr !== '' ? array_map('trim', explode(',', $skipStr)) : []; - - $parser = new ManifestParser(); - $tmpBase = sys_get_temp_dir() . '/moko-enrich-' . getmypid(); - - echo "=== mokocli XML Manifest Enrichment ===\n"; - echo "Mode: " . ($this->dryRun ? "DRY RUN" : "LIVE") . "\n"; - if (!empty($skipRepos)) { - echo "Skipping: " . implode(', ', $skipRepos) . "\n"; - } - echo "\n"; - - if (empty($token)) { - $this->log('ERROR', 'GA_TOKEN required'); - return 1; - } - - $repos = $this->fetchRepos($giteaUrl, $giteaOrg, $token); - echo "Found " . count($repos) . " repositories\n\n"; - - $stats = ['enriched' => 0, 'skipped' => 0, 'failed' => 0]; - - foreach ($repos as $repo) { - $name = $repo['name']; - if ($repoFilter && $name !== $repoFilter) { - continue; - } - if (in_array($name, $skipRepos, true)) { - echo " {$name} ... SKIP (excluded)\n"; - $stats['skipped']++; - continue; - } - if ($repo['archived'] ?? false) { - $stats['skipped']++; - continue; - } - - $defaultBranch = $repo['default_branch'] ?? 'main'; - $httpsUrl = $repo['clone_url'] ?? "{$giteaUrl}/{$giteaOrg}/{$name}.git"; - $authedUrl = preg_replace('#^https://#', "https://gitea-actions:{$token}@", $httpsUrl); - - echo " {$name} ... "; - - $workDir = "{$tmpBase}/{$name}"; - @mkdir($workDir, 0755, true); - [$ret] = $this->safeExec( - 'git clone --depth 1 --branch ' . escapeshellarg($defaultBranch) - . ' ' . escapeshellarg($authedUrl) . ' ' . escapeshellarg($workDir) - ); - if ($ret !== 0) { - echo "FAIL (clone)\n"; - $stats['failed']++; - continue; - } - - $manifestPath = "{$workDir}/.mokogitea/manifest.xml"; - if (!file_exists($manifestPath) || !str_contains(file_get_contents($manifestPath), 'rmTree($workDir); - continue; - } - - $existingXml = file_get_contents($manifestPath); - $platform = $parser->extractPlatform($existingXml) ?? 'default-repository'; - $enrichment = $this->inspectRepo($workDir, $platform); - - if (!isset($enrichment['build'])) { - $enrichment['build'] = []; - } - $enrichment['build']['language'] = $enrichment['build']['language'] - ?? $repo['language'] - ?? ManifestParser::platformLanguage($platform); - $enrichment['build']['package_type'] = $enrichment['build']['package_type'] ?? ManifestParser::platformPackageType($platform); - - $enrichedXml = $this->enrichManifestXml($existingXml, $enrichment); - $dc = count($enrichment['deploy'] ?? []); - $sc = count($enrichment['scripts'] ?? []); - $details = "deploy={$dc} scripts={$sc}"; - - if ($this->dryRun) { - echo "WOULD ENRICH [{$details}]\n"; - $stats['enriched']++; - $this->rmTree($workDir); - continue; - } - - file_put_contents($manifestPath, $enrichedXml); - $this->gitCmd($workDir, 'config', 'user.name', 'gitea-actions[bot]'); - $this->gitCmd($workDir, 'config', 'user.email', 'gitea-actions[bot]@git.mokoconsulting.tech'); - $this->gitCmd($workDir, 'add', '.mokogitea/manifest.xml'); - - [$cr, $co] = $this->gitCmd($workDir, 'commit', '-m', "chore: enrich manifest.xml with build/deploy/scripts\n\nAuto-detected: {$details}"); - if ($cr !== 0) { - echo "SKIP (no diff)\n"; - $stats['skipped']++; - $this->rmTree($workDir); - continue; - } - - [$pr] = $this->gitCmd($workDir, 'push', 'origin', $defaultBranch); - if ($pr !== 0) { - echo "FAIL (push)\n"; - $stats['failed']++; - } else { - echo "ENRICHED [{$details}]\n"; - $stats['enriched']++; - } - - $this->rmTree($workDir); - } - - @rmdir($tmpBase); - echo "\n=== Summary ===\nEnriched: {$stats['enriched']}\nSkipped: {$stats['skipped']}\nFailed: {$stats['failed']}\n"; - - return 0; - } - - private function inspectRepo(string $workDir, string $platform): array - { - $enrichment = []; - $build = []; - - // Detect entry point - if (is_dir("{$workDir}/src")) { - foreach (glob("{$workDir}/src/*.xml") ?: [] as $xf) { - $c = file_get_contents($xf); - if (str_contains($c, ' $pd, 'version' => $composer['require'][$pd], 'type' => 'platform']; - } - } - if (isset($composer['require']['mokoconsulting-tech/enterprise'])) { - $deps[] = [ - 'name' => 'mokoconsulting-tech/enterprise', - 'version' => $composer['require']['mokoconsulting-tech/enterprise'], - 'type' => 'composer', - ]; - } - if (!empty($deps)) { - $build['dependencies'] = $deps; - } - } - - // Artifact from Makefile - if (file_exists("{$workDir}/Makefile")) { - $mk = file_get_contents("{$workDir}/Makefile"); - if (preg_match('/\bdist\/(\S+\.zip)\b/', $mk, $m)) { - $build['artifact'] = ['format' => 'zip', 'path' => 'dist/', 'filename' => $m[1]]; - } - } - - if (!empty($build)) { - $enrichment['build'] = $build; - } - - // Deploy targets from workflows - $targets = []; - $wfDir = is_dir("{$workDir}/.gitea/workflows") ? "{$workDir}/.gitea/workflows" : "{$workDir}/.github/workflows"; - if (is_dir($wfDir)) { - foreach (['deploy-dev', 'deploy-demo', 'deploy-rs'] as $dn) { - $wf = "{$wfDir}/{$dn}.yml"; - if (!file_exists($wf)) { - continue; - } - $wc = file_get_contents($wf); - $t = ['name' => str_replace('deploy-', '', $dn)]; - if (str_contains($wc, 'sftp') || str_contains($wc, 'SFTP')) { - $t['method'] = 'sftp'; - } elseif (str_contains($wc, 'rsync')) { - $t['method'] = 'rsync'; - } - if (str_contains($wc, 'src/')) { - $t['src_dir'] = 'src/'; - } - if (preg_match('/branches:\s*\n\s*-\s*["\']?([^"\'}\s]+)/', $wc, $m)) { - $t['branch'] = $m[1]; - } - $targets[] = $t; - } - } - if (!empty($targets)) { - $enrichment['deploy'] = $targets; - } - - // Scripts from Makefile + composer - $scripts = []; - if (file_exists("{$workDir}/Makefile")) { - $mk = file_get_contents("{$workDir}/Makefile"); - $known = [ - 'build' => 'build', 'test' => 'test', 'lint' => 'lint', - 'clean' => 'build', 'package' => 'build', - 'validate' => 'validate', 'release' => 'release', - ]; - if (preg_match_all('/^([a-zA-Z_-]+)\s*:/m', $mk, $matches)) { - foreach ($matches[1] as $tgt) { - $tl = strtolower($tgt); - if (isset($known[$tl])) { - $scripts[] = [ - 'name' => $tl, 'phase' => $known[$tl], - 'command' => "make {$tgt}", - 'desc' => ucfirst($tl) . ' via make', - 'runner' => 'make', - ]; - } - } - } - } - if (file_exists("{$workDir}/composer.json")) { - $composer = json_decode(file_get_contents("{$workDir}/composer.json"), true) ?: []; - $km = ['test' => 'test','lint' => 'lint','cs' => 'lint','phpcs' => 'lint','phpstan' => 'lint','validate' => 'validate']; - foreach ($composer['scripts'] ?? [] as $sn => $cmd) { - $sl = strtolower($sn); - foreach ($km as $match => $phase) { - if (str_contains($sl, $match)) { - $exists = false; - foreach ($scripts as $s) { - if ($s['name'] === $sl) { - $exists = true; - break; - } - } - if (!$exists) { - $scripts[] = [ - 'name' => $sn, 'phase' => $phase, - 'command' => "composer run {$sn}", - 'desc' => is_string($cmd) ? $cmd : "Run {$sn}", - 'runner' => 'composer', - ]; - } - break; - } - } - } - } - if (!empty($scripts)) { - $enrichment['scripts'] = $scripts; - } - - return $enrichment; - } - - private function enrichManifestXml(string $xml, array $enrichment): string - { - $dom = new \DOMDocument('1.0', 'UTF-8'); - $dom->preserveWhiteSpace = false; - $dom->formatOutput = true; - if (!$dom->loadXML($xml)) { - return $xml; - } - - $ns = ManifestParser::NAMESPACE_URI; - $root = $dom->documentElement; - - foreach (['build', 'deploy', 'scripts'] as $tag) { - $toRemove = []; - $existing = $root->getElementsByTagNameNS($ns, $tag); - for ($i = 0; $i < $existing->length; $i++) { - $toRemove[] = $existing->item($i); - } - foreach ($toRemove as $node) { - $root->removeChild($node); - } - } - - if (!empty($enrichment['build'])) { - $buildEl = $dom->createElementNS($ns, 'build'); - $b = $enrichment['build']; - foreach (['language', 'runtime'] as $f) { - if (isset($b[$f])) { - $buildEl->appendChild($dom->createElementNS($ns, $f, htmlspecialchars($b[$f], ENT_XML1))); - } - } - if (isset($b['package_type'])) { - $buildEl->appendChild($dom->createElementNS($ns, 'package-type', htmlspecialchars($b['package_type'], ENT_XML1))); - } - if (isset($b['entry_point'])) { - $buildEl->appendChild($dom->createElementNS($ns, 'entry-point', htmlspecialchars($b['entry_point'], ENT_XML1))); - } - if (isset($b['artifact'])) { - $art = $dom->createElementNS($ns, 'artifact'); - foreach (['format','path','filename'] as $af) { - if (isset($b['artifact'][$af])) { - $art->appendChild($dom->createElementNS($ns, $af, htmlspecialchars($b['artifact'][$af], ENT_XML1))); - } - } - $buildEl->appendChild($art); - } - if (isset($b['dependencies'])) { - $deps = $dom->createElementNS($ns, 'dependencies'); - foreach ($b['dependencies'] as $d) { - $req = $dom->createElementNS($ns, 'requires', ''); - $req->setAttribute('name', $d['name']); - if (isset($d['version'])) { - $req->setAttribute('version', $d['version']); - } - if (isset($d['type'])) { - $req->setAttribute('type', $d['type']); - } - $deps->appendChild($req); - } - $buildEl->appendChild($deps); - } - $root->appendChild($buildEl); - } - - if (!empty($enrichment['deploy'])) { - $deploy = $dom->createElementNS($ns, 'deploy'); - foreach ($enrichment['deploy'] as $t) { - $target = $dom->createElementNS($ns, 'target'); - $target->setAttribute('name', $t['name']); - $target->appendChild($dom->createElementNS($ns, 'host', '${{ secrets.' . strtoupper($t['name']) . '_HOST }}')); - $target->appendChild($dom->createElementNS($ns, 'path', '${{ secrets.' . strtoupper($t['name']) . '_PATH }}')); - if (isset($t['method'])) { - $target->appendChild($dom->createElementNS($ns, 'method', $t['method'])); - } - if (isset($t['branch'])) { - $target->appendChild($dom->createElementNS($ns, 'branch', htmlspecialchars($t['branch'], ENT_XML1))); - } - if (isset($t['src_dir'])) { - $target->appendChild($dom->createElementNS($ns, 'src-dir', htmlspecialchars($t['src_dir'], ENT_XML1))); - } - $deploy->appendChild($target); - } - $root->appendChild($deploy); - } - - if (!empty($enrichment['scripts'])) { - $scriptsEl = $dom->createElementNS($ns, 'scripts'); - foreach ($enrichment['scripts'] as $s) { - $script = $dom->createElementNS($ns, 'script'); - $script->setAttribute('name', $s['name']); - if (isset($s['phase'])) { - $script->setAttribute('phase', $s['phase']); - } - $script->appendChild($dom->createElementNS($ns, 'command', htmlspecialchars($s['command'], ENT_XML1))); - if (isset($s['desc'])) { - $script->appendChild($dom->createElementNS($ns, 'description', htmlspecialchars($s['desc'], ENT_XML1))); - } - if (isset($s['runner'])) { - $script->appendChild($dom->createElementNS($ns, 'runner', htmlspecialchars($s['runner'], ENT_XML1))); - } - $scriptsEl->appendChild($script); - } - $root->appendChild($scriptsEl); - } - - return $dom->saveXML(); - } - - /** @return array{int, string} */ - private function safeExec(string $command, string $cwd = '.'): array - { - $proc = proc_open($command, [1 => ['pipe', 'w'], 2 => ['pipe', 'w']], $pipes, $cwd); - if (!is_resource($proc)) { - return [1, "proc_open failed"]; - } - $stdout = stream_get_contents($pipes[1]); - $stderr = stream_get_contents($pipes[2]); - fclose($pipes[1]); - fclose($pipes[2]); - return [proc_close($proc), trim($stdout . "\n" . $stderr)]; - } - - private function rmTree(string $dir): void - { - if (!is_dir($dir)) { - return; - } - $it = new \RecursiveDirectoryIterator($dir, \FilesystemIterator::SKIP_DOTS); - $files = new \RecursiveIteratorIterator($it, \RecursiveIteratorIterator::CHILD_FIRST); - foreach ($files as $file) { - if ($file->isDir()) { - @rmdir($file->getPathname()); - } else { - @chmod($file->getPathname(), 0777); - @unlink($file->getPathname()); - } - } - @rmdir($dir); - } - - /** @return array{int, string} */ - private function gitCmd(string $workDir, string ...$args): array - { - $cmd = 'git'; - foreach ($args as $a) { - $cmd .= ' ' . escapeshellarg($a); - } - return $this->safeExec($cmd, $workDir); - } - - private function fetchRepos(string $url, string $org, string $token): array - { - $repos = []; - $page = 1; - do { - $ch = curl_init("{$url}/api/v1/orgs/{$org}/repos?page={$page}&limit=50"); - curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ["Authorization: token {$token}"], CURLOPT_TIMEOUT => 30]); - $body = curl_exec($ch); - $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); - curl_close($ch); - if ($code !== 200) { - break; - } - $batch = json_decode($body, true); - if (empty($batch)) { - break; - } - $repos = array_merge($repos, $batch); - $page++; - } while (count($batch) >= 50); - return $repos; - } -} - -$app = new EnrichManifestXmlCli(); -exit($app->execute()); diff --git a/automation/enrich_mokostandards_xml.php b/automation/enrich_mokostandards_xml.php deleted file mode 100644 index 686e6b3a..00000000 --- a/automation/enrich_mokostandards_xml.php +++ /dev/null @@ -1,484 +0,0 @@ -#!/usr/bin/env php - - * SPDX-License-Identifier: GPL-3.0-or-later - * - * FILE INFORMATION - * DEFGROUP: MokoPlatform.Automation - * INGROUP: MokoPlatform - * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli - * PATH: /automation/enrich_mokostandards_xml.php - * BRIEF: Enrich XML manifests with repo-specific build and deploy details - * - * Note: This script uses proc_open for shell commands. All arguments are escaped - * via escapeshellarg(). No user-supplied input reaches the shell unescaped. - */ - -declare(strict_types=1); - -require_once __DIR__ . '/../vendor/autoload.php'; -require_once __DIR__ . '/../lib/Enterprise/CliFramework.php'; - -use MokoCli\CliFramework; -use MokoCli\ManifestParser; - -class EnrichMokostandardsXmlCli extends CliFramework -{ - protected function configure(): void - { - $this->setDescription('Enrich XML manifests with repo-specific build and deploy details'); - $this->addArgument('--repo', 'Filter to a single repo name', ''); - $this->addArgument('--skip', 'Comma-separated list of repos to skip', ''); - } - - protected function run(): int - { - $giteaUrl = rtrim(getenv('GITEA_URL') ?: 'https://git.mokoconsulting.tech', '/'); - $giteaOrg = getenv('GITEA_ORG') ?: 'MokoConsulting'; - $token = getenv('GA_TOKEN') ?: getenv('GH_TOKEN') ?: ''; - - $repoFilter = $this->getArgument('--repo') ?: null; - $skipStr = $this->getArgument('--skip'); - $skipRepos = $skipStr !== '' ? array_map('trim', explode(',', $skipStr)) : []; - - $parser = new ManifestParser(); - $tmpBase = sys_get_temp_dir() . '/moko-enrich-' . getmypid(); - - echo "=== mokocli XML Manifest Enrichment ===\n"; - echo "Mode: " . ($this->dryRun ? "DRY RUN" : "LIVE") . "\n"; - if (!empty($skipRepos)) { - echo "Skipping: " . implode(', ', $skipRepos) . "\n"; - } - echo "\n"; - - if (empty($token)) { - $this->log('ERROR', 'GA_TOKEN required'); - return 1; - } - - $repos = $this->fetchRepos($giteaUrl, $giteaOrg, $token); - echo "Found " . count($repos) . " repositories\n\n"; - - $stats = ['enriched' => 0, 'skipped' => 0, 'failed' => 0]; - - foreach ($repos as $repo) { - $name = $repo['name']; - if ($repoFilter && $name !== $repoFilter) { - continue; - } - if (in_array($name, $skipRepos, true)) { - echo " {$name} ... SKIP (excluded)\n"; - $stats['skipped']++; - continue; - } - if ($repo['archived'] ?? false) { - $stats['skipped']++; - continue; - } - - $defaultBranch = $repo['default_branch'] ?? 'main'; - $httpsUrl = $repo['clone_url'] ?? "{$giteaUrl}/{$giteaOrg}/{$name}.git"; - $authedUrl = preg_replace('#^https://#', "https://gitea-actions:{$token}@", $httpsUrl); - - echo " {$name} ... "; - - $workDir = "{$tmpBase}/{$name}"; - @mkdir($workDir, 0755, true); - [$ret] = $this->safeExec( - 'git clone --depth 1 --branch ' . escapeshellarg($defaultBranch) - . ' ' . escapeshellarg($authedUrl) . ' ' . escapeshellarg($workDir) - ); - if ($ret !== 0) { - echo "FAIL (clone)\n"; - $stats['failed']++; - continue; - } - - $manifestPath = "{$workDir}/.mokogitea/manifest.xml"; - if (!file_exists($manifestPath) || !str_contains(file_get_contents($manifestPath), 'rmTree($workDir); - continue; - } - - $existingXml = file_get_contents($manifestPath); - $platform = $parser->extractPlatform($existingXml) ?? 'default-repository'; - $enrichment = $this->inspectRepo($workDir, $platform); - - if (!isset($enrichment['build'])) { - $enrichment['build'] = []; - } - $enrichment['build']['language'] = $enrichment['build']['language'] - ?? $repo['language'] - ?? ManifestParser::platformLanguage($platform); - $enrichment['build']['package_type'] = $enrichment['build']['package_type'] ?? ManifestParser::platformPackageType($platform); - - $enrichedXml = $this->enrichManifestXml($existingXml, $enrichment); - $dc = count($enrichment['deploy'] ?? []); - $sc = count($enrichment['scripts'] ?? []); - $details = "deploy={$dc} scripts={$sc}"; - - if ($this->dryRun) { - echo "WOULD ENRICH [{$details}]\n"; - $stats['enriched']++; - $this->rmTree($workDir); - continue; - } - - file_put_contents($manifestPath, $enrichedXml); - $this->gitCmd($workDir, 'config', 'user.name', 'gitea-actions[bot]'); - $this->gitCmd($workDir, 'config', 'user.email', 'gitea-actions[bot]@git.mokoconsulting.tech'); - $this->gitCmd($workDir, 'add', '.mokogitea/manifest.xml'); - - $commitMsg = "chore: enrich .mokostandards" - . " with build/deploy/scripts\n\n" - . "Auto-detected: {$details}"; - [$cr, $co] = $this->gitCmd( - $workDir, - 'commit', - '-m', - $commitMsg - ); - if ($cr !== 0) { - echo "SKIP (no diff)\n"; - $stats['skipped']++; - $this->rmTree($workDir); - continue; - } - - [$pr] = $this->gitCmd($workDir, 'push', 'origin', $defaultBranch); - if ($pr !== 0) { - echo "FAIL (push)\n"; - $stats['failed']++; - } else { - echo "ENRICHED [{$details}]\n"; - $stats['enriched']++; - } - - $this->rmTree($workDir); - } - - @rmdir($tmpBase); - echo "\n=== Summary ===\nEnriched: {$stats['enriched']}\nSkipped: {$stats['skipped']}\nFailed: {$stats['failed']}\n"; - - return 0; - } - - private function inspectRepo(string $workDir, string $platform): array - { - $enrichment = []; - $build = []; - - if (is_dir("{$workDir}/src")) { - foreach (glob("{$workDir}/src/*.xml") ?: [] as $xf) { - $c = file_get_contents($xf); - if (str_contains($c, ' $pd, 'version' => $composer['require'][$pd], 'type' => 'platform']; - } - } - if (isset($composer['require']['mokoconsulting-tech/enterprise'])) { - $deps[] = [ - 'name' => 'mokoconsulting-tech/enterprise', - 'version' => $composer['require']['mokoconsulting-tech/enterprise'], - 'type' => 'composer', - ]; - } - if (!empty($deps)) { - $build['dependencies'] = $deps; - } - } - - if (file_exists("{$workDir}/Makefile")) { - $mk = file_get_contents("{$workDir}/Makefile"); - if (preg_match('/\bdist\/(\S+\.zip)\b/', $mk, $m)) { - $build['artifact'] = ['format' => 'zip', 'path' => 'dist/', 'filename' => $m[1]]; - } - } - - if (!empty($build)) { - $enrichment['build'] = $build; - } - - $targets = []; - $wfDir = is_dir("{$workDir}/.gitea/workflows") ? "{$workDir}/.gitea/workflows" : "{$workDir}/.github/workflows"; - if (is_dir($wfDir)) { - foreach (['deploy-dev', 'deploy-demo', 'deploy-rs'] as $dn) { - $wf = "{$wfDir}/{$dn}.yml"; - if (!file_exists($wf)) { - continue; - } - $wc = file_get_contents($wf); - $t = ['name' => str_replace('deploy-', '', $dn)]; - if (str_contains($wc, 'sftp') || str_contains($wc, 'SFTP')) { - $t['method'] = 'sftp'; - } elseif (str_contains($wc, 'rsync')) { - $t['method'] = 'rsync'; - } - if (str_contains($wc, 'src/')) { - $t['src_dir'] = 'src/'; - } - if (preg_match('/branches:\s*\n\s*-\s*["\']?([^"\'}\s]+)/', $wc, $m)) { - $t['branch'] = $m[1]; - } - $targets[] = $t; - } - } - if (!empty($targets)) { - $enrichment['deploy'] = $targets; - } - - $scripts = []; - if (file_exists("{$workDir}/Makefile")) { - $mk = file_get_contents("{$workDir}/Makefile"); - $known = [ - 'build' => 'build', 'test' => 'test', 'lint' => 'lint', - 'clean' => 'build', 'package' => 'build', - 'validate' => 'validate', 'release' => 'release', - ]; - if (preg_match_all('/^([a-zA-Z_-]+)\s*:/m', $mk, $matches)) { - foreach ($matches[1] as $tgt) { - $tl = strtolower($tgt); - if (isset($known[$tl])) { - $scripts[] = [ - 'name' => $tl, 'phase' => $known[$tl], - 'command' => "make {$tgt}", - 'desc' => ucfirst($tl) . ' via make', - 'runner' => 'make', - ]; - } - } - } - } - if (file_exists("{$workDir}/composer.json")) { - $composer = json_decode(file_get_contents("{$workDir}/composer.json"), true) ?: []; - $km = ['test' => 'test','lint' => 'lint','cs' => 'lint','phpcs' => 'lint','phpstan' => 'lint','validate' => 'validate']; - foreach ($composer['scripts'] ?? [] as $sn => $cmd) { - $sl = strtolower($sn); - foreach ($km as $match => $phase) { - if (str_contains($sl, $match)) { - $exists = false; - foreach ($scripts as $s) { - if ($s['name'] === $sl) { - $exists = true; - break; - } - } - if (!$exists) { - $scripts[] = [ - 'name' => $sn, 'phase' => $phase, - 'command' => "composer run {$sn}", - 'desc' => is_string($cmd) ? $cmd : "Run {$sn}", - 'runner' => 'composer', - ]; - } - break; - } - } - } - } - if (!empty($scripts)) { - $enrichment['scripts'] = $scripts; - } - - return $enrichment; - } - - private function enrichManifestXml(string $xml, array $enrichment): string - { - $dom = new \DOMDocument('1.0', 'UTF-8'); - $dom->preserveWhiteSpace = false; - $dom->formatOutput = true; - if (!$dom->loadXML($xml)) { - return $xml; - } - - $ns = ManifestParser::NAMESPACE_URI; - $root = $dom->documentElement; - - foreach (['build', 'deploy', 'scripts'] as $tag) { - $toRemove = []; - $existing = $root->getElementsByTagNameNS($ns, $tag); - for ($i = 0; $i < $existing->length; $i++) { - $toRemove[] = $existing->item($i); - } - foreach ($toRemove as $node) { - $root->removeChild($node); - } - } - - if (!empty($enrichment['build'])) { - $buildEl = $dom->createElementNS($ns, 'build'); - $b = $enrichment['build']; - foreach (['language', 'runtime'] as $f) { - if (isset($b[$f])) { - $buildEl->appendChild($dom->createElementNS($ns, $f, htmlspecialchars($b[$f], ENT_XML1))); - } - } - if (isset($b['package_type'])) { - $buildEl->appendChild($dom->createElementNS($ns, 'package-type', htmlspecialchars($b['package_type'], ENT_XML1))); - } - if (isset($b['entry_point'])) { - $buildEl->appendChild($dom->createElementNS($ns, 'entry-point', htmlspecialchars($b['entry_point'], ENT_XML1))); - } - if (isset($b['artifact'])) { - $art = $dom->createElementNS($ns, 'artifact'); - foreach (['format','path','filename'] as $af) { - if (isset($b['artifact'][$af])) { - $art->appendChild($dom->createElementNS($ns, $af, htmlspecialchars($b['artifact'][$af], ENT_XML1))); - } - } - $buildEl->appendChild($art); - } - if (isset($b['dependencies'])) { - $deps = $dom->createElementNS($ns, 'dependencies'); - foreach ($b['dependencies'] as $d) { - $req = $dom->createElementNS($ns, 'requires', ''); - $req->setAttribute('name', $d['name']); - if (isset($d['version'])) { - $req->setAttribute('version', $d['version']); - } - if (isset($d['type'])) { - $req->setAttribute('type', $d['type']); - } - $deps->appendChild($req); - } - $buildEl->appendChild($deps); - } - $root->appendChild($buildEl); - } - - if (!empty($enrichment['deploy'])) { - $deploy = $dom->createElementNS($ns, 'deploy'); - foreach ($enrichment['deploy'] as $t) { - $target = $dom->createElementNS($ns, 'target'); - $target->setAttribute('name', $t['name']); - $target->appendChild($dom->createElementNS($ns, 'host', '${{ secrets.' . strtoupper($t['name']) . '_HOST }}')); - $target->appendChild($dom->createElementNS($ns, 'path', '${{ secrets.' . strtoupper($t['name']) . '_PATH }}')); - if (isset($t['method'])) { - $target->appendChild($dom->createElementNS($ns, 'method', $t['method'])); - } - if (isset($t['branch'])) { - $target->appendChild($dom->createElementNS($ns, 'branch', htmlspecialchars($t['branch'], ENT_XML1))); - } - if (isset($t['src_dir'])) { - $target->appendChild($dom->createElementNS($ns, 'src-dir', htmlspecialchars($t['src_dir'], ENT_XML1))); - } - $deploy->appendChild($target); - } - $root->appendChild($deploy); - } - - if (!empty($enrichment['scripts'])) { - $scriptsEl = $dom->createElementNS($ns, 'scripts'); - foreach ($enrichment['scripts'] as $s) { - $script = $dom->createElementNS($ns, 'script'); - $script->setAttribute('name', $s['name']); - if (isset($s['phase'])) { - $script->setAttribute('phase', $s['phase']); - } - $script->appendChild($dom->createElementNS($ns, 'command', htmlspecialchars($s['command'], ENT_XML1))); - if (isset($s['desc'])) { - $script->appendChild($dom->createElementNS($ns, 'description', htmlspecialchars($s['desc'], ENT_XML1))); - } - if (isset($s['runner'])) { - $script->appendChild($dom->createElementNS($ns, 'runner', htmlspecialchars($s['runner'], ENT_XML1))); - } - $scriptsEl->appendChild($script); - } - $root->appendChild($scriptsEl); - } - - return $dom->saveXML(); - } - - /** @return array{int, string} */ - private function safeExec(string $command, string $cwd = '.'): array - { - $proc = proc_open($command, [1 => ['pipe', 'w'], 2 => ['pipe', 'w']], $pipes, $cwd); - if (!is_resource($proc)) { - return [1, "proc_open failed"]; - } - $stdout = stream_get_contents($pipes[1]); - $stderr = stream_get_contents($pipes[2]); - fclose($pipes[1]); - fclose($pipes[2]); - return [proc_close($proc), trim($stdout . "\n" . $stderr)]; - } - - private function rmTree(string $dir): void - { - if (!is_dir($dir)) { - return; - } - $it = new \RecursiveDirectoryIterator($dir, \FilesystemIterator::SKIP_DOTS); - $files = new \RecursiveIteratorIterator($it, \RecursiveIteratorIterator::CHILD_FIRST); - foreach ($files as $file) { - if ($file->isDir()) { - @rmdir($file->getPathname()); - } else { - @chmod($file->getPathname(), 0777); - @unlink($file->getPathname()); - } - } - @rmdir($dir); - } - - /** @return array{int, string} */ - private function gitCmd(string $workDir, string ...$args): array - { - $cmd = 'git'; - foreach ($args as $a) { - $cmd .= ' ' . escapeshellarg($a); - } - return $this->safeExec($cmd, $workDir); - } - - private function fetchRepos(string $url, string $org, string $token): array - { - $repos = []; - $page = 1; - do { - $ch = curl_init("{$url}/api/v1/orgs/{$org}/repos?page={$page}&limit=50"); - curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ["Authorization: token {$token}"], CURLOPT_TIMEOUT => 30]); - $body = curl_exec($ch); - $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); - curl_close($ch); - if ($code !== 200) { - break; - } - $batch = json_decode($body, true); - if (empty($batch)) { - break; - } - $repos = array_merge($repos, $batch); - $page++; - } while (count($batch) >= 50); - return $repos; - } -} - -$app = new EnrichMokostandardsXmlCli(); -exit($app->execute()); diff --git a/automation/migrate_to_gitea.php b/automation/migrate_to_mokogit.php similarity index 78% rename from automation/migrate_to_gitea.php rename to automation/migrate_to_mokogit.php index 323b75b7..4e900cd7 100644 --- a/automation/migrate_to_gitea.php +++ b/automation/migrate_to_mokogit.php @@ -11,14 +11,14 @@ * DEFGROUP: MokoPlatform.Automation * INGROUP: MokoPlatform * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli - * PATH: /automation/migrate_to_gitea.php - * BRIEF: Migrate repositories from GitHub to self-hosted Gitea instance + * PATH: /automation/migrate_to_mokogit.php + * BRIEF: Migrate repositories from GitHub to self-hosted MokoGit instance * * USAGE - * php automation/migrate_to_gitea.php --dry-run - * php automation/migrate_to_gitea.php --repos MokoCRM MokoDoliMods - * php automation/migrate_to_gitea.php --exclude mokocli --skip-archived - * php automation/migrate_to_gitea.php --resume + * php automation/migrate_to_mokogit.php --dry-run + * php automation/migrate_to_mokogit.php --repos MokoCRM MokoDoliMods + * php automation/migrate_to_mokogit.php --exclude mokocli --skip-archived + * php automation/migrate_to_mokogit.php --resume */ declare(strict_types=1); @@ -30,32 +30,32 @@ use MokoCli\CliFramework; use MokoCli\Config; use MokoCli\PlatformAdapterFactory; use MokoCli\GitHubAdapter; -use MokoCli\MokoGiteaAdapter; +use MokoCli\MokoGitAdapter; /** - * Gitea Migration Script + * MokoGit Migration Script * - * Migrates repositories from GitHub to a self-hosted Gitea instance. - * Uses Gitea's built-in migration endpoint for git history, tags, releases, + * Migrates repositories from GitHub to a self-hosted MokoGit instance. + * Uses MokoGit's built-in migration endpoint for git history, tags, releases, * issues, and labels. Post-migration applies branch protection, topics, * and workflow conversion. */ -class MigrateToGitea extends CliFramework +class MigrateToMokoGit extends CliFramework { private ?GitHubAdapter $github = null; - private ?MokoGiteaAdapter $gitea = null; + private ?MokoGitAdapter $mokogit = null; private ?CheckpointManager $checkpoints = null; protected function configure(): void { - $this->setDescription('Migrate repositories from GitHub to Gitea'); + $this->setDescription('Migrate repositories from GitHub to MokoGit'); $this->addArgument('--dry-run', 'Show what would be migrated without making changes', false); $this->addArgument('--repos', 'Specific repositories to migrate (space-separated)', ''); $this->addArgument('--exclude', 'Repositories to exclude (space-separated)', ''); $this->addArgument('--skip-archived', 'Skip archived repositories', false); $this->addArgument('--resume', 'Resume from last checkpoint', false); $this->addArgument('--github-token', 'GitHub token override', ''); - $this->addArgument('--gitea-token', 'Gitea token override', ''); + $this->addArgument('--mokogit-token', 'MokoGit token override', ''); } protected function run(): int @@ -70,19 +70,19 @@ class MigrateToGitea extends CliFramework // Override tokens if provided $ghToken = (string) $this->getArgument('--github-token'); - $giteaToken = (string) $this->getArgument('--gitea-token'); + $mokogitToken = (string) $this->getArgument('--mokogit-token'); if ($ghToken !== '') { $config->set('github.token', $ghToken); } - if ($giteaToken !== '') { - $config->set('gitea.token', $giteaToken); + if ($mokogitToken !== '') { + $config->set('mokogit.token', $mokogitToken); } // Create both adapters try { $adapters = PlatformAdapterFactory::createBoth($config); $this->github = $adapters['github']; - $this->gitea = $adapters['gitea']; + $this->mokogit = $adapters['mokogit']; } catch (\RuntimeException $e) { $this->log('ERROR', $e->getMessage()); return 1; @@ -90,11 +90,11 @@ class MigrateToGitea extends CliFramework $this->checkpoints = new CheckpointManager('.checkpoints/migration'); $org = $config->getString('github.organization', 'MokoConsulting'); - $giteaOrg = $config->getString('gitea.organization', 'MokoConsulting'); + $mokogitOrg = $config->getString('mokogit.organization', 'MokoConsulting'); - echo "=== Gitea Migration Tool ===\n"; + echo "=== MokoGit Migration Tool ===\n"; echo "Source: GitHub ({$org})\n"; - echo "Destination: Gitea ({$giteaOrg}) at " . $config->getString('gitea.url') . "\n"; + echo "Destination: MokoGit ({$mokogitOrg}) at " . $config->getString('mokogit.url') . "\n"; echo "Mode: " . ($dryRun ? 'DRY RUN' : 'LIVE') . "\n\n"; // ── Phase 1: Discovery ────────────────────────────────────────── @@ -111,22 +111,22 @@ class MigrateToGitea extends CliFramework $ghRepos = array_filter($ghRepos, fn($r) => !in_array($r['name'], $excludeRepos, true)); } - // Check which already exist on Gitea - $giteaRepos = []; + // Check which already exist on MokoGit + $mokogitRepos = []; try { - $existing = $this->gitea->listOrgRepos($giteaOrg); + $existing = $this->mokogit->listOrgRepos($mokogitOrg); foreach ($existing as $r) { - $giteaRepos[$r['name']] = true; + $mokogitRepos[$r['name']] = true; } } catch (\Exception $e) { - echo "Note: Could not list Gitea repos (org may not exist yet): {$e->getMessage()}\n"; + echo "Note: Could not list MokoGit repos (org may not exist yet): {$e->getMessage()}\n"; } $toMigrate = []; $toSkip = []; foreach ($ghRepos as $repo) { $name = $repo['name']; - if (isset($giteaRepos[$name])) { + if (isset($mokogitRepos[$name])) { $toSkip[] = $name; } else { $toMigrate[] = $repo; @@ -135,7 +135,7 @@ class MigrateToGitea extends CliFramework echo "\nMigration plan:\n"; echo " Migrate: " . count($toMigrate) . " repositories\n"; - echo " Skip: " . count($toSkip) . " (already on Gitea)\n"; + echo " Skip: " . count($toSkip) . " (already on MokoGit)\n"; if (!empty($toSkip)) { echo " Skipped: " . implode(', ', $toSkip) . "\n"; } @@ -163,7 +163,7 @@ class MigrateToGitea extends CliFramework $results = ['migrated' => [], 'failed' => [], 'skipped' => $toSkip]; // Resume support - $checkpoint = $resume ? $this->checkpoints->loadCheckpoint('gitea_migration') : null; + $checkpoint = $resume ? $this->checkpoints->loadCheckpoint('mokogit_migration') : null; $startFrom = $checkpoint['last_completed'] ?? ''; $skipUntil = !empty($startFrom); @@ -182,11 +182,11 @@ class MigrateToGitea extends CliFramework try { // Shallow migration — copy current branch state only, no past - // commit history. This gives every repo a clean start on Gitea. - $this->gitea->migrateRepository([ + // commit history. This gives every repo a clean start on MokoGit. + $this->mokogit->migrateRepository([ 'clone_addr' => "https://github.com/{$org}/{$name}.git", 'repo_name' => $name, - 'repo_owner' => $giteaOrg, + 'repo_owner' => $mokogitOrg, 'service' => 'github', 'auth_token' => $ghToken, 'mirror' => false, @@ -203,7 +203,7 @@ class MigrateToGitea extends CliFramework $results['migrated'][] = $name; // Save checkpoint after each successful migration - $this->checkpoints->saveCheckpoint('gitea_migration', [ + $this->checkpoints->saveCheckpoint('mokogit_migration', [ 'last_completed' => $name, 'migrated' => $results['migrated'], 'failed' => $results['failed'], @@ -211,7 +211,7 @@ class MigrateToGitea extends CliFramework } catch (\Exception $e) { echo " FAILED: " . $e->getMessage() . "\n"; $results['failed'][] = ['name' => $name, 'error' => $e->getMessage()]; - $this->gitea->getApiClient()->resetCircuitBreaker(); + $this->mokogit->getApiClient()->resetCircuitBreaker(); } } @@ -225,12 +225,12 @@ class MigrateToGitea extends CliFramework // Apply topics from GitHub $ghTopics = $this->github->getRepoTopics($org, $name); if (!empty($ghTopics)) { - $this->gitea->setRepoTopics($giteaOrg, $name, $ghTopics); + $this->mokogit->setRepoTopics($mokogitOrg, $name, $ghTopics); echo " Topics applied\n"; } // Apply branch protection - $this->gitea->setBranchProtection($giteaOrg, $name, 'main', [ + $this->mokogit->setBranchProtection($mokogitOrg, $name, 'main', [ 'required_reviews' => 1, 'dismiss_stale' => true, 'block_on_rejected' => true, @@ -238,7 +238,7 @@ class MigrateToGitea extends CliFramework echo " Branch protection applied\n"; } catch (\Exception $e) { echo " Warning: post-processing issue: " . $e->getMessage() . "\n"; - $this->gitea->getApiClient()->resetCircuitBreaker(); + $this->mokogit->getApiClient()->resetCircuitBreaker(); } } @@ -248,7 +248,7 @@ class MigrateToGitea extends CliFramework $report = "## Migration Report\n\n"; $report .= "**Date:** " . gmdate('Y-m-d H:i:s') . " UTC\n"; $report .= "**Source:** GitHub ({$org})\n"; - $report .= "**Destination:** Gitea ({$giteaOrg})\n\n"; + $report .= "**Destination:** MokoGit ({$mokogitOrg})\n\n"; $report .= "### Results\n\n"; $report .= "| Status | Count |\n|--------|-------|\n"; @@ -274,16 +274,16 @@ class MigrateToGitea extends CliFramework echo $report; - // Create summary issue on Gitea + // Create summary issue on MokoGit try { - $this->gitea->createIssue( - $giteaOrg, + $this->mokogit->createIssue( + $mokogitOrg, 'mokocli', - 'chore: GitHub → Gitea migration report — ' . count($results['migrated']) . ' repos migrated', + 'chore: GitHub → MokoGit migration report — ' . count($results['migrated']) . ' repos migrated', $report, ['labels' => ['automation', 'type: chore']] ); - echo "Migration report issue created on Gitea.\n"; + echo "Migration report issue created on MokoGit.\n"; } catch (\Exception $e) { echo "Could not create report issue: " . $e->getMessage() . "\n"; } @@ -296,5 +296,5 @@ class MigrateToGitea extends CliFramework } } -$script = new MigrateToGitea('migrate_to_gitea', 'Migrate repositories from GitHub to Gitea'); +$script = new MigrateToMokoGit('migrate_to_mokogit', 'Migrate repositories from GitHub to MokoGit'); exit($script->execute()); diff --git a/automation/push_files.php b/automation/push_files.php index a62bfc49..1ca96b84 100644 --- a/automation/push_files.php +++ b/automation/push_files.php @@ -228,18 +228,12 @@ class PushFiles extends CliFramework */ private function detectRepoPlatform(string $org, string $repo): string { - // Read platform from repo's .mokogitea/manifest.xml via API + // Read platform from the MokoGit metadata API (.mokogit/manifest.xml retired). try { - $fileInfo = $this->adapter->getFileContents($org, $repo, '.mokogitea/manifest.xml', 'main'); - $manifestData = isset($fileInfo['content']) ? base64_decode($fileInfo['content']) : ''; - if (!empty($manifestData)) { - $xml = @simplexml_load_string($manifestData); - if ($xml !== false) { - $platform = (string)($xml->governance->platform ?? ''); - if (!empty($platform)) { - return $platform; - } - } + $meta = $this->api->get("/repos/{$org}/{$repo}/metadata"); + $platform = (string)($meta['platform'] ?? ''); + if ($platform !== '') { + return $platform; } } catch (\Exception $e) { // Fall through to local detection diff --git a/automation/push_manifest_xml.php b/automation/push_manifest_xml.php deleted file mode 100644 index 00c7a594..00000000 --- a/automation/push_manifest_xml.php +++ /dev/null @@ -1,345 +0,0 @@ -#!/usr/bin/env php - - * SPDX-License-Identifier: GPL-3.0-or-later - * - * FILE INFORMATION - * DEFGROUP: MokoPlatform.Automation - * INGROUP: MokoPlatform - * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli - * PATH: /automation/push_manifest_xml.php - * BRIEF: Push XML manifests to all governed repositories - */ - -declare(strict_types=1); - -require_once __DIR__ . '/../vendor/autoload.php'; -require_once __DIR__ . '/../lib/Enterprise/CliFramework.php'; - -use MokoCli\CliFramework; -use MokoCli\ManifestParser; - -class PushManifestXmlCli extends CliFramework -{ - private const CRM_PLATFORM_REPOS = ['MokoDolibarr', 'MokoDoliMods']; - - protected function configure(): void - { - $this->setDescription('Push XML manifest.xml to all governed repositories'); - $this->addArgument('--repo', 'Filter to a single repo name', ''); - $this->addArgument('--skip', 'Comma-separated list of repos to skip', ''); - $this->addArgument('--force', 'Force overwrite even if already XML', false); - } - - protected function run(): int - { - $giteaUrl = rtrim(getenv('GITEA_URL') ?: 'https://git.mokoconsulting.tech', '/'); - $giteaOrg = getenv('GITEA_ORG') ?: 'MokoConsulting'; - $token = getenv('GA_TOKEN') ?: getenv('GH_TOKEN') ?: ''; - - $force = $this->getArgument('--force'); - $repoFilter = $this->getArgument('--repo') ?: null; - $skipStr = $this->getArgument('--skip'); - $skipRepos = $skipStr !== '' ? array_map('trim', explode(',', $skipStr)) : []; - - $parser = new ManifestParser(); - $tmpBase = sys_get_temp_dir() . '/moko-manifest-push-' . getmypid(); - - echo "=== mokocli XML Manifest Push ===\n"; - echo "Org: {$giteaOrg}\n"; - echo "Mode: " . ($this->dryRun ? "DRY RUN" : "LIVE") . "\n"; - if ($repoFilter) { - echo "Filter: {$repoFilter}\n"; - } - echo "\n"; - - if (empty($token)) { - $this->log('ERROR', 'GA_TOKEN or GH_TOKEN environment variable required'); - return 1; - } - - $repos = $this->fetchRepos($giteaUrl, $giteaOrg, $token); - echo "Found " . count($repos) . " repositories\n\n"; - - $stats = ['created' => 0, 'updated' => 0, 'skipped' => 0, 'failed' => 0]; - - foreach ($repos as $repo) { - $name = $repo['name']; - if ($repoFilter && $name !== $repoFilter) { - continue; - } - if (in_array($name, $skipRepos, true)) { - echo " SKIP {$name} (excluded)\n"; - $stats['skipped']++; - continue; - } - if ($repo['archived'] ?? false) { - echo " SKIP {$name} (archived)\n"; - $stats['skipped']++; - continue; - } - - $platform = $this->detectPlatform($repo); - $defaultBranch = $repo['default_branch'] ?? 'main'; - $httpsUrl = $repo['clone_url'] ?? "{$giteaUrl}/{$giteaOrg}/{$name}.git"; - $authedUrl = preg_replace('#^https://#', "https://gitea-actions:{$token}@", $httpsUrl); - - echo " {$name} [{$platform}] ... "; - - // Generate XML manifest - $xmlContent = $parser->generate([ - 'name' => $name, - 'org' => $giteaOrg, - 'platform' => $platform, - 'standards_version' => '04.07.00', - 'description' => $repo['description'] ?? '', - 'license' => 'GPL-3.0-or-later', - 'topics' => $repo['topics'] ?? [], - 'language' => $repo['language'] ?? ManifestParser::platformLanguage($platform), - 'package_type' => ManifestParser::platformPackageType($platform), - 'last_synced' => date('c'), - ]); - - if ($this->dryRun) { - echo "WOULD WRITE ({$platform})\n"; - $stats['created']++; - continue; - } - - // Clone shallow via HTTPS (token-authed) - $workDir = "{$tmpBase}/{$name}"; - @mkdir($workDir, 0755, true); - - [$ret, $out] = $this->safeExec( - 'git clone --depth 1 --branch ' . escapeshellarg($defaultBranch) . ' ' - . escapeshellarg($authedUrl) . ' ' . escapeshellarg($workDir) - ); - if ($ret !== 0) { - echo "FAIL (clone)\n"; - fprintf(STDERR, " %s\n", $out); - $stats['failed']++; - continue; - } - - // Check if already XML and up-to-date - $manifestPath = "{$workDir}/.mokogitea/manifest.xml"; - $existingIsXml = file_exists($manifestPath) && str_contains(file_get_contents($manifestPath), 'extractPlatform(file_get_contents($manifestPath)); - if ($existingPlatform === $platform) { - echo "SKIP (already XML)\n"; - $stats['skipped']++; - $this->rmTree($workDir); - continue; - } - } - - // Write manifest - @mkdir("{$workDir}/.gitea", 0755, true); - file_put_contents($manifestPath, $xmlContent); - - // Delete legacy files if present - $legacyDeleted = []; - foreach (['.mokostandards', '.github/.mokostandards', '.gitea/.mokostandards', '.mokogitea/.mokostandards'] as $legacy) { - $legacyPath = "{$workDir}/{$legacy}"; - if (file_exists($legacyPath)) { - unlink($legacyPath); - $legacyDeleted[] = $legacy; - } - } - - // Commit - $isNew = !$existingIsXml; - $commitMsg = $isNew - ? 'chore: add XML manifest.xml' - : 'chore: update manifest.xml'; - if (!empty($legacyDeleted)) { - $commitMsg .= "\n\nRemoved legacy: " . implode(', ', $legacyDeleted); - } - - $this->gitCmd($workDir, 'config', 'user.name', 'gitea-actions[bot]'); - $this->gitCmd($workDir, 'config', 'user.email', 'gitea-actions[bot]@git.mokoconsulting.tech'); - $this->gitCmd($workDir, 'add', '.mokogitea/manifest.xml'); - foreach ($legacyDeleted as $lf) { - $this->gitCmd($workDir, 'add', $lf); - } - - [$commitRet, $commitOut] = $this->gitCmd($workDir, 'commit', '-m', $commitMsg); - if ($commitRet !== 0 && str_contains($commitOut, 'nothing to commit')) { - echo "SKIP (no changes)\n"; - $stats['skipped']++; - $this->rmTree($workDir); - continue; - } - if ($commitRet !== 0) { - echo "FAIL (commit)\n"; - fprintf(STDERR, " %s\n", $commitOut); - $stats['failed']++; - $this->rmTree($workDir); - continue; - } - - [$pushRet, $pushOut] = $this->gitCmd($workDir, 'push', 'origin', $defaultBranch); - if ($pushRet !== 0) { - echo "FAIL (push)\n"; - fprintf(STDERR, " %s\n", $pushOut); - $stats['failed']++; - } else { - $action = $isNew ? 'CREATED' : 'UPDATED'; - echo "{$action}\n"; - $stats[$isNew ? 'created' : 'updated']++; - } - - // Cleanup - $this->rmTree($workDir); - } - - // Cleanup tmp base - @rmdir($tmpBase); - - echo "\n=== Summary ===\n"; - echo "Created: {$stats['created']}\n"; - echo "Updated: {$stats['updated']}\n"; - echo "Skipped: {$stats['skipped']}\n"; - echo "Failed: {$stats['failed']}\n"; - - return 0; - } - - private function detectPlatform(array $repo): string - { - $name = $repo['name'] ?? ''; - $nameLower = strtolower($name); - $description = strtolower($repo['description'] ?? ''); - $topics = $repo['topics'] ?? []; - - if (in_array($name, self::CRM_PLATFORM_REPOS, true)) { - return 'crm-platform'; - } - if (in_array('dolibarr-platform', $topics)) { - return 'crm-platform'; - } - if (in_array('joomla-template', $topics)) { - return 'joomla-template'; - } - if (in_array('joomla', $topics) || in_array('joomla-extension', $topics)) { - return 'waas-component'; - } - if (in_array('dolibarr', $topics) || in_array('dolibarr-module', $topics)) { - return 'crm-module'; - } - - if (str_contains($nameLower, 'template') && (str_contains($nameLower, 'joomla') || str_contains($nameLower, 'tpl'))) { - return 'joomla-template'; - } - if (str_contains($nameLower, 'joomla') || str_contains($nameLower, 'waas')) { - return 'waas-component'; - } - if (str_contains($nameLower, 'doli') || str_contains($nameLower, 'crm')) { - return 'crm-module'; - } - - if (str_contains($description, 'joomla template')) { - return 'joomla-template'; - } - if (str_contains($description, 'joomla') || str_contains($description, 'component')) { - return 'waas-component'; - } - if (str_contains($description, 'dolibarr') || str_contains($description, 'module')) { - return 'crm-module'; - } - - if (str_contains($nameLower, 'standard')) { - return 'standards-repository'; - } - return 'default-repository'; - } - - /** - * @return array{int, string} - */ - private function safeExec(string $command, string $cwd = '.'): array - { - $proc = proc_open( - $command, - [1 => ['pipe', 'w'], 2 => ['pipe', 'w']], - $pipes, - $cwd - ); - if (!is_resource($proc)) { - return [1, "proc_open failed for: {$command}"]; - } - $stdout = stream_get_contents($pipes[1]); - $stderr = stream_get_contents($pipes[2]); - fclose($pipes[1]); - fclose($pipes[2]); - $code = proc_close($proc); - return [$code, trim($stdout . "\n" . $stderr)]; - } - - private function rmTree(string $dir): void - { - if (!is_dir($dir)) { - return; - } - $it = new \RecursiveDirectoryIterator($dir, \FilesystemIterator::SKIP_DOTS); - $files = new \RecursiveIteratorIterator($it, \RecursiveIteratorIterator::CHILD_FIRST); - foreach ($files as $file) { - if ($file->isDir()) { - @rmdir($file->getPathname()); - } else { - @chmod($file->getPathname(), 0777); - @unlink($file->getPathname()); - } - } - @rmdir($dir); - } - - /** - * @return array{int, string} - */ - private function gitCmd(string $workDir, string ...$args): array - { - $cmd = 'git'; - foreach ($args as $a) { - $cmd .= ' ' . escapeshellarg($a); - } - return $this->safeExec($cmd, $workDir); - } - - private function fetchRepos(string $url, string $org, string $token): array - { - $repos = []; - $page = 1; - do { - $ch = curl_init("{$url}/api/v1/orgs/{$org}/repos?page={$page}&limit=50"); - curl_setopt_array($ch, [ - CURLOPT_RETURNTRANSFER => true, - CURLOPT_HTTPHEADER => ["Authorization: token {$token}"], - CURLOPT_TIMEOUT => 30, - ]); - $body = curl_exec($ch); - $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); - curl_close($ch); - - if ($code !== 200) { - $this->log('ERROR', "API error (HTTP {$code}) fetching repos page {$page}"); - break; - } - - $batch = json_decode($body, true); - if (empty($batch)) { - break; - } - $repos = array_merge($repos, $batch); - $page++; - } while (count($batch) >= 50); - - return $repos; - } -} - -$app = new PushManifestXmlCli(); -exit($app->execute()); diff --git a/automation/push_mokostandards_xml.php b/automation/push_mokostandards_xml.php deleted file mode 100644 index 4ba48f98..00000000 --- a/automation/push_mokostandards_xml.php +++ /dev/null @@ -1,345 +0,0 @@ -#!/usr/bin/env php - - * SPDX-License-Identifier: GPL-3.0-or-later - * - * FILE INFORMATION - * DEFGROUP: MokoPlatform.Automation - * INGROUP: MokoPlatform - * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli - * PATH: /automation/push_mokostandards_xml.php - * BRIEF: Push XML manifests to all governed repositories - */ - -declare(strict_types=1); - -require_once __DIR__ . '/../vendor/autoload.php'; -require_once __DIR__ . '/../lib/Enterprise/CliFramework.php'; - -use MokoCli\CliFramework; -use MokoCli\ManifestParser; - -class PushMokostandardsXmlCli extends CliFramework -{ - private const CRM_PLATFORM_REPOS = ['MokoDolibarr', 'MokoDoliMods']; - - protected function configure(): void - { - $this->setDescription('Push XML manifests to all governed repositories'); - $this->addArgument('--repo', 'Filter to a single repo name', ''); - $this->addArgument('--skip', 'Comma-separated list of repos to skip', ''); - $this->addArgument('--force', 'Force overwrite even if already XML', false); - } - - protected function run(): int - { - $giteaUrl = rtrim(getenv('GITEA_URL') ?: 'https://git.mokoconsulting.tech', '/'); - $giteaOrg = getenv('GITEA_ORG') ?: 'MokoConsulting'; - $token = getenv('GA_TOKEN') ?: getenv('GH_TOKEN') ?: ''; - - $force = $this->getArgument('--force'); - $repoFilter = $this->getArgument('--repo') ?: null; - $skipStr = $this->getArgument('--skip'); - $skipRepos = $skipStr !== '' ? array_map('trim', explode(',', $skipStr)) : []; - - $parser = new ManifestParser(); - $tmpBase = sys_get_temp_dir() . '/moko-manifest-push-' . getmypid(); - - echo "=== mokocli XML Manifest Push ===\n"; - echo "Org: {$giteaOrg}\n"; - echo "Mode: " . ($this->dryRun ? "DRY RUN" : "LIVE") . "\n"; - if ($repoFilter) { - echo "Filter: {$repoFilter}\n"; - } - echo "\n"; - - if (empty($token)) { - $this->log('ERROR', 'GA_TOKEN or GH_TOKEN environment variable required'); - return 1; - } - - $repos = $this->fetchRepos($giteaUrl, $giteaOrg, $token); - echo "Found " . count($repos) . " repositories\n\n"; - - $stats = ['created' => 0, 'updated' => 0, 'skipped' => 0, 'failed' => 0]; - - foreach ($repos as $repo) { - $name = $repo['name']; - if ($repoFilter && $name !== $repoFilter) { - continue; - } - if (in_array($name, $skipRepos, true)) { - echo " SKIP {$name} (excluded)\n"; - $stats['skipped']++; - continue; - } - if ($repo['archived'] ?? false) { - echo " SKIP {$name} (archived)\n"; - $stats['skipped']++; - continue; - } - - $platform = $this->detectPlatform($repo); - $defaultBranch = $repo['default_branch'] ?? 'main'; - $httpsUrl = $repo['clone_url'] ?? "{$giteaUrl}/{$giteaOrg}/{$name}.git"; - $authedUrl = preg_replace('#^https://#', "https://gitea-actions:{$token}@", $httpsUrl); - - echo " {$name} [{$platform}] ... "; - - // Generate XML manifest - $xmlContent = $parser->generate([ - 'name' => $name, - 'org' => $giteaOrg, - 'platform' => $platform, - 'standards_version' => '04.07.00', - 'description' => $repo['description'] ?? '', - 'license' => 'GPL-3.0-or-later', - 'topics' => $repo['topics'] ?? [], - 'language' => $repo['language'] ?? ManifestParser::platformLanguage($platform), - 'package_type' => ManifestParser::platformPackageType($platform), - 'last_synced' => date('c'), - ]); - - if ($this->dryRun) { - echo "WOULD WRITE ({$platform})\n"; - $stats['created']++; - continue; - } - - // Clone shallow via HTTPS (token-authed) - $workDir = "{$tmpBase}/{$name}"; - @mkdir($workDir, 0755, true); - - [$ret, $out] = $this->safeExec( - 'git clone --depth 1 --branch ' . escapeshellarg($defaultBranch) . ' ' - . escapeshellarg($authedUrl) . ' ' . escapeshellarg($workDir) - ); - if ($ret !== 0) { - echo "FAIL (clone)\n"; - fprintf(STDERR, " %s\n", $out); - $stats['failed']++; - continue; - } - - // Check if already XML and up-to-date - $manifestPath = "{$workDir}/.mokogitea/manifest.xml"; - $existingIsXml = file_exists($manifestPath) && str_contains(file_get_contents($manifestPath), 'extractPlatform(file_get_contents($manifestPath)); - if ($existingPlatform === $platform) { - echo "SKIP (already XML)\n"; - $stats['skipped']++; - $this->rmTree($workDir); - continue; - } - } - - // Write manifest - @mkdir("{$workDir}/.gitea", 0755, true); - file_put_contents($manifestPath, $xmlContent); - - // Delete legacy files if present - $legacyDeleted = []; - foreach (['.mokostandards', '.github/.mokostandards'] as $legacy) { - $legacyPath = "{$workDir}/{$legacy}"; - if (file_exists($legacyPath)) { - unlink($legacyPath); - $legacyDeleted[] = $legacy; - } - } - - // Commit - $isNew = !$existingIsXml; - $commitMsg = $isNew - ? 'chore: add XML manifest.xml' - : 'chore: update .mokostandards to XML format'; - if (!empty($legacyDeleted)) { - $commitMsg .= "\n\nRemoved legacy: " . implode(', ', $legacyDeleted); - } - - $this->gitCmd($workDir, 'config', 'user.name', 'gitea-actions[bot]'); - $this->gitCmd($workDir, 'config', 'user.email', 'gitea-actions[bot]@git.mokoconsulting.tech'); - $this->gitCmd($workDir, 'add', '.mokogitea/manifest.xml'); - foreach ($legacyDeleted as $lf) { - $this->gitCmd($workDir, 'add', $lf); - } - - [$commitRet, $commitOut] = $this->gitCmd($workDir, 'commit', '-m', $commitMsg); - if ($commitRet !== 0 && str_contains($commitOut, 'nothing to commit')) { - echo "SKIP (no changes)\n"; - $stats['skipped']++; - $this->rmTree($workDir); - continue; - } - if ($commitRet !== 0) { - echo "FAIL (commit)\n"; - fprintf(STDERR, " %s\n", $commitOut); - $stats['failed']++; - $this->rmTree($workDir); - continue; - } - - [$pushRet, $pushOut] = $this->gitCmd($workDir, 'push', 'origin', $defaultBranch); - if ($pushRet !== 0) { - echo "FAIL (push)\n"; - fprintf(STDERR, " %s\n", $pushOut); - $stats['failed']++; - } else { - $action = $isNew ? 'CREATED' : 'UPDATED'; - echo "{$action}\n"; - $stats[$isNew ? 'created' : 'updated']++; - } - - // Cleanup - $this->rmTree($workDir); - } - - // Cleanup tmp base - @rmdir($tmpBase); - - echo "\n=== Summary ===\n"; - echo "Created: {$stats['created']}\n"; - echo "Updated: {$stats['updated']}\n"; - echo "Skipped: {$stats['skipped']}\n"; - echo "Failed: {$stats['failed']}\n"; - - return 0; - } - - private function detectPlatform(array $repo): string - { - $name = $repo['name'] ?? ''; - $nameLower = strtolower($name); - $description = strtolower($repo['description'] ?? ''); - $topics = $repo['topics'] ?? []; - - if (in_array($name, self::CRM_PLATFORM_REPOS, true)) { - return 'crm-platform'; - } - if (in_array('dolibarr-platform', $topics)) { - return 'crm-platform'; - } - if (in_array('joomla-template', $topics)) { - return 'joomla-template'; - } - if (in_array('joomla', $topics) || in_array('joomla-extension', $topics)) { - return 'waas-component'; - } - if (in_array('dolibarr', $topics) || in_array('dolibarr-module', $topics)) { - return 'crm-module'; - } - - if (str_contains($nameLower, 'template') && (str_contains($nameLower, 'joomla') || str_contains($nameLower, 'tpl'))) { - return 'joomla-template'; - } - if (str_contains($nameLower, 'joomla') || str_contains($nameLower, 'waas')) { - return 'waas-component'; - } - if (str_contains($nameLower, 'doli') || str_contains($nameLower, 'crm')) { - return 'crm-module'; - } - - if (str_contains($description, 'joomla template')) { - return 'joomla-template'; - } - if (str_contains($description, 'joomla') || str_contains($description, 'component')) { - return 'waas-component'; - } - if (str_contains($description, 'dolibarr') || str_contains($description, 'module')) { - return 'crm-module'; - } - - if (str_contains($nameLower, 'standard')) { - return 'standards-repository'; - } - return 'default-repository'; - } - - /** - * @return array{int, string} - */ - private function safeExec(string $command, string $cwd = '.'): array - { - $proc = proc_open( - $command, - [1 => ['pipe', 'w'], 2 => ['pipe', 'w']], - $pipes, - $cwd - ); - if (!is_resource($proc)) { - return [1, "proc_open failed for: {$command}"]; - } - $stdout = stream_get_contents($pipes[1]); - $stderr = stream_get_contents($pipes[2]); - fclose($pipes[1]); - fclose($pipes[2]); - $code = proc_close($proc); - return [$code, trim($stdout . "\n" . $stderr)]; - } - - private function rmTree(string $dir): void - { - if (!is_dir($dir)) { - return; - } - $it = new \RecursiveDirectoryIterator($dir, \FilesystemIterator::SKIP_DOTS); - $files = new \RecursiveIteratorIterator($it, \RecursiveIteratorIterator::CHILD_FIRST); - foreach ($files as $file) { - if ($file->isDir()) { - @rmdir($file->getPathname()); - } else { - @chmod($file->getPathname(), 0777); - @unlink($file->getPathname()); - } - } - @rmdir($dir); - } - - /** - * @return array{int, string} - */ - private function gitCmd(string $workDir, string ...$args): array - { - $cmd = 'git'; - foreach ($args as $a) { - $cmd .= ' ' . escapeshellarg($a); - } - return $this->safeExec($cmd, $workDir); - } - - private function fetchRepos(string $url, string $org, string $token): array - { - $repos = []; - $page = 1; - do { - $ch = curl_init("{$url}/api/v1/orgs/{$org}/repos?page={$page}&limit=50"); - curl_setopt_array($ch, [ - CURLOPT_RETURNTRANSFER => true, - CURLOPT_HTTPHEADER => ["Authorization: token {$token}"], - CURLOPT_TIMEOUT => 30, - ]); - $body = curl_exec($ch); - $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); - curl_close($ch); - - if ($code !== 200) { - $this->log('ERROR', "API error (HTTP {$code}) fetching repos page {$page}"); - break; - } - - $batch = json_decode($body, true); - if (empty($batch)) { - break; - } - $repos = array_merge($repos, $batch); - $page++; - } while (count($batch) >= 50); - - return $repos; - } -} - -$app = new PushMokostandardsXmlCli(); -exit($app->execute()); diff --git a/automation/repo_cleanup.php b/automation/repo_cleanup.php index d6d90ab1..8e7f922f 100644 --- a/automation/repo_cleanup.php +++ b/automation/repo_cleanup.php @@ -368,7 +368,7 @@ class RepoCleanup extends CliFramework } // Check both workflow directories for retired workflows (supports dual-platform repos) - $wfDirs = array_unique(['.github/workflows', '.mokogitea/workflows', $this->adapter->getWorkflowDir()]); + $wfDirs = array_unique(['.github/workflows', '.mokogit/workflows', $this->adapter->getWorkflowDir()]); foreach (self::RETIRED_WORKFLOWS as $wf) { foreach ($wfDirs as $wfDir) { $path = "{$wfDir}/{$wf}"; @@ -479,15 +479,14 @@ class RepoCleanup extends CliFramework if (preg_match('/^\s*VERSION:\s*(\d{2}\.\d{2}\.\d{2})/m', $content, $m)) { $version = $m[1]; - // Check manifest.xml for the tracked mokocli version + // Check the MokoGit metadata API for the tracked standards version + // (.mokogit/manifest.xml retired). try { - $mokoFile = $this->api->get("/repos/{$org}/{$repo}/contents/.mokogitea/manifest.xml"); - $mokoContent = base64_decode($mokoFile['content'] ?? ''); - if (preg_match('/standards_version:\s*(\d{2}\.\d{2}\.\d{2})/m', $mokoContent, $vm)) { - if ($vm[1] !== self::VERSION) { - $this->logMsg(" ⚠️ Standards drift: {$vm[1]} (expected " . self::VERSION . ")"); - $results['version_drift']++; - } + $meta = $this->api->get("/repos/{$org}/{$repo}/metadata"); + $sv = (string)($meta['standards_version'] ?? ''); + if ($sv !== '' && $sv !== self::VERSION) { + $this->logMsg(" ⚠️ Standards drift: {$sv} (expected " . self::VERSION . ")"); + $results['version_drift']++; } } catch (\Exception $e) { $this->api->resetCircuitBreaker(); diff --git a/automation/update_dependencies.php b/automation/update_dependencies.php index 5a0f28d1..6850b8a6 100644 --- a/automation/update_dependencies.php +++ b/automation/update_dependencies.php @@ -183,7 +183,7 @@ class UpdateDependencies extends CliFramework // Default exclusions $excludeRepos = array_merge($excludeRepos, [ - 'mokocli', '.mokogitea-private', 'org-profile', + 'mokocli', '.mokogit-private', 'org-profile', ]); try { @@ -505,8 +505,8 @@ class UpdateDependencies extends CliFramework } // Commit and push - exec(sprintf('git -C %s config user.email "gitea-actions[bot]@mokoconsulting.tech"', escapeshellarg($tmpDir))); - exec(sprintf('git -C %s config user.name "gitea-actions[bot]"', escapeshellarg($tmpDir))); + exec(sprintf('git -C %s config user.email "mokogit-actions[bot]@mokoconsulting.tech"', escapeshellarg($tmpDir))); + exec(sprintf('git -C %s config user.name "mokogit-actions[bot]"', escapeshellarg($tmpDir))); exec(sprintf('git -C %s add -A', escapeshellarg($tmpDir))); // Check if there are actual changes diff --git a/bin/moko b/bin/moko index 8cea39b9..2aecac50 100644 --- a/bin/moko +++ b/bin/moko @@ -21,14 +21,14 @@ * * COMMANDS (run `php bin/moko list` for the full list — 97 commands) * - * Automation sync, automation:cleanup, automation:migrate-gitea + * Automation sync, automation:cleanup, automation:migrate-mokogit * Validation health, detect, drift, check:syntax, check:version, ... * Release release, release:joomla, release:create, release:publish, ... * Version version:read, version:bump, version:auto-bump, ... * Build build:package, build:joomla, build:updates-xml, ... * Deploy deploy:joomla, deploy:dolibarr, deploy:sftp, deploy:rollback, ... * Repository repo:create, repo:archive, repo:rename-branch, repo:reset-dev, ... - * Bulk Operations bulk:push-workflow, bulk:push-manifest, bulk:template-joomla, ... + * Bulk Operations bulk:push-workflow, bulk:push-files, bulk:template-joomla, ... * Maintenance maintenance:labels, maintenance:rotate-secrets, maintenance:pin-shas, ... * Fix fix:line-endings, fix:tabs, fix:trailing, fix:permissions * Monitoring dashboard, grafana, client:inventory, client:health-check @@ -91,7 +91,7 @@ const COMMAND_MAP = [ 'sync' => 'automation/bulk_sync.php', 'deps:update' => 'automation/update_dependencies.php', 'automation:cleanup' => 'automation/repo_cleanup.php', - 'automation:migrate-gitea' => 'automation/migrate_to_gitea.php', + 'automation:migrate-mokogit' => 'automation/migrate_to_mokogit.php', // Maintenance 'inventory' => 'maintenance/update_repo_inventory.php', @@ -164,8 +164,6 @@ const COMMAND_MAP = [ // Build & package 'build:package' => 'cli/package_build.php', 'build:joomla' => 'cli/joomla_build.php', - 'build:updates-xml' => 'cli/updates_xml_build.php', - 'build:updates-xml-sync' => 'cli/updates_xml_sync.php', // Platform detection & manifest 'platform:detect' => 'cli/platform_detect.php', @@ -185,12 +183,9 @@ const COMMAND_MAP = [ // Bulk operations 'bulk:push-workflow' => 'cli/bulk_workflow_push.php', 'bulk:trigger' => 'cli/bulk_workflow_trigger.php', + 'workflow:sync' => 'cli/workflow_sync.php', 'bulk:sync-rulesets' => 'cli/sync_rulesets.php', 'bulk:push-files' => 'automation/push_files.php', - 'bulk:push-manifest' => 'automation/push_manifest_xml.php', - 'bulk:push-mokostandards' => 'automation/push_mokostandards_xml.php', - 'bulk:enrich-manifest' => 'automation/enrich_manifest_xml.php', - 'bulk:enrich-mokostandards' => 'automation/enrich_mokostandards_xml.php', 'bulk:template-joomla' => 'automation/bulk_joomla_template.php', // Deploy diff --git a/cli/branch_rename.php b/cli/branch_rename.php index 552d9ef1..58b8dc77 100644 --- a/cli/branch_rename.php +++ b/cli/branch_rename.php @@ -11,7 +11,7 @@ * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * PATH: /cli/branch_rename.php * VERSION: 09.38.05 - * BRIEF: Rename a git branch via Gitea API (create new, update PR, delete old) + * BRIEF: Rename a git branch via MokoGit API (create new, update PR, delete old) */ declare(strict_types=1); @@ -24,7 +24,7 @@ class BranchRenameCli extends CliFramework { protected function configure(): void { - $this->setDescription('Rename a git branch via Gitea API (create new, update PR, delete old)'); + $this->setDescription('Rename a git branch via MokoGit API (create new, update PR, delete old)'); $this->addArgument('--from', 'Source branch name', ''); $this->addArgument('--to', 'Target branch name', ''); $this->addArgument('--token', 'API token', ''); diff --git a/cli/bulk_workflow_push.php b/cli/bulk_workflow_push.php index 12498831..9c36092e 100644 --- a/cli/bulk_workflow_push.php +++ b/cli/bulk_workflow_push.php @@ -13,7 +13,7 @@ * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * PATH: /cli/bulk_workflow_push.php * VERSION: 09.38.05 - * BRIEF: Push a workflow file to all governed repos via the Gitea Contents API + * BRIEF: Push a workflow file to all governed repos via the MokoGit Contents API */ declare(strict_types=1); @@ -31,18 +31,18 @@ class BulkWorkflowPushCli extends CliFramework protected function configure(): void { - $this->setDescription('Push a workflow file to all governed repos via the Gitea Contents API'); - $this->addArgument('--gitea-url', 'Gitea URL (default: https://git.mokoconsulting.tech)', 'https://git.mokoconsulting.tech'); - $this->addArgument('--token', 'Gitea API token', ''); + $this->setDescription('Push a workflow file to all governed repos via the MokoGit Contents API'); + $this->addArgument('--mokogit-url', 'MokoGit URL (default: https://git.mokoconsulting.tech)', 'https://git.mokoconsulting.tech'); + $this->addArgument('--token', 'MokoGit API token', ''); $this->addArgument('--org', 'Target organization', ''); $this->addArgument('--file', 'Local workflow file to push', ''); - $this->addArgument('--dest', 'Destination path in repos (default: .mokogitea/workflows/)', ''); + $this->addArgument('--dest', 'Destination path in repos (default: .mokogit/workflows/)', ''); $this->addArgument('--branch', 'Target branch (default: main)', 'main'); } protected function run(): int { - $giteaUrl = rtrim($this->getArgument('--gitea-url'), '/'); + $mokogitUrl = rtrim($this->getArgument('--mokogit-url'), '/'); $token = $this->getArgument('--token'); $org = $this->getArgument('--org'); $workflowFile = $this->getArgument('--file'); @@ -70,7 +70,7 @@ class BulkWorkflowPushCli extends CliFramework } if ($destPath === '') { - $destPath = '.mokogitea/workflows/' . basename($workflowFile); + $destPath = '.mokogit/workflows/' . basename($workflowFile); } $localContent = file_get_contents($workflowFile); @@ -82,7 +82,7 @@ class BulkWorkflowPushCli extends CliFramework $this->log('INFO', "Pushing: {$workflowFile}"); $this->log('INFO', " -> {$destPath} (branch: {$branch})"); - $this->log('INFO', " -> Org: {$org} @ {$giteaUrl}"); + $this->log('INFO', " -> Org: {$org} @ {$mokogitUrl}"); if ($this->dryRun) { $this->log('INFO', '[DRY RUN] No changes will be made.'); @@ -90,7 +90,7 @@ class BulkWorkflowPushCli extends CliFramework echo "\n"; - $repos = $this->fetchOrgRepos($giteaUrl, $token, $org); + $repos = $this->fetchOrgRepos($mokogitUrl, $token, $org); if ($repos === null) { return 1; @@ -104,7 +104,7 @@ class BulkWorkflowPushCli extends CliFramework $encodedContent = base64_encode($localContent); foreach ($repos as $repo) { - $this->pushToRepo($giteaUrl, $token, $repo, $encodedContent, $localContent, $destPath, $branch); + $this->pushToRepo($mokogitUrl, $token, $repo, $encodedContent, $localContent, $destPath, $branch); } echo "\n"; @@ -115,7 +115,7 @@ class BulkWorkflowPushCli extends CliFramework } private function pushToRepo( - string $giteaUrl, + string $mokogitUrl, string $token, string $repoFullName, string $encodedContent, @@ -126,7 +126,7 @@ class BulkWorkflowPushCli extends CliFramework [$owner, $repoName] = explode('/', $repoFullName, 2); $existing = $this->apiRequest( - $giteaUrl, + $mokogitUrl, $token, 'GET', "/api/v1/repos/{$owner}/{$repoName}/contents/" @@ -159,7 +159,7 @@ class BulkWorkflowPushCli extends CliFramework ]); $response = $this->apiRequest( - $giteaUrl, + $mokogitUrl, $token, 'PUT', "/api/v1/repos/{$owner}/{$repoName}/contents/" @@ -189,7 +189,7 @@ class BulkWorkflowPushCli extends CliFramework ]); $response = $this->apiRequest( - $giteaUrl, + $mokogitUrl, $token, 'POST', "/api/v1/repos/{$owner}/{$repoName}/contents/" @@ -210,7 +210,7 @@ class BulkWorkflowPushCli extends CliFramework } } - private function fetchOrgRepos(string $giteaUrl, string $token, string $org): ?array + private function fetchOrgRepos(string $mokogitUrl, string $token, string $org): ?array { $this->log('INFO', "Fetching repos from org: {$org}"); @@ -219,7 +219,7 @@ class BulkWorkflowPushCli extends CliFramework while (true) { $response = $this->apiRequest( - $giteaUrl, + $mokogitUrl, $token, 'GET', "/api/v1/orgs/{$org}/repos?" @@ -261,13 +261,13 @@ class BulkWorkflowPushCli extends CliFramework } private function apiRequest( - string $giteaUrl, + string $mokogitUrl, string $token, string $method, string $endpoint, ?string $body = null ): array { - $url = $giteaUrl . $endpoint; + $url = $mokogitUrl . $endpoint; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); diff --git a/cli/bulk_workflow_trigger.php b/cli/bulk_workflow_trigger.php index 370b6bca..6de591ee 100644 --- a/cli/bulk_workflow_trigger.php +++ b/cli/bulk_workflow_trigger.php @@ -24,7 +24,7 @@ use MokoCli\CliFramework; class BulkWorkflowTriggerCli extends CliFramework { - private string $giteaUrl = 'https://git.mokoconsulting.tech'; + private string $mokogitUrl = 'https://git.mokoconsulting.tech'; private string $token = ''; private string $reposFile = ''; private string $org = ''; @@ -35,8 +35,8 @@ class BulkWorkflowTriggerCli extends CliFramework protected function configure(): void { $this->setDescription('Trigger a workflow across multiple repos at once'); - $this->addArgument('--gitea-url', 'Gitea URL (default: https://git.mokoconsulting.tech)', 'https://git.mokoconsulting.tech'); - $this->addArgument('--token', 'Gitea API token', ''); + $this->addArgument('--mokogit-url', 'MokoGit URL (default: https://git.mokoconsulting.tech)', 'https://git.mokoconsulting.tech'); + $this->addArgument('--token', 'MokoGit API token', ''); $this->addArgument('--repos', 'File with newline-separated owner/repo list', ''); $this->addArgument('--org', 'Trigger on all repos in an org', ''); $this->addArgument('--workflow', 'Workflow file (e.g., "sync-servers.yml")', ''); @@ -46,7 +46,7 @@ class BulkWorkflowTriggerCli extends CliFramework protected function run(): int { - $this->giteaUrl = rtrim($this->getArgument('--gitea-url'), '/'); + $this->mokogitUrl = rtrim($this->getArgument('--mokogit-url'), '/'); $this->token = $this->getArgument('--token'); $this->reposFile = $this->getArgument('--repos'); $this->org = $this->getArgument('--org'); @@ -78,7 +78,7 @@ class BulkWorkflowTriggerCli extends CliFramework } $this->log('INFO', "Triggering workflow \"{$this->workflow}\" on ref \"{$this->ref}\" across " . count($repos) . " repo(s)."); - $this->log('INFO', "Gitea URL: {$this->giteaUrl}"); + $this->log('INFO', "MokoGit URL: {$this->mokogitUrl}"); if ($this->dryRun) { $this->log('INFO', '[DRY RUN] No requests will be sent.'); @@ -209,7 +209,7 @@ class BulkWorkflowTriggerCli extends CliFramework private function apiRequest(string $method, string $endpoint, ?string $body = null): array { - $url = $this->giteaUrl . $endpoint; + $url = $this->mokogitUrl . $endpoint; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); diff --git a/cli/client_dashboard.php b/cli/client_dashboard.php index 7ecf0985..3c5e20cb 100644 --- a/cli/client_dashboard.php +++ b/cli/client_dashboard.php @@ -24,7 +24,7 @@ use MokoCli\CliFramework; class ClientDashboardCli extends CliFramework { - private string $giteaUrl = 'https://git.mokoconsulting.tech'; + private string $mokogitUrl = 'https://git.mokoconsulting.tech'; private string $token = ''; private string $org = 'MokoConsulting'; private string $outputFile = ''; @@ -36,8 +36,8 @@ class ClientDashboardCli extends CliFramework protected function configure(): void { $this->setDescription('Generate unified client dashboard HTML'); - $this->addArgument('--token', 'Gitea token (or MOKOGITEA_TOKEN)', ''); - $this->addArgument('--gitea-url', 'Gitea URL', 'https://git.mokoconsulting.tech'); + $this->addArgument('--token', 'MokoGit token (or MOKOGIT_TOKEN)', ''); + $this->addArgument('--mokogit-url', 'MokoGit URL', 'https://git.mokoconsulting.tech'); $this->addArgument('--org', 'Primary org (default: MokoConsulting)', 'MokoConsulting'); $this->addArgument('--output', 'Output HTML file (default: stdout)', ''); $this->addArgument('-o', 'Output HTML file (alias)', ''); @@ -48,7 +48,7 @@ class ClientDashboardCli extends CliFramework protected function run(): int { - $this->giteaUrl = rtrim($this->getArgument('--gitea-url'), '/'); + $this->mokogitUrl = rtrim($this->getArgument('--mokogit-url'), '/'); $this->token = $this->getArgument('--token'); $this->org = $this->getArgument('--org'); $this->outputFile = $this->getArgument('--output') ?: $this->getArgument('-o'); @@ -57,11 +57,11 @@ class ClientDashboardCli extends CliFramework $this->sslWarnDays = (int) $this->getArgument('--ssl-warn-days'); if ($this->token === '') { - $this->token = getenv('MOKOGITEA_TOKEN') ?: ''; + $this->token = getenv('MOKOGIT_TOKEN') ?: ''; } if ($this->token === '') { - $this->log('ERROR', '--token or MOKOGITEA_TOKEN required.'); + $this->log('ERROR', '--token or MOKOGIT_TOKEN required.'); return 1; } @@ -460,7 +460,7 @@ CARD; /** @return array{code: int, body: string} */ private function api(string $method, string $endpoint): array { - $url = $this->giteaUrl . $endpoint; + $url = $this->mokogitUrl . $endpoint; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); diff --git a/cli/client_health_check.php b/cli/client_health_check.php index 23037d1b..4c6acd9b 100644 --- a/cli/client_health_check.php +++ b/cli/client_health_check.php @@ -88,7 +88,7 @@ class ClientHealthCheckCli extends CliFramework $checks['update_server'] = 'fail'; } - // -- Check 2: Parse updates.xml for stable version -- + // -- Check 2: Parse update feed for stable version -- $stableVersion = null; $downloadUrl = null; diff --git a/cli/client_inventory.php b/cli/client_inventory.php index 7878c98e..d956a76f 100644 --- a/cli/client_inventory.php +++ b/cli/client_inventory.php @@ -24,21 +24,21 @@ use MokoCli\CliFramework; class ClientInventoryCli extends CliFramework { - private string $giteaUrl = 'https://git.mokoconsulting.tech'; + private string $mokogitUrl = 'https://git.mokoconsulting.tech'; private string $token = ''; private bool $jsonOutput = false; protected function configure(): void { $this->setDescription('Discover and list all client-waas repos with their server configuration status'); - $this->addArgument('--gitea-url', 'Gitea URL (default: https://git.mokoconsulting.tech)', 'https://git.mokoconsulting.tech'); - $this->addArgument('--token', 'Gitea API token', ''); + $this->addArgument('--mokogit-url', 'MokoGit URL (default: https://git.mokoconsulting.tech)', 'https://git.mokoconsulting.tech'); + $this->addArgument('--token', 'MokoGit API token', ''); $this->addArgument('--json', 'Output results as JSON', false); } protected function run(): int { - $this->giteaUrl = rtrim($this->getArgument('--gitea-url'), '/'); + $this->mokogitUrl = rtrim($this->getArgument('--mokogit-url'), '/'); $this->token = $this->getArgument('--token'); $this->jsonOutput = (bool) $this->getArgument('--json'); @@ -47,7 +47,7 @@ class ClientInventoryCli extends CliFramework return 1; } - $this->log('INFO', "Scanning Gitea instance: {$this->giteaUrl}"); + $this->log('INFO', "Scanning MokoGit instance: {$this->mokogitUrl}"); // Step 1: List all orgs $orgs = $this->fetchOrgs(); @@ -241,7 +241,7 @@ class ClientInventoryCli extends CliFramework private function apiRequest(string $method, string $endpoint, ?string $body = null): array { - $url = $this->giteaUrl . $endpoint; + $url = $this->mokogitUrl . $endpoint; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); diff --git a/cli/client_provision.php b/cli/client_provision.php index e6e65732..af9850ed 100644 --- a/cli/client_provision.php +++ b/cli/client_provision.php @@ -24,8 +24,8 @@ use MokoCli\CliFramework; class ClientProvisionCli extends CliFramework { - private string $giteaUrl = 'https://git.mokoconsulting.tech'; - private string $giteaToken = ''; + private string $mokogitUrl = 'https://git.mokoconsulting.tech'; + private string $mokogitToken = ''; private string $grafanaUrl = ''; private string $grafanaToken = ''; private string $configFile = ''; @@ -65,17 +65,17 @@ class ClientProvisionCli extends CliFramework return 1; } - $this->giteaToken = $this->config['gitea_token'] - ?? getenv('MOKOGITEA_TOKEN') ?: ''; + $this->mokogitToken = $this->config['mokogit_token'] + ?? getenv('MOKOGIT_TOKEN') ?: ''; $this->grafanaUrl = $this->config['grafana_url'] ?? getenv('GRAFANA_URL') ?: ''; $this->grafanaToken = $this->config['grafana_token'] ?? getenv('GRAFANA_TOKEN') ?: ''; - $this->giteaUrl = $this->config['gitea_url'] - ?? $this->giteaUrl; + $this->mokogitUrl = $this->config['mokogit_url'] + ?? $this->mokogitUrl; - if ($this->giteaToken === '') { - $this->log('ERROR', 'gitea_token or MOKOGITEA_TOKEN required.'); + if ($this->mokogitToken === '') { + $this->log('ERROR', 'mokogit_token or MOKOGIT_TOKEN required.'); return 1; } @@ -128,7 +128,7 @@ class ClientProvisionCli extends CliFramework { $this->log('INFO', '[1/5] Creating repository...'); - $check = $this->giteaApi( + $check = $this->mokogitApi( 'GET', "/api/v1/repos/{$this->org}/{$this->repoName}" ); @@ -153,7 +153,7 @@ class ClientProvisionCli extends CliFramework 'labels' => true, ]); - $resp = $this->giteaApi( + $resp = $this->mokogitApi( 'POST', '/api/v1/repos/MokoConsulting/' . 'Template-Client-WaaS/generate', @@ -167,7 +167,7 @@ class ClientProvisionCli extends CliFramework $this->log('INFO', ' OK: Repo created'); - $this->giteaApi( + $this->mokogitApi( 'POST', "/api/v1/repos/{$this->org}/{$this->repoName}/branches", json_encode([ @@ -250,7 +250,7 @@ class ClientProvisionCli extends CliFramework continue; } - $resp = $this->giteaApi( + $resp = $this->mokogitApi( 'PUT', "{$api}/{$name}", json_encode(['data' => $value]) @@ -391,7 +391,7 @@ class ClientProvisionCli extends CliFramework echo "\n"; $this->log('INFO', '[5/5] Provisioning summary'); echo str_repeat('=', 60) . "\n"; - echo " Repo: {$this->giteaUrl}/{$this->org}/{$this->repoName}\n"; + echo " Repo: {$this->mokogitUrl}/{$this->org}/{$this->repoName}\n"; echo ' Variables: ' . count($vars) . " set\n"; echo ' Secrets: ' . count($secrets) . " set\n"; echo "\n"; @@ -409,14 +409,14 @@ class ClientProvisionCli extends CliFramework string $name, string $value ): bool { - $resp = $this->giteaApi( + $resp = $this->mokogitApi( 'PUT', "{$api}/{$name}", json_encode(['value' => $value]) ); if ($resp['code'] === 404) { - $resp = $this->giteaApi( + $resp = $this->mokogitApi( 'POST', $api, json_encode(['name' => $name, 'value' => $value]) @@ -426,15 +426,15 @@ class ClientProvisionCli extends CliFramework return $resp['code'] >= 200 && $resp['code'] < 300; } - private function giteaApi( + private function mokogitApi( string $method, string $endpoint, ?string $body = null ): array { return $this->httpRequest( - $this->giteaUrl . $endpoint, + $this->mokogitUrl . $endpoint, $method, - "token {$this->giteaToken}", + "token {$this->mokogitToken}", $body ); } diff --git a/cli/create_project.php b/cli/create_project.php index f7926ef7..db5e2397 100644 --- a/cli/create_project.php +++ b/cli/create_project.php @@ -81,7 +81,7 @@ class CreateProjectCli extends CliFramework } $config = \MokoCli\Config::load(); - $platformName = $config->getString('platform', 'gitea'); + $platformName = $config->getString('platform', 'mokogit'); try { $adapter = \MokoCli\PlatformAdapterFactory::create($config); $api = $adapter->getApiClient(); @@ -89,8 +89,8 @@ class CreateProjectCli extends CliFramework $this->log('ERROR', "Platform initialization failed: " . $e->getMessage()); return 1; } - $token = $platformName === 'gitea' - ? $config->getString('gitea.token', '') + $token = $platformName === 'mokogit' + ? $config->getString('mokogit.token', '') : $config->getString('github.token', ''); $repoRoot = dirname(__DIR__, 2); @@ -169,7 +169,7 @@ class CreateProjectCli extends CliFramework return $failed > 0 ? 1 : 0; } - private function graphql(string $query, array $variables, string $token, string $platformName = 'gitea'): array + private function graphql(string $query, array $variables, string $token, string $platformName = 'mokogit'): array { if ($platformName !== 'github') { return []; @@ -219,7 +219,7 @@ class CreateProjectCli extends CliFramework private function detectRepoPlatform(string $org, string $repo, string $token, ?\MokoCli\ApiClient $apiClient = null): string { - foreach (['.github/.mokostandards', '.mokogitea/.mokostandards', '.mokostandards'] as $path) { + foreach (['.github/.mokostandards', '.mokogit/.mokostandards', '.mokostandards'] as $path) { $data = $this->restGet("repos/{$org}/{$repo}/contents/{$path}", $token, $apiClient); if (!empty($data['content'])) { $content = base64_decode($data['content']); diff --git a/cli/create_repo.php b/cli/create_repo.php index 5cb01d4c..fdcb352c 100644 --- a/cli/create_repo.php +++ b/cli/create_repo.php @@ -116,27 +116,11 @@ class CreateRepoCli extends CliFramework echo " (dry-run) would set topics: " . implode(', ', $topics) . "\n"; } - echo "Step 3: Creating .mokogitea/manifest.xml...\n"; - $mokoContent = "platform: {$platform}\nversion: 04.02.30\nmanaged: true\n"; - if (!$this->dryRun) { - try { - $adapter->createOrUpdateFile( - $org, - $name, - '.mokogitea/manifest.xml', - $mokoContent, - 'chore: add manifest.xml platform config [skip ci]' - ); - echo " manifest.xml created\n"; - } catch (\Exception $e) { - echo " Warning: " . $e->getMessage() . "\n"; - } - } else { - echo " (dry-run) would create .mokogitea/manifest.xml\n"; - } + // Repo metadata (platform, version, managed flag) is now sourced from the MokoGit + // metadata API, not a committed .mokogit/manifest.xml. Manifest creation retired. - echo "Step 4: Creating README.md...\n"; - $baseUrl = $platformName === 'gitea' ? $config->getString('gitea.url', 'https://git.mokoconsulting.tech') : 'https://github.com'; + echo "Step 3: Creating README.md...\n"; + $baseUrl = $platformName === 'mokogit' ? $config->getString('mokogit.url', 'https://git.mokoconsulting.tech') : 'https://github.com'; $repoUrl = "{$baseUrl}/{$org}/{$name}"; $standardsUrl = "{$baseUrl}/{$org}/MokoCli"; $readmeContent = " - - -XML; - $allEntries = array_merge($preservedEntries, $entries); - - $stabilityOrder = ['dev' => 0, 'development' => 0, 'alpha' => 1, 'beta' => 2, 'rc' => 3, 'stable' => 4]; - usort($allEntries, function ($a, $b) use ($stabilityOrder) { - preg_match('/([^<]+)<\/tag>/', $a, $ma); - preg_match('/([^<]+)<\/tag>/', $b, $mb); - return ($stabilityOrder[$ma[1] ?? ''] ?? 99) - ($stabilityOrder[$mb[1] ?? ''] ?? 99); - }); - - $output .= "\n" . implode("\n", $allEntries) . "\n\n"; - - $dest = $outputFile ?? "{$root}/updates.xml"; - file_put_contents($dest, $output); - - $channelCount = count($entries); - echo "updates.xml: {$primaryVersion} ({$channelCount} channel(s), stability={$stability})\n"; - echo "Output: {$dest}\n"; - return 0; - } - - private function buildEntry( - string $tagName, - string $entryVersion, - string $entryDownloadUrl, - string $displayName, - string $stabilityLabel, - string $extElement, - string $extType, - string $clientTag, - string $folderTag, - string $infoUrl, - string $targetPlatform, - string $phpTag, - string $shaTag, - string $changelogUrl = '' - ): string { - $lines = []; - $lines[] = ' '; - $lines[] = " {$displayName}"; - $lines[] = " {$displayName} {$stabilityLabel} build."; - $prefixMap = [ - 'package' => 'pkg_', - 'module' => 'mod_', - 'component' => 'com_', - 'library' => 'lib_', - ]; - $dbElement = isset($prefixMap[$extType]) ? $prefixMap[$extType] . $extElement : $extElement; - $lines[] = " {$dbElement}"; - $lines[] = " {$extType}"; - $lines[] = $clientTag; - $lines[] = " {$entryVersion}"; - $lines[] = " " . date('Y-m-d') . ""; - if (!empty($folderTag)) { - $lines[] = $folderTag; - } - $lines[] = " {$infoUrl}"; - $lines[] = ' '; - $lines[] = " {$entryDownloadUrl}"; - $lines[] = ' '; - if (!empty($shaTag)) { - $lines[] = $shaTag; - } - $lines[] = " {$tagName}"; - if (!empty($changelogUrl)) { - $lines[] = " {$changelogUrl}"; - } - $lines[] = ' Moko Consulting'; - $lines[] = ' https://mokoconsulting.tech'; - $lines[] = " {$targetPlatform}"; - if (!empty($phpTag)) { - $lines[] = $phpTag; - } - $lines[] = ' '; - return implode("\n", $lines); - } -} - -$app = new UpdatesXmlBuildCli(); -exit($app->execute()); diff --git a/cli/updates_xml_sync.php b/cli/updates_xml_sync.php deleted file mode 100644 index 3e932474..00000000 --- a/cli/updates_xml_sync.php +++ /dev/null @@ -1,228 +0,0 @@ -#!/usr/bin/env php - - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - * FILE INFORMATION - * DEFGROUP: mokocli.CLI - * INGROUP: mokocli - * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli - * PATH: /cli/updates_xml_sync.php - * VERSION: 09.38.05 - * BRIEF: Sync updates.xml to target branches via Gitea API - * NOTE: Called by pre-release and auto-release workflows after updates.xml - * is modified on the current branch. Pushes the file to other branches - * without requiring a git checkout (avoids merge conflicts). - */ - -declare(strict_types=1); - -require_once __DIR__ . '/../lib/Enterprise/CliFramework.php'; - -use MokoCli\CliFramework; - -class UpdatesXmlSyncCli extends CliFramework -{ - protected function configure(): void - { - $this->setDescription('Sync updates.xml to target branches via Gitea API'); - $this->addArgument('--path', 'Repository root containing updates.xml', '.'); - $this->addArgument('--branches', 'Comma-separated target branches to sync to', 'main,dev'); - $this->addArgument('--all', 'Auto-discover all branches via Gitea API', false); - $this->addArgument('--current', 'Current branch to skip (required)', ''); - $this->addArgument('--version', 'Version string for commit message', ''); - $this->addArgument('--token', 'Gitea API token', ''); - $this->addArgument('--gitea-url', 'Gitea instance URL', ''); - $this->addArgument('--org', 'Organization', ''); - $this->addArgument('--repo', 'Repository name', ''); - } - - protected function run(): int - { - $path = $this->getArgument('--path'); - $branches = $this->getArgument('--branches'); - $discoverAll = $this->getArgument('--all'); - $current = $this->getArgument('--current'); - $version = $this->getArgument('--version'); - $token = $this->getArgument('--token'); - $giteaUrl = $this->getArgument('--gitea-url'); - $org = $this->getArgument('--org'); - $repo = $this->getArgument('--repo'); - - // Fall back to environment variables - if ($token === '') { - $token = getenv('MOKOGITEA_TOKEN') ?: ''; - } - if ($giteaUrl === '') { - $giteaUrl = getenv('GITEA_URL') ?: 'https://git.mokoconsulting.tech'; - } - if ($org === '') { - $org = getenv('GITEA_ORG') ?: ''; - } - if ($repo === '') { - $repo = getenv('GITEA_REPO') ?: ''; - } - - if ($current === '') { - $this->log('ERROR', '--current is required'); - return 1; - } - - if ($token === '') { - $this->log('ERROR', '--token or MOKOGITEA_TOKEN env is required'); - return 1; - } - - if ($org === '' || $repo === '') { - $this->log('ERROR', '--org and --repo (or GITEA_ORG/GITEA_REPO env) are required'); - return 1; - } - - // Auto-discover branches if --all flag is set - if ($discoverAll) { - $apiUrl = "{$giteaUrl}/api/v1/repos/{$org}/{$repo}/branches?limit=50"; - $ch = curl_init($apiUrl); - curl_setopt_array($ch, [ - CURLOPT_RETURNTRANSFER => true, - CURLOPT_HTTPHEADER => ["Authorization: token {$token}", 'Accept: application/json'], - CURLOPT_TIMEOUT => 15, - ]); - $response = curl_exec($ch); - curl_close($ch); - $branchList = json_decode($response ?: '[]', true) ?: []; - $discovered = []; - foreach ($branchList as $b) { - $name = $b['name'] ?? ''; - if ( - $name !== '' && $name !== $current - && !str_starts_with($name, 'version/') - && !str_starts_with($name, 'feature/') - && !str_starts_with($name, 'patch/') - ) { - $discovered[] = $name; - } - } - if (!empty($discovered)) { - $branches = implode(',', $discovered); - echo "Discovered branches: {$branches}\n"; - } - } - - $updatesFile = rtrim($path, '/') . '/updates.xml'; - if (!file_exists($updatesFile)) { - $this->log('ERROR', "No updates.xml found at {$updatesFile}"); - return 0; - } - - $content = file_get_contents($updatesFile); - $encoded = base64_encode($content); - $giteaUrl = rtrim($giteaUrl, '/'); - $apiBase = "{$giteaUrl}/api/v1/repos/{$org}/{$repo}"; - $vLabel = $version !== '' ? " {$version}" : ''; - - $targets = array_filter( - array_map('trim', explode(',', $branches)), - fn($b) => $b !== '' && $b !== $current - ); - - if (empty($targets)) { - $this->log('ERROR', "No target branches to sync to (current: {$current})"); - return 0; - } - - $synced = 0; - $failed = 0; - - foreach ($targets as $branch) { - $this->log('INFO', "Syncing updates.xml -> {$branch}..."); - - $sha = $this->getFileSha($apiBase, $token, $branch); - - if ($sha === null) { - $this->warning("could not get SHA from {$branch}"); - $failed++; - continue; - } - - $ok = $this->putFile( - $apiBase, - $token, - $branch, - $encoded, - $sha, - "chore: sync updates.xml{$vLabel} from {$current} [skip ci]" - ); - - if ($ok) { - $this->log('INFO', "Synced to {$branch}"); - $synced++; - } else { - $this->warning("push to {$branch} failed"); - $failed++; - } - } - - $this->log('INFO', "Done: {$synced} synced, {$failed} failed"); - return $failed > 0 ? 1 : 0; - } - - private function getFileSha(string $apiBase, string $token, string $branch): ?string - { - $resp = $this->apiCall('GET', "{$apiBase}/contents/updates.xml?ref={$branch}", $token); - return $resp['sha'] ?? null; - } - - private function putFile( - string $apiBase, - string $token, - string $branch, - string $encoded, - string $sha, - string $msg - ): bool { - $resp = $this->apiCall('PUT', "{$apiBase}/contents/updates.xml", $token, [ - 'content' => $encoded, - 'sha' => $sha, - 'message' => $msg, - 'branch' => $branch, - ]); - return $resp !== null; - } - - private function apiCall(string $method, string $url, string $token, ?array $data = null): ?array - { - $headers = [ - "Authorization: token {$token}", - 'Content-Type: application/json', - 'Accept: application/json', - ]; - - $ch = curl_init($url); - curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); - curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_TIMEOUT, 30); - curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); - - if ($data !== null) { - curl_setopt( - $ch, - CURLOPT_POSTFIELDS, - json_encode($data, JSON_UNESCAPED_SLASHES) - ); - } - - $body = curl_exec($ch); - $code = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); - curl_close($ch); - - return ($code >= 200 && $code < 300) - ? (json_decode($body, true) ?: []) - : null; - } -} - -$app = new UpdatesXmlSyncCli(); -exit($app->execute()); diff --git a/cli/version_auto_bump.php b/cli/version_auto_bump.php index 89ce1363..7482b6f5 100644 --- a/cli/version_auto_bump.php +++ b/cli/version_auto_bump.php @@ -68,16 +68,9 @@ class VersionAutoBumpCli extends CliFramework $cli = __DIR__; $php = '"' . PHP_BINARY . '"'; - // Auto-detect watch path from manifest.xml if not provided - if (empty($watchPath)) { - $manifestFile = realpath($path) . '/.mokogitea/manifest.xml'; - if (file_exists($manifestFile)) { - $xml = @simplexml_load_file($manifestFile); - if ($xml && isset($xml->build->{'entry-point'})) { - $watchPath = (string) $xml->build->{'entry-point'}; - } - } - } + // Watch-path was previously read from .mokogit/manifest.xml . + // That manifest is retired; when --watch-path is not supplied we simply skip the + // change-gate and always bump (the prior no-manifest behavior). // Check if code files actually changed (skip bump for docs/config-only changes) $shouldBump = true; @@ -142,6 +135,14 @@ class VersionAutoBumpCli extends CliFramework // Step 4: Version consistency check and fix exec("{$php} {$cli}/version_check.php --path " . escapeshellarg($path) . " --fix 2>&1", $checkOutput); + // Step 4b (#351/#354): keep Joomla #__schemas in lockstep with the stamped manifest. + // Must run AFTER version_set_platform/version_check have stamped each manifest , + // and BEFORE the git commit below so markers are staged in the same bump commit. + $markerRoot = realpath($path) ?: $path; + foreach ($this->writeSchemaMarkers($markerRoot) as $marker) { + echo "Schema marker: {$marker}\n"; + } + // Re-read version (now includes suffix from version_set_platform) $suffixMap = [ 'dev' => '-dev', @@ -176,11 +177,11 @@ class VersionAutoBumpCli extends CliFramework $cdRoot = $cd . escapeshellarg($root); @shell_exec( $cdRoot . " && git config --local user.email" - . " \"gitea-actions[bot]@mokoconsulting.tech\"" + . " \"mokogit-actions[bot]@mokoconsulting.tech\"" ); @shell_exec( $cdRoot . " && git config --local user.name" - . " \"gitea-actions[bot]\"" + . " \"mokogit-actions[bot]\"" ); if (!empty($repoUrl)) { @@ -196,8 +197,8 @@ class VersionAutoBumpCli extends CliFramework : "chore(version): set {$stability} suffix {$displayVersion} [skip ci]"; @shell_exec( $cdRoot . " && git commit -m " . escapeshellarg($commitMsg) - . " --author=\"gitea-actions[bot]" - . " \"" + . " --author=\"mokogit-actions[bot]" + . " \"" ); $pushResult = @shell_exec( @@ -209,6 +210,94 @@ class VersionAutoBumpCli extends CliFramework echo "Bumped to {$displayVersion}\n"; return 0; } + + /** + * Issues #351/#354 — keep Joomla #__schemas in lockstep with the manifest version. + * + * Joomla advances #__schemas only to the highest schema-update file whose version is + * <= the manifest . When auto-bump climbs the manifest without adding a matching + * marker, #__schemas freezes at the last real migration and com_installer perpetually + * reports the component "a schema version behind". For every Joomla extension manifest that + * declares , write a comment-only no-op marker named + * exactly .sql (idempotent). Reading the version back out of the stamped + * manifest guarantees the filename equals — never exceeds — the manifest version. + * + * @param string $root Repository root. + * @return string[] Marker paths created (each suffixed " (would create)" under --dry-run). + */ + private function writeSchemaMarkers(string $root): array + { + $created = []; + + // Joomla manifests may sit at the repo root or under a source/packages tree. + $manifests = array_unique(array_merge( + glob("{$root}/*.xml") ?: [], + glob("{$root}/*/*.xml") ?: [], + glob("{$root}/*/packages/*/*.xml") ?: [] + )); + + foreach ($manifests as $file) { + $xml = @simplexml_load_file($file); + + if ($xml === false) { + continue; + } + + // Only Joomla extension manifests that actually declare a schema update path. + if (!isset($xml->update->schemas->schemapath)) { + continue; + } + + $version = trim((string) $xml->version); + + // Guard: only stamp when the manifest carries a well-formed platform version. + if (!preg_match('/^\d{2}\.\d{2}\.\d{2}((?:-(?:dev|alpha|beta|rc))+)?$/', $version)) { + continue; + } + + // Resolve the admin-relative root: . + $baseDir = dirname($file); + $adminFolder = isset($xml->administration->files['folder']) + ? trim((string) $xml->administration->files['folder']) + : ''; + $adminDir = $adminFolder !== '' ? "{$baseDir}/{$adminFolder}" : $baseDir; + + // One marker per driver-specific schemapath (mysql, postgresql, …). + foreach ($xml->update->schemas->schemapath as $schemapath) { + $rel = trim((string) $schemapath); + + if ($rel === '') { + continue; + } + + $dir = "{$adminDir}/{$rel}"; + $marker = "{$dir}/{$version}.sql"; + + // Idempotent: never overwrite an existing marker (real or prior no-op). + if (file_exists($marker)) { + continue; + } + + if ($this->dryRun) { + $created[] = "{$marker} (would create)"; + continue; + } + + if (!is_dir($dir) && !@mkdir($dir, 0755, true) && !is_dir($dir)) { + $this->log('WARNING', "Could not create schemapath dir: {$dir}"); + continue; + } + + $body = "/* {$version} — no schema changes (auto version marker) */\n"; + + if (file_put_contents($marker, $body) !== false) { + $created[] = $marker; + } + } + } + + return $created; + } } $app = new VersionAutoBumpCli(); diff --git a/cli/version_bump.php b/cli/version_bump.php index a29e79e4..fd22b5f9 100644 --- a/cli/version_bump.php +++ b/cli/version_bump.php @@ -44,24 +44,8 @@ class VersionBumpCli extends CliFramework $mokoVersion = null; $existingSuffix = ''; $versionPrefix = ''; - $mokoManifest = "{$root}/.mokogitea/manifest.xml"; - $mokoContent = ''; - if (file_exists($mokoManifest)) { - $mokoContent = file_get_contents($mokoManifest); - if (preg_match('#(\d{2}\.\d{2}\.\d{2})((?:-(?:dev|alpha|beta|rc))+)?#', $mokoContent, $m)) { - $mokoVersion = $m[1]; - $existingSuffix = $m[2] ?? ''; - } - // Read version_prefix from manifest.xml (supports nested and flat structure) - $xml = @simplexml_load_file($mokoManifest); - if ($xml !== false) { - $prefix = (string)($xml->identity->version_prefix ?? ''); - if ($prefix === '') { - $prefix = (string)($xml->version_prefix ?? ''); - } - $versionPrefix = $prefix; - } - } + // .mokogit/manifest.xml retired — no longer a version/prefix source ($versionPrefix + // stays empty; README.md and platform files below drive the bump). $readmeVersion = null; $readme = "{$root}/README.md"; $readmeContent = ''; @@ -172,19 +156,8 @@ class VersionBumpCli extends CliFramework } $newBase = sprintf('%02d.%02d.%02d', $major, $minor, $patch); $newFull = $newBase . $existingSuffix; - if (file_exists($mokoManifest) && !empty($mokoContent)) { - $pattern = '#\d{2}\.\d{2}\.\d{2}' - . '(?:(?:-(?:dev|alpha|beta|rc))+)?#'; - $updated = preg_replace( - $pattern, - "{$newFull}", - $mokoContent, - 1 - ); - if ($updated !== null) { - file_put_contents($mokoManifest, $updated); - } - } + // .mokogit/manifest.xml retired — nothing to write back there; README.md and + // platform manifests below carry the bumped version. if (file_exists($readme) && !empty($readmeContent)) { if (!empty($versionPrefix)) { // Prefix-aware README replacement: preserve prefix, replace only version part @@ -342,9 +315,6 @@ class VersionBumpCli extends CliFramework if (in_array($relPath, $updatedFiles ?? [], true)) { continue; } - if (strpos($relPath, '.mokogitea/manifest.xml') !== false) { - continue; - } $content = @file_get_contents($filePath); if ($content === false) { continue; diff --git a/cli/version_bump_remote.php b/cli/version_bump_remote.php index 759a075b..dbd7467f 100644 --- a/cli/version_bump_remote.php +++ b/cli/version_bump_remote.php @@ -10,7 +10,7 @@ * INGROUP: mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * PATH: /cli/version_bump_remote.php - * BRIEF: Bump version in manifest XML and CHANGELOG.md on a remote branch via Gitea API + * BRIEF: Bump version in manifest XML and CHANGELOG.md on a remote branch via MokoGit API */ declare(strict_types=1); @@ -23,15 +23,15 @@ class VersionBumpRemoteCli extends CliFramework { protected function configure(): void { - $this->setDescription('Bump version in manifest XML and CHANGELOG.md on a remote branch via Gitea API'); + $this->setDescription('Bump version in manifest XML and CHANGELOG.md on a remote branch via MokoGit API'); $this->addArgument('--path', 'Repository root', '.'); $this->addArgument('--branch', 'Target branch to bump (required)', null); $this->addArgument('--bump', 'Bump type: patch | minor | major', 'minor'); - $this->addArgument('--token', 'Gitea API token (or MOKOGITEA_TOKEN env var)', null); - $this->addArgument('--api-base', 'Gitea API base URL for the repo', null); + $this->addArgument('--token', 'MokoGit API token (or MOKOGIT_TOKEN env var)', null); + $this->addArgument('--api-base', 'MokoGit API base URL for the repo', null); $this->addArgument('--no-changelog', 'Skip CHANGELOG.md bump', false); $this->addArgument('--repo', 'Repository path (owner/repo)', null); - $this->addArgument('--gitea-url', 'Gitea instance URL', null); + $this->addArgument('--mokogit-url', 'MokoGit instance URL', null); } protected function run(): int @@ -43,15 +43,15 @@ class VersionBumpRemoteCli extends CliFramework $apiBase = $this->getArgument('--api-base'); $noChangelog = (bool) $this->getArgument('--no-changelog'); $repo = $this->getArgument('--repo'); - $giteaUrl = $this->getArgument('--gitea-url'); + $mokogitUrl = $this->getArgument('--mokogit-url'); if ($token === null) { - $token = getenv('MOKOGITEA_TOKEN') ?: getenv('GITEA_TOKEN') ?: null; + $token = getenv('MOKOGIT_TOKEN') ?: getenv('MOKOGIT_TOKEN') ?: null; } - if ($giteaUrl === null) { - $giteaUrl = getenv('GITEA_URL') ?: 'https://git.mokoconsulting.tech'; + if ($mokogitUrl === null) { + $mokogitUrl = getenv('MOKOGIT_URL') ?: 'https://git.mokoconsulting.tech'; } if ($apiBase === null && $repo !== null) { - $apiBase = rtrim($giteaUrl, '/') . '/api/v1/repos/' . $repo; + $apiBase = rtrim($mokogitUrl, '/') . '/api/v1/repos/' . $repo; } if ($branch === null || $token === null || $apiBase === null) { $this->log('ERROR', "Usage: version_bump_remote.php --branch BRANCH --token TOKEN --api-base URL [--bump minor|patch|major]"); @@ -148,7 +148,7 @@ class VersionBumpRemoteCli extends CliFramework return 0; } - private function giteaApi(string $method, string $url, string $token, ?string $body = null): ?array + private function mokogitApi(string $method, string $url, string $token, ?string $body = null): ?array { $ch = curl_init($url); curl_setopt_array($ch, [ @@ -180,7 +180,7 @@ class VersionBumpRemoteCli extends CliFramework callable $transform, string $commitMessage ): bool { - $file = $this->giteaApi('GET', "{$apiBase}/contents/{$filePath}?ref={$branch}", $token); + $file = $this->mokogitApi('GET', "{$apiBase}/contents/{$filePath}?ref={$branch}", $token); if ($file === null || !isset($file['sha']) || !isset($file['content'])) { return false; } @@ -191,7 +191,7 @@ class VersionBumpRemoteCli extends CliFramework return true; } $payload = json_encode(['content' => base64_encode($newContent), 'sha' => $file['sha'], 'message' => $commitMessage, 'branch' => $branch]); - $result = $this->giteaApi('PUT', "{$apiBase}/contents/{$filePath}", $token, $payload); + $result = $this->mokogitApi('PUT', "{$apiBase}/contents/{$filePath}", $token, $payload); if ($result === null) { $this->log('ERROR', "{$filePath}: failed to update"); return false; diff --git a/cli/version_check.php b/cli/version_check.php index 48b5de27..4df7ab4c 100644 --- a/cli/version_check.php +++ b/cli/version_check.php @@ -38,17 +38,7 @@ class VersionCheckCli extends CliFramework $root = realpath($path) ?: $path; $errors = 0; $versions = []; - $mokoManifest = "{$root}/.mokogitea/manifest.xml"; - if (file_exists($mokoManifest)) { - $xml = @simplexml_load_file($mokoManifest); - if ($xml !== false) { - $v = (string)($xml->identity->version ?? ''); - $base = preg_replace('/(-(dev|alpha|beta|rc))+$/', '', $v); - if (preg_match('/^\d{2}\.\d{2}\.\d{2}$/', $base)) { - $versions['.mokogitea/manifest.xml'] = $base; - } - } - } + // .mokogit/manifest.xml retired — README.md et al. are the version sources now. $readme = "{$root}/README.md"; if (file_exists($readme)) { $content = file_get_contents($readme); @@ -124,19 +114,6 @@ class VersionCheckCli extends CliFramework file_put_contents($readme, $updated); } echo " Fixed: README.md -> {$highestVersion}\n"; } - if (isset($versions['.mokogitea/manifest.xml']) && $versions['.mokogitea/manifest.xml'] !== $highestVersion) { - $content = file_get_contents($mokoManifest); - $vPat = '#\d{2}\.\d{2}\.\d{2}' - . '(?:(?:-(?:dev|alpha|beta|rc))+)?#'; - $updated = preg_replace( - $vPat, - "{$highestVersion}", - $content - ); - if ($updated !== null) { - file_put_contents($mokoManifest, $updated); - } echo " Fixed: .mokogitea/manifest.xml -> {$highestVersion}\n"; - } if (isset($versions['CHANGELOG.md']) && $versions['CHANGELOG.md'] !== $highestVersion) { $content = file_get_contents($changelog); $clPat = '/(VERSION:\s*)\d{2}\.\d{2}\.\d{2}' @@ -177,7 +154,7 @@ class VersionCheckCli extends CliFramework } echo " Fixed: pyproject.toml -> {$highestVersion}\n"; } foreach ($versions as $source => $ver) { - if (in_array($source, ['README.md', 'CHANGELOG.md', '.mokogitea/manifest.xml', 'package.json', 'pyproject.toml'], true)) { + if (in_array($source, ['README.md', 'CHANGELOG.md', 'package.json', 'pyproject.toml'], true)) { continue; } if ($ver === $highestVersion) { continue; diff --git a/cli/version_read.php b/cli/version_read.php index 1569a294..3a5ff821 100644 --- a/cli/version_read.php +++ b/cli/version_read.php @@ -32,33 +32,12 @@ class VersionReadCli extends CliFramework $path = $this->getArgument('--path'); $root = realpath($path) ?: $path; - // -- 1. Read from .mokogitea/manifest.xml (canonical source) -- - $mokoVersion = null; + // The retired .mokogit/manifest.xml is no longer a version source; README.md is now + // canonical (version_prefix, when needed, comes from the MokoGit metadata API, not a + // committed manifest). Default to an empty prefix — non-prefixed repos parse normally. $versionPrefix = ''; - $mokoManifest = "{$root}/.mokogitea/manifest.xml"; - if (file_exists($mokoManifest)) { - $xml = @simplexml_load_file($mokoManifest); - if ($xml !== false) { - $v = (string)($xml->identity->version ?? ''); - if (preg_match('/^\d{2}\.\d{2}\.\d{2}((?:-(?:dev|alpha|beta|rc))+)?$/', $v)) { - $mokoVersion = $v; - } - // Read version_prefix (supports both nested and flat structure) - $prefix = (string)($xml->identity->version_prefix ?? ''); - if ($prefix === '') { - $prefix = (string)($xml->version_prefix ?? ''); - } - $versionPrefix = $prefix; - } - } - // If manifest.xml has a version, that is authoritative - if ($mokoVersion !== null) { - echo $mokoVersion . "\n"; - return 0; - } - - // -- 2. Fallback: README.md -- + // -- 1. README.md (canonical) -- $readmeVersion = null; $readme = "{$root}/README.md"; if (file_exists($readme)) { @@ -151,30 +130,6 @@ class VersionReadCli extends CliFramework return 1; } - // -- Backfill: if manifest.xml exists but lacks , insert it -- - if (file_exists($mokoManifest)) { - $content = file_get_contents($mokoManifest); - if (!preg_match('#\d{2}\.\d{2}\.\d{2}((?:-(?:dev|alpha|beta|rc))+)?#', $content)) { - if (strpos($content, '{$version}\$1", - $content, - 1 - ); - } elseif (strpos($content, '') !== false) { - $content = preg_replace( - '|()|', - " {$version}\n \$1", - $content, - 1 - ); - } - file_put_contents($mokoManifest, $content); - $this->log('ERROR', "Backfilled manifest.xml with version {$version}"); - } - } - echo $version . "\n"; return 0; } diff --git a/cli/version_reset_dev.php b/cli/version_reset_dev.php index ebcf0865..865c1293 100644 --- a/cli/version_reset_dev.php +++ b/cli/version_reset_dev.php @@ -10,22 +10,22 @@ * INGROUP: mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * PATH: /cli/version_reset_dev.php - * BRIEF: Reset platform version to 'development' on a branch via Gitea API + * BRIEF: Reset platform version to 'development' on a branch via MokoGit API */ declare(strict_types=1); require_once __DIR__ . '/../lib/Enterprise/CliFramework.php'; -use MokoCli\CliFramework; +use MokoCli\{CliFramework, PlatformDetector}; class VersionResetDevCli extends CliFramework { protected function configure(): void { - $this->setDescription('Reset platform version to development on a branch via Gitea API'); - $this->addArgument('--token', 'Gitea API token (also reads MOKOGITEA_TOKEN / GITEA_TOKEN env)', ''); - $this->addArgument('--api-base', 'Gitea API base URL for the repo', ''); + $this->setDescription('Reset platform version to development on a branch via MokoGit API'); + $this->addArgument('--token', 'MokoGit API token (also reads MOKOGIT_TOKEN / MOKOGIT_TOKEN env)', ''); + $this->addArgument('--api-base', 'MokoGit API base URL for the repo', ''); $this->addArgument('--branch', 'Target branch (default: dev)', 'dev'); $this->addArgument('--platform', 'Platform type: dolibarr, crm-module, joomla, waas-component', ''); $this->addArgument('--path', 'Repo root for auto-detecting platform from manifest.xml', ''); @@ -41,13 +41,7 @@ class VersionResetDevCli extends CliFramework // Allow token from environment if ($token === '') { - $envToken = getenv('MOKOGITEA_TOKEN'); - if ($envToken !== false && $envToken !== '') { - $token = $envToken; - } - } - if ($token === '') { - $envToken = getenv('GITEA_TOKEN'); + $envToken = getenv('MOKOGIT_TOKEN'); if ($envToken !== false && $envToken !== '') { $token = $envToken; } @@ -93,28 +87,16 @@ class VersionResetDevCli extends CliFramework private function detectPlatform(string $repoPath): ?string { $root = realpath($repoPath) ?: $repoPath; - $manifestXml = "{$root}/.mokogitea/manifest.xml"; - if (!file_exists($manifestXml)) { - return null; - } + // .mokogit/manifest.xml retired — detect from files and return the stamp vocabulary + // this tool's callers expect (crm-module / waas-component), matching the old + // governance.platform value. + $platform = PlatformDetector::toStampPlatform(PlatformDetector::detect($root)); - $xml = @simplexml_load_file($manifestXml); - if ($xml === false) { - return null; - } - - if (isset($xml->governance->platform)) { - $platform = (string) $xml->governance->platform; - if ($platform !== '') { - return $platform; - } - } - - return null; + return $platform !== 'generic' ? $platform : null; } - private function giteaApiCall(string $url, string $token, string $method = 'GET', ?string $body = null): ?array + private function mokogitApiCall(string $url, string $token, string $method = 'GET', ?string $body = null): ?array { $ch = curl_init($url); if ($ch === false) { @@ -161,7 +143,7 @@ class VersionResetDevCli extends CliFramework { // Search the repo tree for mod*.class.php files $treeUrl = "{$apiBase}/git/trees/{$branch}?recursive=true"; - $tree = $this->giteaApiCall($treeUrl, $token); + $tree = $this->mokogitApiCall($treeUrl, $token); if ($tree === null || !isset($tree['tree']) || !is_array($tree['tree'])) { $this->log('ERROR', "Could not read repository tree for branch '{$branch}'."); @@ -191,7 +173,7 @@ class VersionResetDevCli extends CliFramework // GET file contents via API $encodedPath = implode('/', array_map('rawurlencode', explode('/', $filePath))); $fileUrl = "{$apiBase}/contents/{$encodedPath}?ref={$branch}"; - $fileData = $this->giteaApiCall($fileUrl, $token); + $fileData = $this->mokogitApiCall($fileUrl, $token); if ($fileData === null || !isset($fileData['content'])) { echo "Skipping {$filePath}: could not fetch contents.\n"; @@ -233,7 +215,7 @@ class VersionResetDevCli extends CliFramework ]); $putUrl = "{$apiBase}/contents/{$encodedPath}"; - $result = $this->giteaApiCall($putUrl, $token, 'PUT', $putBody); + $result = $this->mokogitApiCall($putUrl, $token, 'PUT', $putBody); if ($result !== null) { echo "Reset: {$filePath} -> \$this->version = 'development'\n"; diff --git a/cli/version_set_platform.php b/cli/version_set_platform.php index 79e1c155..0e6b6c84 100644 --- a/cli/version_set_platform.php +++ b/cli/version_set_platform.php @@ -17,7 +17,7 @@ declare(strict_types=1); require_once __DIR__ . '/../lib/Enterprise/CliFramework.php'; -use MokoCli\{CliFramework, SourceResolver}; +use MokoCli\{CliFramework, SourceResolver, PlatformDetector}; class VersionSetPlatformCli extends CliFramework { @@ -77,34 +77,9 @@ class VersionSetPlatformCli extends CliFramework $root = realpath($path) ?: $path; - // Detect platform — check manifest.xml first, then legacy .mokostandards - $platform = ''; - - // New format: .mokogitea/manifest.xml (XML with tag) - $manifestXml = "{$root}/.mokogitea/manifest.xml"; - if (file_exists($manifestXml)) { - $xml = @simplexml_load_file($manifestXml); - if ($xml && isset($xml->governance->platform)) { - $platform = (string) $xml->governance->platform; - } - } - - // Legacy: .mokostandards YAML file - if (empty($platform)) { - $mokoStandards = "{$root}/.github/.mokostandards"; - if (!file_exists($mokoStandards)) { - $mokoStandards = "{$root}/.mokogitea/manifest.xml"; - } - if (!file_exists($mokoStandards)) { - $mokoStandards = "{$root}/.mokostandards"; - } - if (file_exists($mokoStandards)) { - $content = file_get_contents($mokoStandards); - if (preg_match('/^platform:\s*(.+)/m', $content, $m)) { - $platform = trim($m[1], " \t\n\r\"'"); - } - } - } + // Detect platform from repo files (.mokogit/manifest.xml retired) and translate to + // the stamp vocabulary this tool branches on below (crm-module / waas-component). + $platform = PlatformDetector::toStampPlatform(PlatformDetector::detect($root)); $changed = 0; diff --git a/cli/wiki_sync.php b/cli/wiki_sync.php index 22ba4f85..db54df0d 100644 --- a/cli/wiki_sync.php +++ b/cli/wiki_sync.php @@ -22,7 +22,7 @@ use MokoCli\CliFramework; class WikiSyncCli extends CliFramework { - private string $giteaUrl = 'https://git.mokoconsulting.tech'; + private string $mokogitUrl = 'https://git.mokoconsulting.tech'; private string $token = ''; private string $org = 'MokoConsulting'; private string $sourceRepo = 'mokocli'; @@ -39,7 +39,7 @@ class WikiSyncCli extends CliFramework protected function configure(): void { $this->setDescription('Sync wiki pages from mokocli to template repos'); - $this->addArgument('--token', 'Gitea API token (required)', ''); + $this->addArgument('--token', 'MokoGit API token (required)', ''); $this->addArgument('--org', 'Organization (default: MokoConsulting)', 'MokoConsulting'); $this->addArgument('--source', 'Source repo (default: mokocli)', 'mokocli'); $this->addArgument('--target', 'Target repo (can repeat)', ''); @@ -195,7 +195,7 @@ class WikiSyncCli extends CliFramework private function apiGet(string $endpoint): ?array { - $url = "{$this->giteaUrl}/api/v1{$endpoint}"; + $url = "{$this->mokogitUrl}/api/v1{$endpoint}"; $opts = [ 'http' => [ 'method' => 'GET', @@ -224,7 +224,7 @@ class WikiSyncCli extends CliFramework private function apiWrite(string $method, string $endpoint, string $payload): ?array { - $url = "{$this->giteaUrl}/api/v1{$endpoint}"; + $url = "{$this->mokogitUrl}/api/v1{$endpoint}"; $opts = [ 'http' => [ 'method' => $method, diff --git a/cli/workflow_sync.php b/cli/workflow_sync.php index 8019ec5d..c4e13d21 100644 --- a/cli/workflow_sync.php +++ b/cli/workflow_sync.php @@ -10,8 +10,9 @@ * INGROUP: mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * PATH: /cli/workflow_sync.php - * VERSION: 09.38.05 - * BRIEF: Sync workflows from Generic → platform templates → live repos based on manifest.platform + * VERSION: 09.39.00 + * BRIEF: Sync workflows from Generic → platform templates → live repos based on manifest.platform, + * plus a read-only health-check (--phase health) that alerts on repos missing synced workflows. */ declare(strict_types=1); @@ -24,22 +25,66 @@ class WorkflowSyncCli extends CliFramework { private const PLATFORM_TEMPLATES = [ 'joomla' => 'Template-Joomla', - 'dolibarr' => 'Template-Dolibarr', 'go' => 'Template-Go', - 'mcp' => 'Template-MCP', + // Template-MCP was renamed to Template-NPM. Both the 'mcp' platform (declared by + // the mcp-* repos in metadata) and 'npm'/'node' resolve to it. Pointing 'mcp' at the + // old name yielded a 301 → null → Generic fallback, which made cleanupOrphanedWorkflows + // strip every MCP-specific workflow as an "orphan". Keep this in sync with the org. + 'mcp' => 'Template-NPM', + 'npm' => 'Template-NPM', + 'node' => 'Template-NPM', 'platform' => 'Template-Generic', 'generic' => 'Template-Generic', + // Dot-prefixed org repos (.mokogit, .vault, …) sync from Template-Dot. These repos + // carry no platform in metadata, so getRepoPlatform() maps them to 'dot' by name. + 'dot' => 'Template-Dot', + // NOTE: 'dolibarr' intentionally omitted — Template-Dolibarr no longer exists and no + // repo declares platform=dolibarr; it falls through to DEFAULT_TEMPLATE (Generic). ]; private const DEFAULT_TEMPLATE = 'Template-Generic'; private const GENERIC_TEMPLATE = 'Template-Generic'; + /** + * Canonical workflow directory in every repo. + * + * NOTE: This moved from '.mokogit/workflows' to '.mokogit/workflows' during the + * MokoGit → MokoGIT rebrand. The old constant was hardcoded inline in every path, + * so when the repos migrated the sync silently read/wrote a directory that no longer + * existed — Phase 1/2 both saw "0 workflows" and did nothing. Keep this in ONE place. + */ + private const WORKFLOW_DIR = '.mokogit/workflows'; + + /** Default ntfy endpoint for critical drift alerts (matches notify.yml / gitleaks.yml). */ + private const DEFAULT_NTFY_URL = 'https://ntfy.mokoconsulting.tech'; + private const DEFAULT_NTFY_TOPIC = 'mokogit-ops'; + /** * Workflows to exclude per platform during sync. * Key = platform name (matching PLATFORM_TEMPLATES keys), Value = array of workflow filenames to skip. */ private const PLATFORM_EXCLUDES = [ 'joomla' => ['deploy-manual.yml'], + // Dot-repos (.mokogit, .vault, …) are config/data repos: no build, no versioned + // releases, no deploy. Curate Template-Dot down to governance/security/hygiene only by + // excluding the build, versioning, release-pipeline, and deploy workflows. Applied in + // both Phase 1 (Generic → Template-Dot) and Phase 2 (Template-Dot → dot-repos). + 'dot' => [ + // build/test + 'ci-generic.yml', + // versioning + 'auto-bump.yml', + 'version-set.yml', + // release pipeline + 'auto-release.yml', + 'pre-release.yml', + 'rc-revert.yml', + 'cascade-dev.yml', + // deploy (never in Generic, excluded defensively) + 'deploy-dev.yml', + 'deploy-prod.yml', + 'deploy-rc.yml', + ], ]; private int $updated = 0; @@ -50,17 +95,24 @@ class WorkflowSyncCli extends CliFramework protected function configure(): void { $this->setDescription('Sync workflows from Generic → platform templates → live repos based on manifest.platform'); - $this->addArgument('--gitea-url', 'Gitea URL (default: https://git.mokoconsulting.tech)', 'https://git.mokoconsulting.tech'); - $this->addArgument('--token', 'Gitea API token', ''); + $this->addArgument('--mokogit-url', 'MokoGit URL (default: https://git.mokoconsulting.tech)', 'https://git.mokoconsulting.tech'); + $this->addArgument('--token', 'MokoGit API token', ''); $this->addArgument('--org', 'Target organization', ''); $this->addArgument('--branch', 'Target branch (default: main)', 'main'); - $this->addArgument('--phase', 'Phase to run: all, templates, repos (default: all)', 'all'); + $this->addArgument('--phase', 'Phase to run: all, templates, repos, health (default: all)', 'all'); $this->addArgument('--platform-filter', 'Only sync repos matching this platform', ''); + $this->addArgument('--repo-filter', 'Only sync/check these repos (comma-separated names)', ''); + + // Health-check (--phase health) options — all read-only unless an alert flag is set. + $this->addArgument('--alert-ntfy', 'On drift, send a critical ntfy push notification', false); + $this->addArgument('--ntfy-url', 'ntfy server URL', self::DEFAULT_NTFY_URL); + $this->addArgument('--ntfy-topic', 'ntfy topic', self::DEFAULT_NTFY_TOPIC); + $this->addArgument('--alert-issue', 'On drift, open/update a MokoGit issue on each affected repo', false); } protected function run(): int { - $giteaUrl = rtrim($this->getArgument('--gitea-url'), '/'); + $mokogitUrl = rtrim($this->getArgument('--mokogit-url'), '/'); $token = $this->getArgument('--token'); $org = $this->getArgument('--org'); $branch = $this->getArgument('--branch'); @@ -77,11 +129,16 @@ class WorkflowSyncCli extends CliFramework return 1; } - if (!in_array($phase, ['all', 'templates', 'repos'], true)) { - $this->log('ERROR', "--phase must be one of: all, templates, repos (got: {$phase})"); + if (!in_array($phase, ['all', 'templates', 'repos', 'health'], true)) { + $this->log('ERROR', "--phase must be one of: all, templates, repos, health (got: {$phase})"); return 1; } + // Health-check is a standalone, read-only phase — it never syncs. + if ($phase === 'health') { + return $this->runHealthCheck($mokogitUrl, $token, $org, $branch, $platformFilter); + } + $this->log('INFO', "Workflow Sync — org: {$org}, branch: {$branch}, phase: {$phase}"); if ($platformFilter !== '') { @@ -96,7 +153,7 @@ class WorkflowSyncCli extends CliFramework // Phase 1: Sync Generic → Platform Templates if ($phase === 'all' || $phase === 'templates') { - $result = $this->syncGenericToTemplates($giteaUrl, $token, $org, $branch, $platformFilter); + $result = $this->syncGenericToTemplates($mokogitUrl, $token, $org, $branch, $platformFilter); if ($result !== 0) { return $result; @@ -105,7 +162,7 @@ class WorkflowSyncCli extends CliFramework // Phase 2: Sync Platform Templates → Live Repos if ($phase === 'all' || $phase === 'repos') { - $result = $this->syncTemplatesToRepos($giteaUrl, $token, $org, $branch, $platformFilter); + $result = $this->syncTemplatesToRepos($mokogitUrl, $token, $org, $branch, $platformFilter); if ($result !== 0) { return $result; @@ -124,7 +181,7 @@ class WorkflowSyncCli extends CliFramework * Skips platform-specific overrides (files that exist in the platform template but NOT in Generic). */ private function syncGenericToTemplates( - string $giteaUrl, + string $mokogitUrl, string $token, string $org, string $branch, @@ -134,7 +191,7 @@ class WorkflowSyncCli extends CliFramework echo "\n"; // Get all workflow files from Template-Generic - $genericWorkflows = $this->listWorkflows($giteaUrl, $token, $org, self::GENERIC_TEMPLATE, $branch); + $genericWorkflows = $this->listWorkflows($mokogitUrl, $token, $org, self::GENERIC_TEMPLATE, $branch); if ($genericWorkflows === null) { $this->log('ERROR', 'Could not list workflows from ' . self::GENERIC_TEMPLATE); @@ -180,12 +237,12 @@ class WorkflowSyncCli extends CliFramework $this->skipped++; continue; } - $destPath = '.mokogitea/workflows/' . $filename; + $destPath = self::WORKFLOW_DIR . '/' . $filename; $label = "{$templateRepo}/{$filename}"; // Get file content from Generic $sourceContent = $this->getFileContent( - $giteaUrl, $token, $org, + $mokogitUrl, $token, $org, self::GENERIC_TEMPLATE, $destPath, $branch ); @@ -198,7 +255,7 @@ class WorkflowSyncCli extends CliFramework $commitMsg = "chore: sync {$filename} from " . self::GENERIC_TEMPLATE . " [skip ci]"; $this->pushFile( - $giteaUrl, $token, $org, $templateRepo, + $mokogitUrl, $token, $org, $templateRepo, $destPath, $sourceContent, $branch, $commitMsg, $label ); } @@ -212,7 +269,7 @@ class WorkflowSyncCli extends CliFramework * Phase 2: Sync platform template workflows to live repos based on manifest.platform. */ private function syncTemplatesToRepos( - string $giteaUrl, + string $mokogitUrl, string $token, string $org, string $branch, @@ -221,7 +278,13 @@ class WorkflowSyncCli extends CliFramework $this->log('INFO', '=== Phase 2: Sync Platform Templates → Live Repos ==='); echo "\n"; - $repos = $this->fetchOrgRepos($giteaUrl, $token, $org); + $repoFilter = $this->parseRepoFilter(); + + if ($repoFilter !== []) { + $this->log('INFO', 'Repo filter: ' . implode(', ', $repoFilter)); + } + + $repos = $this->fetchOrgRepos($mokogitUrl, $token, $org); if ($repos === null) { return 1; @@ -244,8 +307,13 @@ class WorkflowSyncCli extends CliFramework continue; } + // Apply repo filter + if ($repoFilter !== [] && !in_array($repoName, $repoFilter, true)) { + continue; + } + // Read manifest.platform - $platform = $this->getRepoPlatform($giteaUrl, $token, $org, $repoName, $branch); + $platform = $this->getRepoPlatform($mokogitUrl, $token, $org, $repoName, $branch); // Apply platform filter if ($platformFilter !== '' && $platform !== $platformFilter) { @@ -257,36 +325,44 @@ class WorkflowSyncCli extends CliFramework // Get workflows from the template (cached) if (!isset($templateWorkflowCache[$templateRepo])) { - $workflows = $this->listWorkflows($giteaUrl, $token, $org, $templateRepo, $branch); - - if ($workflows === null) { - $this->log('WARN', "Could not list workflows from {$templateRepo}, falling back to " . self::GENERIC_TEMPLATE); - $workflows = $this->listWorkflows($giteaUrl, $token, $org, self::GENERIC_TEMPLATE, $branch); - } - - $templateWorkflowCache[$templateRepo] = $workflows ?? []; + $templateWorkflowCache[$templateRepo] = + $this->listWorkflows($mokogitUrl, $token, $org, $templateRepo, $branch); } $workflows = $templateWorkflowCache[$templateRepo]; + // SAFETY: if the mapped template can't be listed (renamed/missing repo — e.g. a stale + // PLATFORM_TEMPLATES entry or a not-yet-created template), do NOT fall back to Generic. + // Falling back would treat Generic's set as authoritative and make + // cleanupOrphanedWorkflows() strip this repo's platform-specific workflows. Skip the + // repo and warn so the miss is visible instead of silently destructive. + if ($workflows === null) { + $this->log('WARN', "Template '{$templateRepo}' for platform '{$platform}' is unreachable" + . " — skipping {$repoName} (no sync, no cleanup)."); + continue; + } + if (count($workflows) === 0) { continue; } + $templateFilenames = []; + foreach ($workflows as $workflow) { $filename = $workflow['name']; + $templateFilenames[] = $filename; + $label = "{$repoFullName}/{$filename}"; // Skip platform-excluded workflows if (in_array($filename, self::PLATFORM_EXCLUDES[$platform] ?? [], true)) { fprintf(STDERR, "%-45s | %s\n", $label, 'EXCLUDED (platform)'); $this->skipped++; continue; } - $destPath = '.mokogitea/workflows/' . $filename; - $label = "{$repoFullName}/{$filename}"; + $destPath = self::WORKFLOW_DIR . '/' . $filename; // Get source content from template $sourceContent = $this->getFileContent( - $giteaUrl, $token, $org, + $mokogitUrl, $token, $org, $templateRepo, $destPath, $branch ); @@ -299,21 +375,136 @@ class WorkflowSyncCli extends CliFramework $commitMsg = "chore: sync {$filename} from {$templateRepo} [skip ci]"; $this->pushFile( - $giteaUrl, $token, $org, $repoName, + $mokogitUrl, $token, $org, $repoName, $destPath, $sourceContent, $branch, $commitMsg, $label ); } + + // Cleanup: delete workflows not in the template and not in custom/ + $this->cleanupOrphanedWorkflows( + $mokogitUrl, $token, $org, $repoName, $branch, + $templateFilenames, $repoFullName + ); } echo "\n"; return 0; } + private const CUSTOM_PREFIX = 'custom/'; + + /** + * Parse --repo-filter into a list of repo names (empty ⇒ no filter, process all). + * + * @return string[] + */ + private function parseRepoFilter(): array + { + $raw = (string) $this->getArgument('--repo-filter'); + + return array_values(array_filter(array_map('trim', explode(',', $raw)), fn($n) => $n !== '')); + } + + /** + * Delete workflows in a repo that are not in the template and not under custom/. + */ + private function cleanupOrphanedWorkflows( + string $mokogitUrl, + string $token, + string $org, + string $repoName, + string $branch, + array $templateFilenames, + string $repoFullName + ): void { + $repoWorkflows = $this->listWorkflows($mokogitUrl, $token, $org, $repoName, $branch); + + if ($repoWorkflows === null) { + return; + } + + foreach ($repoWorkflows as $item) { + $name = $item['name'] ?? ''; + $type = $item['type'] ?? 'file'; + + // Skip directories (like custom/) + if ($type !== 'file') { + continue; + } + + // Skip files that exist in the template + if (in_array($name, $templateFilenames, true)) { + continue; + } + + // This file is not in the template — delete it + $destPath = self::WORKFLOW_DIR . '/' . $name; + $label = "{$repoFullName}/{$name}"; + + $this->deleteFile( + $mokogitUrl, $token, $org, $repoName, + $destPath, $branch, + "chore: remove orphaned workflow {$name} [skip ci]", + $label + ); + } + } + + /** + * Delete a file from a repo via the MokoGit API. + */ + private function deleteFile( + string $mokogitUrl, + string $token, + string $org, + string $repoName, + string $filePath, + string $branch, + string $commitMsg, + string $label + ): void { + $existing = $this->apiRequest( + $mokogitUrl, $token, 'GET', + "/api/v1/repos/{$org}/{$repoName}/contents/{$filePath}?ref={$branch}" + ); + + if ($existing['code'] !== 200) { + return; + } + + $data = json_decode($existing['body'], true); + $sha = $data['sha'] ?? ''; + + if ($this->dryRun) { + fprintf(STDERR, "%-45s | %s\n", $label, 'WOULD DELETE'); + return; + } + + $payload = json_encode([ + 'sha' => $sha, + 'message' => $commitMsg, + 'branch' => $branch, + ]); + + $response = $this->apiRequest( + $mokogitUrl, $token, 'DELETE', + "/api/v1/repos/{$org}/{$repoName}/contents/{$filePath}", + $payload + ); + + if ($response['code'] === 200) { + fprintf(STDERR, "%-45s | %s\n", $label, 'DELETED (orphaned)'); + } else { + fprintf(STDERR, "%-45s | %s\n", $label, "DELETE ERROR (HTTP {$response['code']})"); + $this->errors++; + } + } + /** * Push a file to a repo — create or update, skip if identical. */ private function pushFile( - string $giteaUrl, + string $mokogitUrl, string $token, string $org, string $repoName, @@ -324,7 +515,7 @@ class WorkflowSyncCli extends CliFramework string $label ): void { $existing = $this->apiRequest( - $giteaUrl, + $mokogitUrl, $token, 'GET', "/api/v1/repos/{$org}/{$repoName}/contents/" @@ -358,7 +549,7 @@ class WorkflowSyncCli extends CliFramework ]); $response = $this->apiRequest( - $giteaUrl, + $mokogitUrl, $token, 'PUT', "/api/v1/repos/{$org}/{$repoName}/contents/" . $destPath, @@ -386,7 +577,7 @@ class WorkflowSyncCli extends CliFramework ]); $response = $this->apiRequest( - $giteaUrl, + $mokogitUrl, $token, 'POST', "/api/v1/repos/{$org}/{$repoName}/contents/" . $destPath, @@ -407,20 +598,20 @@ class WorkflowSyncCli extends CliFramework } /** - * List workflow files in a repo's .mokogitea/workflows/ directory. + * List workflow files in a repo's .mokogit/workflows/ directory. */ private function listWorkflows( - string $giteaUrl, + string $mokogitUrl, string $token, string $org, string $repoName, string $branch ): ?array { $response = $this->apiRequest( - $giteaUrl, + $mokogitUrl, $token, 'GET', - "/api/v1/repos/{$org}/{$repoName}/contents/.mokogitea/workflows?ref={$branch}" + "/api/v1/repos/{$org}/{$repoName}/contents/" . self::WORKFLOW_DIR . "?ref={$branch}" ); if ($response['code'] !== 200) { @@ -441,7 +632,7 @@ class WorkflowSyncCli extends CliFramework * Get file content from a repo as a raw string. */ private function getFileContent( - string $giteaUrl, + string $mokogitUrl, string $token, string $org, string $repoName, @@ -449,7 +640,7 @@ class WorkflowSyncCli extends CliFramework string $branch ): ?string { $response = $this->apiRequest( - $giteaUrl, + $mokogitUrl, $token, 'GET', "/api/v1/repos/{$org}/{$repoName}/contents/{$filePath}?ref={$branch}" @@ -469,21 +660,29 @@ class WorkflowSyncCli extends CliFramework } /** - * Read a repo's manifest.xml and extract the platform value. - * Returns 'generic' if the manifest is missing or has no platform field. + * Read a repo's platform from the MokoGit metadata API. + * Returns 'generic' if metadata is missing or has no platform field. + * (Replaces the retired .mokogit/manifest.xml lookup — platform now lives + * in the repo Metadata endpoint: GET /api/v1/repos/{owner}/{repo}/metadata.) */ private function getRepoPlatform( - string $giteaUrl, + string $mokogitUrl, string $token, string $org, string $repoName, string $branch ): string { + // Dot-prefixed org repos (.mokogit, .vault, …) sync from Template-Dot regardless of + // metadata (they carry no platform field). Name is authoritative for these. + if (str_starts_with($repoName, '.')) { + return 'dot'; + } + $response = $this->apiRequest( - $giteaUrl, + $mokogitUrl, $token, 'GET', - "/api/v1/repos/{$org}/{$repoName}/contents/.mokogitea/manifest.xml?ref={$branch}" + "/api/v1/repos/{$org}/{$repoName}/metadata" ); if ($response['code'] !== 200) { @@ -492,80 +691,17 @@ class WorkflowSyncCli extends CliFramework $data = json_decode($response['body'], true); - if (!is_array($data) || !isset($data['content'])) { + if (!is_array($data) || empty($data['platform'])) { return 'generic'; } - $xmlContent = base64_decode($data['content']); - - if ($xmlContent === false || $xmlContent === '') { - return 'generic'; - } - - // Suppress XML warnings for malformed manifests - $previous = libxml_use_internal_errors(true); - $xml = simplexml_load_string($xmlContent); - libxml_use_internal_errors($previous); - - if ($xml === false) { - return 'generic'; - } - - // Try (standard location) - $platform = ''; - - // Register namespace if present - $namespaces = $xml->getNamespaces(true); - - if (!empty($namespaces)) { - $ns = reset($namespaces); - $xml->registerXPathNamespace('mp', $ns); - - $nodes = $xml->xpath('//mp:governance/mp:platform'); - - if (!empty($nodes)) { - $platform = trim((string) $nodes[0]); - } - - // Fallback: - if ($platform === '') { - $nodes = $xml->xpath('//mp:identity/mp:platform'); - - if (!empty($nodes)) { - $platform = trim((string) $nodes[0]); - } - } - - // Fallback: top-level - if ($platform === '') { - $nodes = $xml->xpath('//mp:platform'); - - if (!empty($nodes)) { - $platform = trim((string) $nodes[0]); - } - } - } else { - // No namespace - if (isset($xml->governance->platform)) { - $platform = trim((string) $xml->governance->platform); - } elseif (isset($xml->identity->platform)) { - $platform = trim((string) $xml->identity->platform); - } elseif (isset($xml->platform)) { - $platform = trim((string) $xml->platform); - } - } - - if ($platform === '') { - return 'generic'; - } - - return strtolower($platform); + return strtolower(trim((string) $data['platform'])); } /** * Fetch all non-archived repos in an org (paginated). */ - private function fetchOrgRepos(string $giteaUrl, string $token, string $org): ?array + private function fetchOrgRepos(string $mokogitUrl, string $token, string $org): ?array { $this->log('INFO', "Fetching repos from org: {$org}"); @@ -574,7 +710,7 @@ class WorkflowSyncCli extends CliFramework while (true) { $response = $this->apiRequest( - $giteaUrl, + $mokogitUrl, $token, 'GET', "/api/v1/orgs/{$org}/repos?" @@ -615,17 +751,315 @@ class WorkflowSyncCli extends CliFramework return $repos; } + // ========================================================================= + // Phase: health — read-only drift detection + alerting + // ========================================================================= + + private const HEALTH_ISSUE_MARKER = '[workflow-health]'; + /** - * Make an HTTP request to the Gitea API. + * Health-check phase: verify every live repo still has the synced workflows its + * platform template provides, and (optionally) alert on drift. + * + * This closes the exact gap that caused the original outage: the sync treated an + * empty/missing workflow directory as "nothing to do" and moved on silently. Here + * we assert the canonical set is present and fail loudly (non-zero exit) when it + * is not — so a scheduled MokoGit Action, an ntfy push, and/or a MokoGit issue surface + * the problem instead of it rotting undetected. + */ + private function runHealthCheck( + string $mokogitUrl, + string $token, + string $org, + string $branch, + string $platformFilter + ): int { + $alertNtfy = (bool) $this->getArgument('--alert-ntfy'); + $alertIssue = (bool) $this->getArgument('--alert-issue'); + $ntfyUrl = rtrim((string) $this->getArgument('--ntfy-url'), '/'); + $ntfyTopic = (string) $this->getArgument('--ntfy-topic'); + + $this->log('INFO', "Workflow Health-Check — org: {$org}, branch: {$branch}"); + + if ($platformFilter !== '') { + $this->log('INFO', "Platform filter: {$platformFilter}"); + } + + $repoFilter = $this->parseRepoFilter(); + + if ($repoFilter !== []) { + $this->log('INFO', 'Repo filter: ' . implode(', ', $repoFilter)); + } + + echo "\n"; + + $repos = $this->fetchOrgRepos($mokogitUrl, $token, $org); + + if ($repos === null) { + return self::EXIT_FAILURE; + } + + $this->log('INFO', 'Scanning ' . count($repos) . " repo(s) in \"{$org}\"."); + echo "\n"; + + $templateCache = []; + $unhealthy = []; + $checked = 0; + + foreach ($repos as $repoFullName) { + [, $repoName] = explode('/', $repoFullName, 2); + + if (str_starts_with($repoName, 'Template-')) { + continue; + } + + $platform = $this->getRepoPlatform($mokogitUrl, $token, $org, $repoName, $branch); + + if ($platformFilter !== '' && $platform !== $platformFilter) { + continue; + } + + if ($repoFilter !== [] && !in_array($repoName, $repoFilter, true)) { + continue; + } + + // A repo that has no such branch is simply out of scope for this run + // (e.g. single-branch repos have no 'dev'), not unhealthy. + if (!$this->branchExists($mokogitUrl, $token, $org, $repoName, $branch)) { + continue; + } + + $templateRepo = self::PLATFORM_TEMPLATES[$platform] ?? self::DEFAULT_TEMPLATE; + + // Expected set = the template's workflows (cached), minus platform excludes. + // Do NOT fall back to Generic when the mapped template is unreachable — that would + // silently assess against the wrong baseline. Record null (missing) distinctly. + if (!array_key_exists($templateRepo, $templateCache)) { + $tpl = $this->listWorkflows($mokogitUrl, $token, $org, $templateRepo, $branch); + $templateCache[$templateRepo] = $tpl === null + ? null + : array_map(fn($w) => $w['name'], $tpl); + } + + if ($templateCache[$templateRepo] === null) { + $this->log('WARN', "Template '{$templateRepo}' for platform '{$platform}' is unreachable" + . " — cannot assess {$repoName}."); + continue; + } + + $expected = array_values(array_diff( + $templateCache[$templateRepo], + self::PLATFORM_EXCLUDES[$platform] ?? [] + )); + + // Template itself is empty — we can't assert anything meaningful. + if (count($expected) === 0) { + continue; + } + + $repoList = $this->listWorkflows($mokogitUrl, $token, $org, $repoName, $branch); + $actual = array_map(fn($w) => $w['name'], $repoList ?? []); + + $missing = $this->evaluateRepoHealth($expected, $actual); + $checked++; + + if (count($missing) > 0) { + $unhealthy[$repoName] = [ + 'full' => $repoFullName, + 'platform' => $platform, + 'expected' => count($expected), + 'present' => count(array_intersect($expected, $actual)), + 'missing' => $missing, + ]; + } + } + + echo "\n"; + + if (count($unhealthy) === 0) { + $this->success("All {$checked} in-scope repo(s) have their synced workflows on '{$branch}'."); + return self::EXIT_SUCCESS; + } + + $rows = []; + + foreach ($unhealthy as $repo => $info) { + $rows[] = [ + $repo, + $info['platform'], + "{$info['present']}/{$info['expected']}", + (string) count($info['missing']), + ]; + } + + $this->log('ERROR', count($unhealthy) . " of {$checked} repo(s) are MISSING synced workflows on '{$branch}':"); + $this->table(['Repo', 'Platform', 'Present', 'Missing'], $rows); + + if ($alertNtfy) { + $this->sendNtfyAlert($ntfyUrl, $ntfyTopic, $org, $branch, $unhealthy); + } + + if ($alertIssue) { + foreach ($unhealthy as $repo => $info) { + $this->openHealthIssue($mokogitUrl, $token, $org, $repo, $branch, $info); + } + } + + return self::EXIT_FAILURE; + } + + /** + * Health verdict policy — given the workflows a repo SHOULD have (its platform + * template's set, minus platform excludes) and the workflows it ACTUALLY has, + * return the filenames that are missing. Non-empty result ⇒ repo is unhealthy. + * + * Default policy: every expected workflow must be present by exact filename. + * Extra files (repo-specific custom/ workflows, in-flight RC workflows) are + * ignored — we assert the canonical set is PRESENT, never that nothing else exists. + * + * @param string[] $expected Canonical workflow filenames the repo should carry. + * @param string[] $actual Workflow filenames currently in the repo. + * @return string[] Missing filenames (empty ⇒ healthy). + */ + private function evaluateRepoHealth(array $expected, array $actual): array + { + return array_values(array_diff($expected, $actual)); + } + + /** + * Return true when the given branch exists in the repo. + */ + private function branchExists( + string $mokogitUrl, + string $token, + string $org, + string $repoName, + string $branch + ): bool { + $response = $this->apiRequest( + $mokogitUrl, $token, 'GET', + "/api/v1/repos/{$org}/{$repoName}/branches/{$branch}" + ); + + return $response['code'] === 200; + } + + /** + * Send a critical ntfy push notification about drift. + * Matches the org convention in .mokogit/workflows/notify.yml (Title/Priority/Tags headers). + */ + private function sendNtfyAlert( + string $ntfyUrl, + string $topic, + string $org, + string $branch, + array $unhealthy + ): void { + if ($ntfyUrl === '' || $topic === '') { + $this->warn('ntfy alert requested but --ntfy-url/--ntfy-topic is empty; skipping.'); + return; + } + + $count = count($unhealthy); + $names = implode(', ', array_keys($unhealthy)); + $title = "Workflow drift: {$count} repo(s) missing workflows"; + $body = "Org {$org} ({$branch}): {$count} repo(s) missing synced " . self::WORKFLOW_DIR . "/.\n{$names}"; + + if ($this->dryRun) { + $this->log('INFO', "[DRY RUN] Would send critical ntfy to {$ntfyUrl}/{$topic}: {$title}"); + return; + } + + $ch = curl_init("{$ntfyUrl}/{$topic}"); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $body); + curl_setopt($ch, CURLOPT_HTTPHEADER, [ + "Title: {$title}", + 'Priority: urgent', + 'Tags: rotating_light,warning', + ]); + curl_exec($ch); + $code = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); + curl_close($ch); + + if ($code >= 200 && $code < 300) { + $this->success("Sent critical ntfy alert to {$ntfyUrl}/{$topic}."); + } else { + $this->warn("ntfy alert failed (HTTP {$code})."); + } + } + + /** + * Open a MokoGit issue on an affected repo describing the missing workflows. + * Idempotent: skips if an open issue carrying the marker already exists. + */ + private function openHealthIssue( + string $mokogitUrl, + string $token, + string $org, + string $repoName, + string $branch, + array $info + ): void { + // Idempotency — don't stack duplicate issues on repeated runs. + $existing = $this->apiRequest( + $mokogitUrl, $token, 'GET', + "/api/v1/repos/{$org}/{$repoName}/issues?state=open&type=issues&limit=50" + ); + + if ($existing['code'] === 200) { + $issues = json_decode($existing['body'], true) ?: []; + + foreach ($issues as $iss) { + if (str_contains((string) ($iss['title'] ?? ''), self::HEALTH_ISSUE_MARKER)) { + $this->log('INFO', "{$repoName}: health issue already open (#{$iss['number']}), skipping."); + return; + } + } + } + + $missingList = implode("\n", array_map(fn($f) => "- `{$f}`", $info['missing'])); + $title = self::HEALTH_ISSUE_MARKER . " Missing synced workflows on {$branch}"; + $body = 'Automated health-check found this repository is missing ' + . count($info['missing']) . " workflow(s) that its platform template " + . "(`{$info['platform']}`) provides in `" . self::WORKFLOW_DIR . "/` on `{$branch}`:\n\n" + . $missingList + . "\n\nRestore with:\n\n```\nphp bin/moko workflow:sync --org {$org} --branch {$branch} --token \$TOKEN\n```" + . "\n\nFiled by workflow_sync.php --phase health."; + + if ($this->dryRun) { + $this->log('INFO', "[DRY RUN] Would open health issue on {$org}/{$repoName}."); + return; + } + + $payload = json_encode(['title' => $title, 'body' => $body]); + + $resp = $this->apiRequest( + $mokogitUrl, $token, 'POST', + "/api/v1/repos/{$org}/{$repoName}/issues", + $payload + ); + + if ($resp['code'] === 201) { + $data = json_decode($resp['body'], true); + $this->success("Opened health issue {$org}/{$repoName}#" . ($data['number'] ?? '?') . '.'); + } else { + $this->warn("Failed to open issue on {$org}/{$repoName} (HTTP {$resp['code']})."); + } + } + + /** + * Make an HTTP request to the MokoGit API. */ private function apiRequest( - string $giteaUrl, + string $mokogitUrl, string $token, string $method, string $endpoint, ?string $body = null ): array { - $url = $giteaUrl . $endpoint; + $url = $mokogitUrl . $endpoint; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); diff --git a/index.md b/index.md index 02692f29..ac2e0f34 100644 --- a/index.md +++ b/index.md @@ -61,7 +61,7 @@ Shared library code - GitHub client ### [Wiki](https://git.mokoconsulting.tech/MokoConsulting/mokocli/wiki) -All documentation lives in the Gitea wiki. +All documentation lives in the MokoGit wiki. ### [Tests](tests/) Test scripts diff --git a/lib/Enterprise/ApiClient.php b/lib/Enterprise/ApiClient.php index c766734b..c4959b98 100644 --- a/lib/Enterprise/ApiClient.php +++ b/lib/Enterprise/ApiClient.php @@ -154,7 +154,7 @@ class ApiClient * @param bool $enableCaching Enable response caching * @param string $userAgent User agent string * @param LoggerInterface|null $logger Optional logger - * @param string $authScheme Authorization scheme ('Bearer' for GitHub, 'token' for Gitea) + * @param string $authScheme Authorization scheme ('Bearer' for GitHub, 'token' for MokoGit) */ public function __construct( string $baseUrl, diff --git a/lib/Enterprise/Config.php b/lib/Enterprise/Config.php index b2bd66bb..33b941d0 100644 --- a/lib/Enterprise/Config.php +++ b/lib/Enterprise/Config.php @@ -74,14 +74,14 @@ class Config private const DEFAULT_CONFIG = [ 'version' => '04.00.04', 'environment' => 'development', - 'platform' => 'gitea', + 'platform' => 'mokogit', 'github' => [ 'organization' => 'mokoconsulting-tech', 'rate_limit' => 5000, 'max_retries' => 3, 'timeout' => 30, ], - 'gitea' => [ + 'mokogit' => [ 'url' => 'https://git.mokoconsulting.tech', 'organization' => 'mokoconsulting-tech', 'rate_limit' => 5000, @@ -227,16 +227,16 @@ class Config $configData['github']['organization'] = $org; } - // Gitea token resolution: GA_TOKEN env var (Gitea Actions) - $giteaToken = getenv('GA_TOKEN') ?: ''; - if (!empty($giteaToken)) { - $configData['gitea']['token'] = $giteaToken; + // MokoGit token resolution: GA_TOKEN env var (MokoGit Actions) + $mokogitToken = getenv('GA_TOKEN') ?: ''; + if (!empty($mokogitToken)) { + $configData['mokogit']['token'] = $mokogitToken; } - if ($giteaUrl = getenv('GITEA_URL')) { - $configData['gitea']['url'] = rtrim($giteaUrl, '/'); + if ($mokogitUrl = getenv('MOKOGIT_URL')) { + $configData['mokogit']['url'] = rtrim($mokogitUrl, '/'); } - if ($giteaOrg = getenv('GITEA_ORG')) { - $configData['gitea']['organization'] = $giteaOrg; + if ($mokogitOrg = getenv('MOKOGIT_ORG')) { + $configData['mokogit']['organization'] = $mokogitOrg; } // Logging configuration diff --git a/lib/Enterprise/GitHubAdapter.php b/lib/Enterprise/GitHubAdapter.php index 5fa23b9e..4a4209ac 100644 --- a/lib/Enterprise/GitHubAdapter.php +++ b/lib/Enterprise/GitHubAdapter.php @@ -419,7 +419,7 @@ class GitHubAdapter implements GitPlatformAdapter public function migrateRepository(array $options): array { - throw new RuntimeException('Repository migration is not supported on GitHub — use Gitea\'s built-in migration'); + throw new RuntimeException('Repository migration is not supported on GitHub — use MokoGit\'s built-in migration'); } // ────────────────────────────────────────────── diff --git a/lib/Enterprise/GitPlatformAdapter.php b/lib/Enterprise/GitPlatformAdapter.php index 3fa2a943..661b9bef 100644 --- a/lib/Enterprise/GitPlatformAdapter.php +++ b/lib/Enterprise/GitPlatformAdapter.php @@ -11,7 +11,7 @@ * INGROUP: MokoPlatform.Enterprise * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * PATH: /lib/Enterprise/GitPlatformAdapter.php - * BRIEF: Interface defining all git platform operations for GitHub/Gitea abstraction + * BRIEF: Interface defining all git platform operations for GitHub/MokoGit abstraction */ declare(strict_types=1); @@ -22,7 +22,7 @@ namespace MokoCli; * Git Platform Adapter Interface * * Defines all platform operations required by mokocli automation. - * Implementations exist for GitHub (GitHubAdapter) and Gitea (MokoGiteaAdapter), + * Implementations exist for GitHub (GitHubAdapter) and MokoGit (MokoGitAdapter), * allowing scripts to work against either platform transparently. * * @package MokoPlatform\Enterprise @@ -37,7 +37,7 @@ interface GitPlatformAdapter /** * Get the platform name identifier. * - * @return string 'github' or 'gitea' + * @return string 'github' or 'mokogit' */ public function getPlatformName(): string; @@ -51,14 +51,14 @@ interface GitPlatformAdapter /** * Get the workflow directory name for this platform. * - * @return string '.github/workflows' or '.mokogitea/workflows' + * @return string '.github/workflows' or '.mokogit/workflows' */ public function getWorkflowDir(): string; /** * Get the platform-specific metadata directory. * - * @return string '.github' or '.mokogitea' + * @return string '.github' or '.mokogit' */ public function getMetadataDir(): string; @@ -104,7 +104,7 @@ interface GitPlatformAdapter /** * Get the environment variable name for step summary output (CI-specific). * - * @return string 'GITHUB_STEP_SUMMARY' or 'GITEA_STEP_SUMMARY' + * @return string 'GITHUB_STEP_SUMMARY' or 'MOKOGIT_STEP_SUMMARY' */ public function getStepSummaryEnvVar(): string; @@ -379,7 +379,7 @@ interface GitPlatformAdapter * @param string $org Organization name * @param string $repo Repository name * @param int $number Issue/PR number - * @param array $labels Label names (GitHub) or label IDs (Gitea) + * @param array $labels Label names (GitHub) or label IDs (MokoGit) * @return array API response */ public function addIssueLabels(string $org, string $repo, int $number, array $labels): array; @@ -391,7 +391,7 @@ interface GitPlatformAdapter /** * Set branch protection rules. * - * On GitHub this maps to rulesets; on Gitea to branch_protections. + * On GitHub this maps to rulesets; on MokoGit to branch_protections. * * @param string $org Organization name * @param string $repo Repository name @@ -450,13 +450,13 @@ interface GitPlatformAdapter public function paginateAll(string $endpoint, array $params = [], int $perPage = 100): array; // ────────────────────────────────────────────── - // Migration (Gitea-specific, no-op on GitHub) + // Migration (MokoGit-specific, no-op on GitHub) // ────────────────────────────────────────────── /** * Migrate a repository from an external service. * - * On Gitea, this calls POST /api/v1/repos/migrate. + * On MokoGit, this calls POST /api/v1/repos/migrate. * On GitHub, this is a no-op (throws UnsupportedOperationException). * * @param array $options Migration options (clone_addr, service, auth_token, etc.) diff --git a/lib/Enterprise/ManifestParser.php b/lib/Enterprise/ManifestParser.php index 77653cd3..66426ee5 100644 --- a/lib/Enterprise/ManifestParser.php +++ b/lib/Enterprise/ManifestParser.php @@ -26,7 +26,7 @@ use SimpleXMLElement; * MokoCli Parser * * Reads, writes, and validates the manifest.xml repository manifest. - * The file uses XML format (no file extension) and lives at .mokogitea/manifest.xml. + * The file uses XML format (no file extension) and lives at .mokogit/manifest.xml. * * @package MokoPlatform\Enterprise * @version 04.07.00 diff --git a/lib/Enterprise/ManifestReader.php b/lib/Enterprise/ManifestReader.php deleted file mode 100644 index be771197..00000000 --- a/lib/Enterprise/ManifestReader.php +++ /dev/null @@ -1,194 +0,0 @@ -#!/usr/bin/env php - - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - * FILE INFORMATION - * DEFGROUP: mokocli.Enterprise - * INGROUP: mokocli - * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli - * PATH: /lib/Enterprise/ManifestReader.php - * BRIEF: Read and parse .mokogitea/manifest.xml — shared across all CLI tools - */ - -declare(strict_types=1); - -namespace MokoCli; - -/** - * Manifest Reader - * - * Parses .mokogitea/manifest.xml and provides typed access to all fields. - * Used by CLI tools and the Enterprise library to determine platform, - * build configuration, and deployment settings from the repository manifest. - * - * @since 09.01.00 - */ -class ManifestReader -{ - /** @var array Parsed manifest fields */ - private array $fields = []; - - /** @var bool Whether a manifest was found and parsed */ - private bool $loaded = false; - - /** - * Load manifest from a repository root directory. - * - * @param string $root Repository root path - * @return self - */ - public static function fromPath(string $root): self - { - $reader = new self(); - $reader->load($root); - return $reader; - } - - /** - * Load and parse the manifest file. - * - * @param string $root Repository root path - */ - public function load(string $root): void - { - $candidates = [ - "{$root}/.mokogitea/manifest.xml", - "{$root}/.mokogitea/.manifest.xml", - "{$root}/.mokogitea/.mokocli", - ]; - - $manifestFile = null; - foreach ($candidates as $candidate) { - if (file_exists($candidate)) { - $manifestFile = $candidate; - break; - } - } - - if ($manifestFile === null) { - return; - } - - $xml = @simplexml_load_file($manifestFile); - if ($xml === false) { - // Fallback: YAML legacy format - $content = file_get_contents($manifestFile); - if (preg_match('/^platform:\s*(.+)/m', $content, $m)) { - $this->fields['platform'] = trim($m[1], " \t\n\r\"'"); - } - $this->loaded = true; - return; - } - - $this->fields = [ - 'name' => (string)($xml->identity->name ?? ''), - 'org' => (string)($xml->identity->org ?? ''), - 'description' => (string)($xml->identity->description ?? ''), - 'license' => (string)($xml->identity->license ?? ''), - 'license-spdx' => (string)($xml->identity->license['spdx'] ?? ''), - 'version' => (string)($xml->identity->version ?? ''), - 'platform' => (string)($xml->governance->platform ?? ''), - 'standards-version' => (string)($xml->governance->{"standards-version"} ?? ''), - 'language' => (string)($xml->build->language ?? ''), - 'package-type' => (string)($xml->build->{"package-type"} ?? ''), - 'entry-point' => (string)($xml->build->{"entry-point"} ?? ''), - 'source-dir' => (string)($xml->deploy->{"source-dir"} ?? ''), - 'remote-subdir' => (string)($xml->deploy->{"remote-subdir"} ?? ''), - 'dev-host' => (string)($xml->deploy->{"dev-host"} ?? ''), - 'demo-host' => (string)($xml->deploy->{"demo-host"} ?? ''), - ]; - - // Strip empty values - $this->fields = array_filter($this->fields, fn($v) => $v !== ''); - $this->loaded = true; - } - - /** - * Whether a manifest was found and loaded. - * - * @return bool - */ - public function isLoaded(): bool - { - return $this->loaded; - } - - /** - * Get a single field value. - * - * @param string $key Field name (e.g. 'platform', 'package-type') - * @param string $default Default value if field is missing - * @return string - */ - public function get(string $key, string $default = ''): string - { - return $this->fields[$key] ?? $default; - } - - /** - * Get the platform slug, normalized to canonical values. - * - * @return string One of: joomla, dolibarr, generic, mcp, nodejs - */ - public function getPlatform(): string - { - $raw = $this->get('platform', 'generic'); - return match ($raw) { - 'waas-component' => 'joomla', - 'crm-module' => 'dolibarr', - default => $raw, - }; - } - - /** - * Get the source/entry-point directory. - * - * Fallback chain: manifest entry-point → source/ → src/ → htdocs/ → 'source'. - * Uses SourceResolver for the directory fallback when no entry-point is set. - * - * @param string $root Repository root for existence checking - * @return string Resolved source directory path (e.g. 'source', 'src', 'htdocs') - */ - public function getSourceDir(string $root = ''): string - { - $entryPoint = $this->get('entry-point', ''); - if ($entryPoint !== '') { - // Strip trailing filename (e.g. source/index.ts → source) - $dir = rtrim(dirname($entryPoint) === '.' ? $entryPoint : dirname($entryPoint), '/'); - if ($root === '' || is_dir("{$root}/{$dir}")) { - return $dir; - } - } - - // Fallback: use SourceResolver (source/ → src/ → htdocs/ → default 'source') - if ($root !== '') { - return SourceResolver::resolve($root); - } - - return 'source'; - } - - /** - * Get the package type for build decisions. - * - * @return string e.g. 'package', 'dolibarr', 'generic', 'mcp-server' - */ - public function getPackageType(): string - { - return $this->get('package-type', 'generic'); - } - - /** - * Get all parsed fields. - * - * @return array - */ - public function getAll(): array - { - return $this->fields; - } -} diff --git a/lib/Enterprise/MokoGiteaAdapter.php b/lib/Enterprise/MokoGitAdapter.php similarity index 92% rename from lib/Enterprise/MokoGiteaAdapter.php rename to lib/Enterprise/MokoGitAdapter.php index 451731f4..cb517d6e 100644 --- a/lib/Enterprise/MokoGiteaAdapter.php +++ b/lib/Enterprise/MokoGitAdapter.php @@ -10,8 +10,8 @@ * DEFGROUP: MokoPlatform.Enterprise.Platform * INGROUP: MokoPlatform.Enterprise * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli - * PATH: /lib/Enterprise/MokoGiteaAdapter.php - * BRIEF: Gitea implementation of GitPlatformAdapter + * PATH: /lib/Enterprise/MokoGitAdapter.php + * BRIEF: MokoGit implementation of GitPlatformAdapter */ declare(strict_types=1); @@ -22,32 +22,32 @@ use Exception; use RuntimeException; /** - * Gitea implementation of GitPlatformAdapter. + * MokoGit implementation of GitPlatformAdapter. * - * Wraps ApiClient with Gitea-specific API semantics: + * Wraps ApiClient with MokoGit-specific API semantics: * - Base URL: https://git.mokoconsulting.tech/api/v1 * - Auth: token {token} * - Pagination: limit + page params * - File ops: POST for create, PUT for update (check existence first) * - Topics: PUT with {"topics": [...]} * - Branch protection: flat API (not rulesets) - * - Workflow dir: .mokogitea/workflows + * - Workflow dir: .mokogit/workflows * * @package MokoPlatform\Enterprise * @since 04.06.10 * @see GitPlatformAdapter */ -class MokoGiteaAdapter implements GitPlatformAdapter +class MokoGitAdapter implements GitPlatformAdapter { - /** @var ApiClient HTTP client for Gitea API calls. */ + /** @var ApiClient HTTP client for MokoGit API calls. */ private ApiClient $apiClient; - /** @var string Base URL for Gitea API (e.g. https://git.mokoconsulting.tech/api/v1). */ + /** @var string Base URL for MokoGit API (e.g. https://git.mokoconsulting.tech/api/v1). */ private string $baseUrl; /** * @param ApiClient $apiClient Configured API client - * @param string $baseUrl Gitea API base URL + * @param string $baseUrl MokoGit API base URL */ public function __construct(ApiClient $apiClient, string $baseUrl = 'https://git.mokoconsulting.tech/api/v1') { @@ -61,7 +61,7 @@ class MokoGiteaAdapter implements GitPlatformAdapter public function getPlatformName(): string { - return 'gitea'; + return 'mokogit'; } public function getBaseUrl(): string @@ -71,12 +71,12 @@ class MokoGiteaAdapter implements GitPlatformAdapter public function getWorkflowDir(): string { - return '.mokogitea/workflows'; + return '.mokogit/workflows'; } public function getMetadataDir(): string { - return '.mokogitea'; + return '.mokogit'; } public function getRepoWebUrl(string $org, string $repo): string @@ -88,7 +88,7 @@ class MokoGiteaAdapter implements GitPlatformAdapter public function getPullRequestWebUrl(string $org, string $repo, int $number): string { - // Gitea uses /pulls/ (not /pull/) for web UI + // MokoGit uses /pulls/ (not /pull/) for web UI $webBase = preg_replace('#/api/v1$#', '', $this->baseUrl); return "{$webBase}/{$org}/{$repo}/pulls/{$number}"; } @@ -106,14 +106,14 @@ class MokoGiteaAdapter implements GitPlatformAdapter public function getBranchWebUrl(string $org, string $repo, string $branch): string { - // Gitea uses /src/branch/ (not /tree/) for web UI + // MokoGit uses /src/branch/ (not /tree/) for web UI $webBase = preg_replace('#/api/v1$#', '', $this->baseUrl); return "{$webBase}/{$org}/{$repo}/src/branch/{$branch}"; } public function getStepSummaryEnvVar(): string { - return 'GITEA_STEP_SUMMARY'; + return 'MOKOGIT_STEP_SUMMARY'; } // ────────────────────────────────────────────── @@ -157,7 +157,7 @@ class MokoGiteaAdapter implements GitPlatformAdapter public function archiveRepo(string $org, string $repo): array { - // Gitea uses PATCH with archived flag, same as GitHub + // MokoGit uses PATCH with archived flag, same as GitHub return $this->apiClient->patch("/repos/{$org}/{$repo}", [ 'archived' => true, ]); @@ -165,7 +165,7 @@ class MokoGiteaAdapter implements GitPlatformAdapter public function setRepoTopics(string $org, string $repo, array $topics): void { - // Gitea uses {"topics": [...]} not {"names": [...]} + // MokoGit uses {"topics": [...]} not {"names": [...]} $this->apiClient->put("/repos/{$org}/{$repo}/topics", [ 'topics' => $topics, ]); @@ -209,12 +209,12 @@ class MokoGiteaAdapter implements GitPlatformAdapter } if ($sha !== null) { - // Update existing file — Gitea uses PUT with SHA + // Update existing file — MokoGit uses PUT with SHA $data['sha'] = $sha; return $this->apiClient->put("/repos/{$org}/{$repo}/contents/{$path}", $data); } - // Create new file — Gitea uses POST + // Create new file — MokoGit uses POST return $this->apiClient->post("/repos/{$org}/{$repo}/contents/{$path}", $data); } @@ -226,7 +226,7 @@ class MokoGiteaAdapter implements GitPlatformAdapter string $message, ?string $branch = null ): array { - // Gitea's delete uses the same endpoint but with DELETE method + // MokoGit's delete uses the same endpoint but with DELETE method // ApiClient::delete() doesn't support a body, so we use the raw approach // For now, this matches GitHubAdapter's limitation return $this->apiClient->delete("/repos/{$org}/{$repo}/contents/{$path}"); @@ -281,7 +281,7 @@ class MokoGiteaAdapter implements GitPlatformAdapter string $body = '', array $options = [] ): array { - // Gitea expects label IDs (int64), not names. Resolve if needed. + // MokoGit expects label IDs (int64), not names. Resolve if needed. if (!empty($options['labels']) && is_string($options['labels'][0] ?? null)) { $labelNames = $options['labels']; $existing = $this->listLabels($org, $repo); @@ -330,7 +330,7 @@ class MokoGiteaAdapter implements GitPlatformAdapter public function createLabel(string $org, string $repo, string $name, string $color, string $description = ''): array { - // Gitea expects color with # prefix + // MokoGit expects color with # prefix $color = ltrim($color, '#'); return $this->apiClient->post("/repos/{$org}/{$repo}/labels", [ 'name' => $name, @@ -341,7 +341,7 @@ class MokoGiteaAdapter implements GitPlatformAdapter public function addIssueLabels(string $org, string $repo, int $number, array $labels): array { - // Gitea requires label IDs, not names. Resolve names to IDs first. + // MokoGit requires label IDs, not names. Resolve names to IDs first. $allLabels = $this->listLabels($org, $repo); $labelMap = []; foreach ($allLabels as $label) { @@ -372,7 +372,7 @@ class MokoGiteaAdapter implements GitPlatformAdapter public function setBranchProtection(string $org, string $repo, string $branch, array $rules): array { - // Gitea uses a flat branch protection API + // MokoGit uses a flat branch protection API $whitelistActions = $rules['whitelist_actions_user'] ?? false; $protection = [ 'branch_name' => $branch, @@ -421,7 +421,7 @@ class MokoGiteaAdapter implements GitPlatformAdapter // Try as a tag first try { $tag = $this->apiClient->get("/repos/{$org}/{$repo}/git/tags/{$ref}"); - // Gitea tag objects have a 'commit' field with the SHA + // MokoGit tag objects have a 'commit' field with the SHA if (isset($tag['commit']['sha'])) { return $tag['commit']['sha']; } @@ -458,7 +458,7 @@ class MokoGiteaAdapter implements GitPlatformAdapter { $all = []; $page = 1; - // Gitea uses 'limit' instead of 'per_page' + // MokoGit uses 'limit' instead of 'per_page' $params['limit'] = $perPage; while (true) { @@ -488,7 +488,7 @@ class MokoGiteaAdapter implements GitPlatformAdapter public function migrateRepository(array $options): array { - // Gitea's built-in migration endpoint + // MokoGit's built-in migration endpoint $data = array_merge([ 'service' => 'github', 'issues' => true, diff --git a/lib/Enterprise/PlatformAdapterFactory.php b/lib/Enterprise/PlatformAdapterFactory.php index 287c8a2d..ceba28f1 100644 --- a/lib/Enterprise/PlatformAdapterFactory.php +++ b/lib/Enterprise/PlatformAdapterFactory.php @@ -44,18 +44,18 @@ class PlatformAdapterFactory * Create a GitPlatformAdapter based on configuration. * * @param Config $config Configuration instance - * @param string|null $platformOverride Force a specific platform ('github' or 'gitea') + * @param string|null $platformOverride Force a specific platform ('github' or 'mokogit') * @return GitPlatformAdapter The constructed adapter * @throws RuntimeException If the platform is not supported or token is missing */ public static function create(Config $config, ?string $platformOverride = null): GitPlatformAdapter { - $platform = $platformOverride ?? $config->getString('platform', 'gitea'); + $platform = $platformOverride ?? $config->getString('platform', 'mokogit'); return match ($platform) { 'github' => self::createGitHubAdapter($config), - 'gitea' => self::createMokoGiteaAdapter($config), - default => throw new RuntimeException("Unsupported git platform: {$platform}. Use 'github' or 'gitea'."), + 'mokogit' => self::createMokoGitAdapter($config), + default => throw new RuntimeException("Unsupported git platform: {$platform}. Use 'github' or 'mokogit'."), }; } @@ -87,62 +87,55 @@ class PlatformAdapterFactory } /** - * Create a MokoGiteaAdapter with configured ApiClient. + * Create a MokoGitAdapter with configured ApiClient. * * @param Config $config Configuration instance - * @return MokoGiteaAdapter Configured Gitea adapter - * @throws RuntimeException If Gitea token is not available + * @return MokoGitAdapter Configured MokoGit adapter + * @throws RuntimeException If MokoGit token is not available */ - private static function createMokoGiteaAdapter(Config $config): MokoGiteaAdapter + private static function createMokoGitAdapter(Config $config): MokoGitAdapter { - $token = $config->getString('gitea.token', ''); + $token = $config->getString('mokogit.token', ''); if (empty($token)) { throw new RuntimeException( - 'Gitea token not found. Set GA_TOKEN environment variable.' + 'MokoGit token not found. Set GA_TOKEN environment variable.' ); } - $giteaUrl = $config->getString('gitea.url', 'https://git.mokoconsulting.tech'); - $apiBaseUrl = rtrim($giteaUrl, '/') . '/api/v1'; + $mokogitUrl = $config->getString('mokogit.url', 'https://git.mokoconsulting.tech'); + $apiBaseUrl = rtrim($mokogitUrl, '/') . '/api/v1'; $apiClient = new ApiClient( baseUrl: $apiBaseUrl, authToken: $token, - maxRequestsPerHour: $config->getInt('gitea.rate_limit', 5000), - maxRetries: $config->getInt('gitea.max_retries', 3), + maxRequestsPerHour: $config->getInt('mokogit.rate_limit', 5000), + maxRetries: $config->getInt('mokogit.max_retries', 3), authScheme: 'token' ); - return new MokoGiteaAdapter($apiClient, $apiBaseUrl); + return new MokoGitAdapter($apiClient, $apiBaseUrl); } /** * Create adapters for both platforms (useful during migration). * * @param Config $config Configuration instance - * @return array{github: GitHubAdapter, gitea: MokoGiteaAdapter} Both adapters + * @return array{github: GitHubAdapter, mokogit: MokoGitAdapter} Both adapters * @throws RuntimeException If either token is missing */ public static function createBoth(Config $config): array { return [ 'github' => self::createGitHubAdapter($config), - 'gitea' => self::createMokoGiteaAdapter($config), + 'mokogit' => self::createMokoGitAdapter($config), ]; } /** - * Sync a file between Gitea (primary) and GitHub (mirror) for a given repo. + * Sync a file between MokoGit (primary) and GitHub (mirror) for a given repo. * - * Reads the file from Gitea and pushes it to GitHub, ensuring both platforms - * serve identical content. Commonly used for updates.xml sync after releases. - * - * @param Config $config Configuration instance - * @param string $repo Repository name - * @param string $branch Branch to sync (default: 'main') - * @param string $filePath Path to the file (default: 'updates.xml') - * @return bool True if sync succeeded or file was already identical - * @throws RuntimeException If either platform is unreachable + * Reads the file from MokoGit and pushes it to GitHub, ensuring both platforms + * serve identical content. */ public static function syncUpdatesBetweenPlatforms( Config $config, @@ -151,18 +144,18 @@ class PlatformAdapterFactory string $filePath = 'updates.xml' ): bool { $adapters = self::createBoth($config); - $giteaOrg = $config->getString('gitea.organization', 'mokoconsulting-tech'); + $mokogitOrg = $config->getString('mokogit.organization', 'mokoconsulting-tech'); $githubOrg = $config->getString('github.organization', 'mokoconsulting-tech'); - // Read from Gitea (primary) + // Read from MokoGit (primary) try { - $giteaFile = $adapters['gitea']->getFileContents($giteaOrg, $repo, $filePath, $branch); + $mokogitFile = $adapters['mokogit']->getFileContents($mokogitOrg, $repo, $filePath, $branch); } catch (\Exception $e) { - throw new RuntimeException("Failed to read {$filePath} from Gitea ({$giteaOrg}/{$repo}): " . $e->getMessage()); + throw new RuntimeException("Failed to read {$filePath} from MokoGit ({$mokogitOrg}/{$repo}): " . $e->getMessage()); } - $giteaContent = base64_decode($giteaFile['content'] ?? ''); - if (empty($giteaContent)) { + $mokogitContent = base64_decode($mokogitFile['content'] ?? ''); + if (empty($mokogitContent)) { return false; } @@ -173,7 +166,7 @@ class PlatformAdapterFactory $githubContent = base64_decode($githubFile['content'] ?? ''); $githubSha = $githubFile['sha'] ?? null; - if ($githubContent === $giteaContent) { + if ($githubContent === $mokogitContent) { return true; } } catch (\Exception $e) { @@ -184,8 +177,8 @@ class PlatformAdapterFactory $githubOrg, $repo, $filePath, - $giteaContent, - "chore(sync): sync {$filePath} from Gitea primary", + $mokogitContent, + "chore(sync): sync {$filePath} from MokoGit primary", $githubSha, $branch ); diff --git a/lib/Enterprise/PlatformDetector.php b/lib/Enterprise/PlatformDetector.php new file mode 100644 index 00000000..47423bc8 --- /dev/null +++ b/lib/Enterprise/PlatformDetector.php @@ -0,0 +1,98 @@ + + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + * FILE INFORMATION + * DEFGROUP: MokoCli.Enterprise + * INGROUP: MokoCli.Enterprise + * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli + * PATH: /lib/Enterprise/PlatformDetector.php + * BRIEF: File-based repository platform detection — the local-tool replacement for the + * retired .mokogit/manifest.xml lookup. Remote/API callers should use + * the MokoGit metadata API instead; this class needs no token or network. + */ + +declare(strict_types=1); + +namespace MokoCli; + +/** + * Detects a repository's platform from the files present on disk. + * + * Returns a CANONICAL platform name. Some legacy tools stamp against their own + * vocabulary (e.g. version_set_platform expects 'crm-module' / 'waas-component'); + * use toStampPlatform() to translate. + */ +final class PlatformDetector +{ + /** + * Detect the canonical platform for a checked-out repository root. + * + * @return string One of: joomla, dolibarr, go, mcp, node, python, platform, generic. + */ + public static function detect(string $root): string + { + // 1. Joomla — pkg_*.xml, Joomla service provider, or template manifest. + $joomla = array_merge( + glob("{$root}/source/pkg_*.xml") ?: [], + glob("{$root}/pkg_*.xml") ?: [], + glob("{$root}/source/packages/*/services/provider.php") ?: [], + glob("{$root}/**/templateDetails.xml") ?: [] + ); + if (!empty($joomla)) { + return 'joomla'; + } + + // 2. Dolibarr — module descriptor class + langs dir. + $doli = array_merge( + glob("{$root}/core/modules/mod*.class.php") ?: [], + glob("{$root}/htdocs/**/core/modules/mod*.class.php") ?: [], + glob("{$root}/class/*.class.php") ?: [] + ); + if (!empty($doli) && is_dir("{$root}/langs")) { + return 'dolibarr'; + } + + // 3. Go + if (file_exists("{$root}/go.mod")) { + return 'go'; + } + + // 4. MCP / Node — package.json; MCP if it looks like an MCP server. + if (file_exists("{$root}/package.json")) { + $pkg = json_decode((string) file_get_contents("{$root}/package.json"), true) ?: []; + $name = (string) ($pkg['name'] ?? ''); + if (str_contains($name, 'mcp') || isset($pkg['dependencies']['@modelcontextprotocol/sdk'])) { + return 'mcp'; + } + return 'node'; + } + + // 5. Python + if (file_exists("{$root}/pyproject.toml") || file_exists("{$root}/setup.py")) { + return 'python'; + } + + // 6. mokocli itself / org-config repos. + if (in_array(basename($root), ['mokocli', 'MokoCLI'], true)) { + return 'platform'; + } + + return 'generic'; + } + + /** + * Translate a canonical platform to the "stamp" vocabulary used by the legacy + * version/release tools (create_repo's TYPE_TO_PLATFORM values). + */ + public static function toStampPlatform(string $canonical): string + { + return match ($canonical) { + 'dolibarr' => 'crm-module', + 'joomla' => 'waas-component', + default => $canonical, + }; + } +} diff --git a/lib/Enterprise/Plugins/ApiPlugin.php b/lib/Enterprise/Plugins/ApiPlugin.php index 9df5af00..0143c9a9 100644 --- a/lib/Enterprise/Plugins/ApiPlugin.php +++ b/lib/Enterprise/Plugins/ApiPlugin.php @@ -288,7 +288,7 @@ class ApiPlugin extends AbstractProjectPlugin 'docker-compose.yml', 'kubernetes/*.yaml', 'tests/ or test/', - '.mokogitea/workflows/* or .gitea/workflows/* or .gitlab-ci.yml', + '.mokogit/workflows/* or .mokogit/workflows/* or .gitlab-ci.yml', 'middleware/ or middlewares/', ]; } @@ -696,8 +696,8 @@ class ApiPlugin extends AbstractProjectPlugin */ private function hasCICD(string $projectPath): bool { - return $this->fileExists($projectPath, '.mokogitea/workflows') || - $this->fileExists($projectPath, '.mokogitea/workflows') || + return $this->fileExists($projectPath, '.mokogit/workflows') || + $this->fileExists($projectPath, '.mokogit/workflows') || $this->fileExists($projectPath, '.gitlab-ci.yml') || $this->fileExists($projectPath, 'Jenkinsfile') || $this->fileExists($projectPath, '.circleci'); diff --git a/lib/Enterprise/Plugins/GenericPlugin.php b/lib/Enterprise/Plugins/GenericPlugin.php index d9ccf5fa..e5dab22d 100644 --- a/lib/Enterprise/Plugins/GenericPlugin.php +++ b/lib/Enterprise/Plugins/GenericPlugin.php @@ -80,8 +80,8 @@ class GenericPlugin extends AbstractProjectPlugin } // Check for CI/CD configuration - $hasCICD = $this->fileExists($projectPath, '.mokogitea/workflows') || - $this->fileExists($projectPath, '.mokogitea/workflows') || + $hasCICD = $this->fileExists($projectPath, '.mokogit/workflows') || + $this->fileExists($projectPath, '.mokogit/workflows') || $this->fileExists($projectPath, '.gitlab-ci.yml') || $this->fileExists($projectPath, '.travis.yml') || $this->fileExists($projectPath, 'Jenkinsfile') || @@ -288,7 +288,7 @@ class GenericPlugin extends AbstractProjectPlugin 'CONTRIBUTING.md', 'CODE_OF_CONDUCT.md', 'SECURITY.md', - '.mokogitea/workflows/* or .gitea/workflows/* or .gitlab-ci.yml', + '.mokogit/workflows/* or .mokogit/workflows/* or .gitlab-ci.yml', 'docs/ or documentation/', 'tests/ or test/', ]; @@ -372,8 +372,8 @@ class GenericPlugin extends AbstractProjectPlugin */ private function hasCICD(string $projectPath): bool { - return $this->fileExists($projectPath, '.mokogitea/workflows') || - $this->fileExists($projectPath, '.mokogitea/workflows') || + return $this->fileExists($projectPath, '.mokogit/workflows') || + $this->fileExists($projectPath, '.mokogit/workflows') || $this->fileExists($projectPath, '.gitlab-ci.yml') || $this->fileExists($projectPath, '.travis.yml') || $this->fileExists($projectPath, 'Jenkinsfile') || diff --git a/lib/Enterprise/Plugins/MobilePlugin.php b/lib/Enterprise/Plugins/MobilePlugin.php index b12318df..084de961 100644 --- a/lib/Enterprise/Plugins/MobilePlugin.php +++ b/lib/Enterprise/Plugins/MobilePlugin.php @@ -344,7 +344,7 @@ class MobilePlugin extends AbstractProjectPlugin 'App icons for all required sizes', 'Splash screen assets', 'tests/ or __tests__/', - '.mokogitea/workflows/* or .gitea/workflows/* or fastlane/', + '.mokogit/workflows/* or .mokogit/workflows/* or fastlane/', 'React Native: metro.config.js', 'Flutter: analysis_options.yaml', 'iOS: Podfile', @@ -551,8 +551,8 @@ class MobilePlugin extends AbstractProjectPlugin */ private function hasCICD(string $projectPath): bool { - return $this->fileExists($projectPath, '.mokogitea/workflows') || - $this->fileExists($projectPath, '.mokogitea/workflows') || + return $this->fileExists($projectPath, '.mokogit/workflows') || + $this->fileExists($projectPath, '.mokogit/workflows') || $this->fileExists($projectPath, '.gitlab-ci.yml') || $this->fileExists($projectPath, 'fastlane') || $this->fileExists($projectPath, '.circleci'); diff --git a/lib/Enterprise/Plugins/NodeJsPlugin.php b/lib/Enterprise/Plugins/NodeJsPlugin.php index 957a645c..8dcf6501 100644 --- a/lib/Enterprise/Plugins/NodeJsPlugin.php +++ b/lib/Enterprise/Plugins/NodeJsPlugin.php @@ -327,7 +327,7 @@ class NodeJsPlugin extends AbstractProjectPlugin '.nvmrc or .node-version', '.editorconfig', 'jest.config.js or vitest.config.js', - '.mokogitea/workflows/* or .gitea/workflows/* or .gitlab-ci.yml', + '.mokogit/workflows/* or .mokogit/workflows/* or .gitlab-ci.yml', ]; } @@ -539,8 +539,8 @@ class NodeJsPlugin extends AbstractProjectPlugin */ private function hasCICD(string $projectPath): bool { - return $this->fileExists($projectPath, '.mokogitea/workflows') || - $this->fileExists($projectPath, '.mokogitea/workflows') || + return $this->fileExists($projectPath, '.mokogit/workflows') || + $this->fileExists($projectPath, '.mokogit/workflows') || $this->fileExists($projectPath, '.gitlab-ci.yml') || $this->fileExists($projectPath, '.travis.yml') || $this->fileExists($projectPath, '.circleci/config.yml'); diff --git a/lib/Enterprise/Plugins/PythonPlugin.php b/lib/Enterprise/Plugins/PythonPlugin.php index 016279c1..1693d732 100644 --- a/lib/Enterprise/Plugins/PythonPlugin.php +++ b/lib/Enterprise/Plugins/PythonPlugin.php @@ -344,7 +344,7 @@ class PythonPlugin extends AbstractProjectPlugin 'pytest.ini or pyproject.toml', '.python-version or .tool-versions', 'Dockerfile', - '.mokogitea/workflows/* or .gitea/workflows/* or .gitlab-ci.yml', + '.mokogit/workflows/* or .mokogit/workflows/* or .gitlab-ci.yml', ]; } @@ -566,8 +566,8 @@ class PythonPlugin extends AbstractProjectPlugin */ private function hasCICD(string $projectPath): bool { - return $this->fileExists($projectPath, '.mokogitea/workflows') || - $this->fileExists($projectPath, '.mokogitea/workflows') || + return $this->fileExists($projectPath, '.mokogit/workflows') || + $this->fileExists($projectPath, '.mokogit/workflows') || $this->fileExists($projectPath, '.gitlab-ci.yml') || $this->fileExists($projectPath, '.travis.yml') || $this->fileExists($projectPath, 'tox.ini'); diff --git a/lib/Enterprise/ProjectMetricsCollector.php b/lib/Enterprise/ProjectMetricsCollector.php index 531a3960..e4e6e11f 100644 --- a/lib/Enterprise/ProjectMetricsCollector.php +++ b/lib/Enterprise/ProjectMetricsCollector.php @@ -124,15 +124,15 @@ class ProjectMetricsCollector // Git $this->collectedMetrics['has_gitignore'] = file_exists("{$path}/.gitignore") ? 1 : 0; - // CI/CD — check both .github/workflows and .gitea/workflows + // CI/CD — check both .github/workflows and .mokogit/workflows $hasGithubWf = is_dir("{$path}/.github/workflows"); - $hasGiteaWf = is_dir("{$path}/.mokogitea/workflows"); - $this->collectedMetrics['has_ci_workflows'] = ($hasGithubWf || $hasGiteaWf) ? 1 : 0; + $hasMokoGitWf = is_dir("{$path}/.mokogit/workflows"); + $this->collectedMetrics['has_ci_workflows'] = ($hasGithubWf || $hasMokoGitWf) ? 1 : 0; $this->collectedMetrics['workflow_count'] = $this->countFiles("{$path}/.github/workflows", '*.yml') + $this->countFiles("{$path}/.github/workflows", '*.yaml') + - $this->countFiles("{$path}/.mokogitea/workflows", '*.yml') + - $this->countFiles("{$path}/.mokogitea/workflows", '*.yaml'); + $this->countFiles("{$path}/.mokogit/workflows", '*.yml') + + $this->countFiles("{$path}/.mokogit/workflows", '*.yaml'); } private function collectNodeJSMetrics(string $path): void diff --git a/lib/Enterprise/RepositoryHealthChecker.php b/lib/Enterprise/RepositoryHealthChecker.php index 38e666cc..35937d8c 100644 --- a/lib/Enterprise/RepositoryHealthChecker.php +++ b/lib/Enterprise/RepositoryHealthChecker.php @@ -204,11 +204,11 @@ class RepositoryHealthChecker 'checks_failed' => 0, ]; - // Check both .github/workflows and .gitea/workflows + // Check both .github/workflows and .mokogit/workflows $githubDir = "{$path}/.github/workflows"; - $giteaDir = "{$path}/.mokogitea/workflows"; - $hasWorkflowDir = is_dir($githubDir) || is_dir($giteaDir); - $workflowDir = is_dir($giteaDir) ? $giteaDir : $githubDir; + $mokogitDir = "{$path}/.mokogit/workflows"; + $hasWorkflowDir = is_dir($githubDir) || is_dir($mokogitDir); + $workflowDir = is_dir($mokogitDir) ? $mokogitDir : $githubDir; // Check workflows directory exists $this->addCheck( @@ -253,15 +253,15 @@ class RepositoryHealthChecker 10 ); - // Check for security scanning workflow (CodeQL on GitHub, Trivy on Gitea) + // Check for security scanning workflow (CodeQL on GitHub, Trivy on MokoGit) $githubWf = "{$path}/.github/workflows"; - $giteaWf = "{$path}/.mokogitea/workflows"; + $mokogitWf = "{$path}/.mokogit/workflows"; $hasSecurityScan = false; if (is_dir($githubWf)) { $hasSecurityScan = !empty(glob("{$githubWf}/*codeql*.yml")) || !empty(glob("{$githubWf}/*codeql*.yaml")); } - if (!$hasSecurityScan && is_dir($giteaWf)) { - $hasSecurityScan = !empty(glob("{$giteaWf}/*trivy*.yml")) || !empty(glob("{$giteaWf}/*trivy*.yaml")); + if (!$hasSecurityScan && is_dir($mokogitWf)) { + $hasSecurityScan = !empty(glob("{$mokogitWf}/*trivy*.yml")) || !empty(glob("{$mokogitWf}/*trivy*.yaml")); } $this->addCheck( $category, @@ -270,7 +270,7 @@ class RepositoryHealthChecker 10 ); - // Check for dependency management (Dependabot on GitHub, Renovate on Gitea) + // Check for dependency management (Dependabot on GitHub, Renovate on MokoGit) $this->addCheck( $category, 'Dependency management configured', diff --git a/lib/Enterprise/RepositorySynchronizer.php b/lib/Enterprise/RepositorySynchronizer.php index 51e0e57d..7db1884f 100644 --- a/lib/Enterprise/RepositorySynchronizer.php +++ b/lib/Enterprise/RepositorySynchronizer.php @@ -62,7 +62,7 @@ class RepositorySynchronizer ?CheckpointManager $checkpoints = null, ?GitPlatformAdapter $adapter = null ) { - $this->adapter = $adapter ?? new MokoGiteaAdapter($apiClient); + $this->adapter = $adapter ?? new MokoGitAdapter($apiClient); $this->logger = $logger; $this->metrics = $metrics; $this->checkpoints = $checkpoints ?? new CheckpointManager('.checkpoints'); @@ -266,7 +266,7 @@ class RepositorySynchronizer /** * Read the platform slug from the remote manifest.xml. - * Checks .mokogitea/manifest.xml, then legacy locations (.mokostandards, .github/.mokostandards). + * Checks .mokogit/manifest.xml, then legacy locations (.mokostandards, .github/.mokostandards). * * @return string|null Platform slug or null if not found/parseable */ @@ -278,7 +278,7 @@ class RepositorySynchronizer "{$metaDir}/.mokostandards", '.mokostandards', ]; - if ($metaDir === '.mokogitea') { + if ($metaDir === '.mokogit') { $paths[] = '.github/.mokostandards'; } @@ -633,11 +633,11 @@ class RepositorySynchronizer } /** - * Migrate legacy .mokostandards to the platform metadata dir (.gitea/ or .github/) + * Migrate legacy .mokostandards to the platform metadata dir (.mokogit/ or .github/) * and convert legacy YAML-like format to the new XML manifest. * * Handles: - * 1. Location migration: root or .github/ → .mokogitea/manifest.xml + * 1. Location migration: root or .github/ → .mokogit/manifest.xml * 2. Format migration: legacy "platform: xxx" → XML manifest * 3. Update existing XML: refresh timestamp */ @@ -654,7 +654,7 @@ class RepositorySynchronizer // ── Collect existing files from all legacy locations ───────── $legacySources = ['.mokostandards']; - if ($metaDir === '.mokogitea') { + if ($metaDir === '.mokogit') { $legacySources[] = '.github/.mokostandards'; } @@ -762,7 +762,7 @@ class RepositorySynchronizer * @param string $org Organization name * @param string $repo Repository name * @param string $platform Detected platform slug - * @param array $repoInfo Gitea API repo object + * @param array $repoInfo MokoGit API repo object * @param string|null $existingContent Current .mokostandards content (XML or legacy) * @return string Well-formed XML content */ @@ -1069,10 +1069,10 @@ class RepositorySynchronizer } // Read all .yml files from the template's workflow directory - $sourceDir = "{$cacheDir}/.mokogitea/workflows"; - // Fallback to legacy path if .mokogitea doesn't exist + $sourceDir = "{$cacheDir}/.mokogit/workflows"; + // Fallback to legacy path if .mokogit doesn't exist if (!is_dir($sourceDir)) { - $sourceDir = "{$cacheDir}/.gitea/workflows"; + $sourceDir = "{$cacheDir}/.mokogit/workflows"; } $shared = []; @@ -1083,9 +1083,9 @@ class RepositorySynchronizer } } - // CODEOWNERS — GitHub only; Gitea doesn't enforce it + // CODEOWNERS — GitHub only; MokoGit doesn't enforce it if ($this->adapter->getPlatformName() === 'github') { - $shared[] = ['templates/mokogitea/CODEOWNERS', '.github/CODEOWNERS']; + $shared[] = ['templates/mokogit/CODEOWNERS', '.github/CODEOWNERS']; } // Platform-specific gitignore (merged, not replaced) diff --git a/lib/Enterprise/SourceResolver.php b/lib/Enterprise/SourceResolver.php index 8b582b02..8ed0eace 100644 --- a/lib/Enterprise/SourceResolver.php +++ b/lib/Enterprise/SourceResolver.php @@ -58,7 +58,7 @@ class SourceResolver * Resolve the source directory name for a repository root. * * Resolution order: - * 1. Gitea Manifest API `entry_point` (when GA_TOKEN/GITEA_TOKEN + GITHUB_REPOSITORY are set) + * 1. MokoGit Manifest API `entry_point` (when GA_TOKEN/MOKOGIT_TOKEN + GITHUB_REPOSITORY are set) * 2. First candidate directory that exists on the filesystem * 3. 'source' as the default (e.g. for new repos being scaffolded) * @@ -84,9 +84,9 @@ class SourceResolver } /** - * Query the MokoGitea Manifest API for the entry_point field. + * Query the MokoGit Manifest API for the entry_point field. * - * Only attempts the call when GA_TOKEN or GITEA_TOKEN is set. Results are + * Only attempts the call when GA_TOKEN or MOKOGIT_TOKEN is set. Results are * cached per org/repo for the lifetime of the process. * * @param string $root Repository root (used to derive org/repo from git remote). @@ -94,7 +94,7 @@ class SourceResolver */ public static function resolveFromApi(string $root): ?string { - $token = getenv('GA_TOKEN') ?: getenv('GITEA_TOKEN') ?: ''; + $token = getenv('GA_TOKEN') ?: getenv('MOKOGIT_TOKEN') ?: ''; if ($token === '') { return null; } @@ -109,7 +109,7 @@ class SourceResolver return self::$apiCache[$cacheKey]; } - $baseUrl = rtrim(getenv('GITEA_URL') ?: 'https://git.mokoconsulting.tech', '/'); + $baseUrl = rtrim(getenv('MOKOGIT_URL') ?: 'https://git.mokoconsulting.tech', '/'); $url = "{$baseUrl}/api/v1/repos/{$org}/{$repo}/manifest"; $ctx = stream_context_create([ diff --git a/lib/Enterprise/UnifiedValidation.php b/lib/Enterprise/UnifiedValidation.php index 8db0afe8..d384745e 100644 --- a/lib/Enterprise/UnifiedValidation.php +++ b/lib/Enterprise/UnifiedValidation.php @@ -275,7 +275,7 @@ class WorkflowValidatorPlugin extends ValidationPlugin public function validate(array $context): ValidationResult { $workflowDir = $context['workflow_dir'] - ?? (is_dir('.mokogitea/workflows') ? '.mokogitea/workflows' : '.github/workflows'); + ?? (is_dir('.mokogit/workflows') ? '.mokogit/workflows' : '.github/workflows'); if (!is_dir($workflowDir)) { return new ValidationResult($this->name, true, 'No workflows directory'); @@ -286,7 +286,7 @@ class WorkflowValidatorPlugin extends ValidationPlugin glob($workflowDir . '/*.yml') ?: [], glob($workflowDir . '/*.yaml') ?: [] ); - $altDir = ($workflowDir === '.mokogitea/workflows') ? '.github/workflows' : '.mokogitea/workflows'; + $altDir = ($workflowDir === '.mokogit/workflows') ? '.github/workflows' : '.mokogit/workflows'; if (is_dir($altDir)) { $workflows = array_merge( $workflows, diff --git a/lib/plugins/Joomla/UpdateXmlGenerator.php b/lib/plugins/Joomla/UpdateXmlGenerator.php deleted file mode 100644 index 505eafb8..00000000 --- a/lib/plugins/Joomla/UpdateXmlGenerator.php +++ /dev/null @@ -1,420 +0,0 @@ - - * - * This file is part of a Moko Consulting project. - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - * FILE INFORMATION - * DEFGROUP: MokoPlatform.Joomla - * INGROUP: MokoPlatform - * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli - * PATH: /lib/plugins/Joomla/UpdateXmlGenerator.php - * BRIEF: Generates and updates Joomla extension updates.xml files - */ - -declare(strict_types=1); - -namespace MokoCli\Plugins\Joomla; - -use DOMDocument; -use DOMElement; -use Exception; - -/** - * Joomla Update XML Generator - * - * Generates and updates updates.xml files for Joomla extensions - * following the Joomla update server specification - */ -class UpdateXmlGenerator -{ - private string $extensionName; - private string $extensionType; - private string $element; - private string $clientId; - - /** - * Constructor - * - * @param string $extensionName Human-readable extension name - * @param string $extensionType Extension type (component, module, plugin, etc.) - * @param string $element Extension element (e.g., com_example, mod_custom) - * @param string $clientId Client ID (0 for site, 1 for admin) - */ - public function __construct( - string $extensionName, - string $extensionType = 'component', - string $element = '', - string $clientId = '0' - ) { - $this->extensionName = $extensionName; - $this->extensionType = $extensionType; - $this->element = $element ?: $this->deriveElement($extensionName, $extensionType); - $this->clientId = $clientId; - } - - /** - * Generate updates.xml from release information - * - * @param array $release Release information - * @return string XML content - */ - public function generate(array $release): string - { - $dom = new DOMDocument('1.0', 'UTF-8'); - $dom->formatOutput = true; - $dom->preserveWhiteSpace = false; - - // Create root element - $updates = $dom->createElement('updates'); - $dom->appendChild($updates); - - // Add update entry - $this->addUpdateEntry($dom, $updates, $release); - - return $dom->saveXML(); - } - - /** - * Update existing updates.xml file with new release - * - * @param string $xmlPath Path to existing updates.xml - * @param array $release New release information - * @return string Updated XML content - * @throws Exception If XML cannot be parsed - */ - public function update(string $xmlPath, array $release): string - { - if (!file_exists($xmlPath)) { - return $this->generate($release); - } - - $dom = new DOMDocument('1.0', 'UTF-8'); - $dom->formatOutput = true; - $dom->preserveWhiteSpace = false; - - if (!@$dom->load($xmlPath)) { - throw new Exception("Failed to parse existing updates.xml at {$xmlPath}"); - } - - $updates = $dom->getElementsByTagName('updates')->item(0); - if (!$updates) { - throw new Exception("Invalid updates.xml: missing root element"); - } - - // Check if this version already exists - $version = $release['version']; - $existingUpdates = $updates->getElementsByTagName('update'); - - foreach ($existingUpdates as $existingUpdate) { - $versionNode = $existingUpdate->getElementsByTagName('version')->item(0); - if ($versionNode && $versionNode->textContent === $version) { - // Remove existing entry for this version - $updates->removeChild($existingUpdate); - break; - } - } - - // Add new update entry at the beginning - $this->addUpdateEntry($dom, $updates, $release, true); - - return $dom->saveXML(); - } - - /** - * Map numeric client ID to Joomla client name - * - * @param string $clientId Numeric client ID - * @return string Client name for updates.xml - */ - private function resolveClientName(string $clientId): string - { - return match ($clientId) { - '1' => 'administrator', - default => 'site', - }; - } - - /** - * Add an update entry to the XML document - * - * @param DOMDocument $dom DOM document - * @param DOMElement $updates Updates element - * @param array $release Release information - * @param bool $prepend Whether to prepend (insert at beginning) - */ - private function addUpdateEntry( - DOMDocument $dom, - DOMElement $updates, - array $release, - bool $prepend = false - ): void { - $update = $dom->createElement('update'); - - // Required fields - $this->addElement($dom, $update, 'name', $this->extensionName); - $this->addElement($dom, $update, 'description', $release['description'] ?? ''); - $this->addElement($dom, $update, 'element', $this->element); - $this->addElement($dom, $update, 'type', $this->extensionType); - - // Folder (for plugins) - if (!empty($release['folder'])) { - $this->addElement($dom, $update, 'folder', $release['folder']); - } - - // Client — always emit for correct extension matching - $this->addElement($dom, $update, 'client', $this->resolveClientName($this->clientId)); - - $this->addElement($dom, $update, 'version', $release['version']); - - // Creation date - if (!empty($release['creation_date'])) { - $this->addElement($dom, $update, 'creationDate', $release['creation_date']); - } - - // Joomla target platform - $infourl = $this->addElement($dom, $update, 'infourl', $release['infourl'] ?? ''); - if (!empty($release['infourl'])) { - $infourl->setAttribute('title', 'Release Information'); - } - - // Downloads section - $downloads = $dom->createElement('downloads'); - $update->appendChild($downloads); - - $downloadUrl = $this->addElement($dom, $downloads, 'downloadurl', $release['download_url']); - $downloadUrl->setAttribute('type', 'full'); - $downloadUrl->setAttribute('format', 'zip'); - - // Checksums - if (!empty($release['sha256'])) { - $this->addElement($dom, $update, 'sha256', $release['sha256']); - } - - if (!empty($release['sha384'])) { - $this->addElement($dom, $update, 'sha384', $release['sha384']); - } - - if (!empty($release['sha512'])) { - $this->addElement($dom, $update, 'sha512', $release['sha512']); - } - - // Tags - if (!empty($release['tags'])) { - $tags = $dom->createElement('tags'); - $update->appendChild($tags); - foreach ($release['tags'] as $tag) { - $this->addElement($dom, $tags, 'tag', $tag); - } - } - - // Maintainer information - if (!empty($release['maintainer'])) { - $this->addElement($dom, $update, 'maintainer', $release['maintainer']); - } - - if (!empty($release['maintainer_url'])) { - $this->addElement($dom, $update, 'maintainerurl', $release['maintainer_url']); - } - - // Target platform - if (!empty($release['target_platform'])) { - $targetPlatform = $dom->createElement('targetplatform'); - $targetPlatform->setAttribute('name', 'joomla'); - $targetPlatform->setAttribute('version', $release['target_platform']); - $update->appendChild($targetPlatform); - } - - // Optional: PHP minimum version - if (!empty($release['php_minimum'])) { - $this->addElement($dom, $update, 'php_minimum', $release['php_minimum']); - } - - // Add to updates element - if ($prepend && $updates->firstChild) { - $updates->insertBefore($update, $updates->firstChild); - } else { - $updates->appendChild($update); - } - } - - /** - * Add a text element to parent - * - * @param DOMDocument $dom DOM document - * @param DOMElement $parent Parent element - * @param string $name Element name - * @param string $value Element value - * @return DOMElement Created element - */ - private function addElement( - DOMDocument $dom, - DOMElement $parent, - string $name, - string $value - ): DOMElement { - $element = $dom->createElement($name); - $element->textContent = $value; - $parent->appendChild($element); - return $element; - } - - /** - * Derive element name from extension name and type - * - * @param string $name Extension name - * @param string $type Extension type - * @return string Element name - */ - private function deriveElement(string $name, string $type): string - { - $prefix = match ($type) { - 'component' => 'com_', - 'module' => 'mod_', - 'plugin' => 'plg_', - 'library' => 'lib_', - 'template' => 'tpl_', - 'package' => 'pkg_', - default => '', - }; - - // Convert name to lowercase and replace spaces with underscores - $element = strtolower(preg_replace('/[^a-z0-9]+/i', '_', $name)); - - // Add prefix if not already present - if (!str_starts_with($element, $prefix)) { - $element = $prefix . $element; - } - - return $element; - } - - /** - * Validate updates.xml structure - * - * @param string $xmlContent XML content to validate - * @return array Validation result ['valid' => bool, 'errors' => array] - */ - public static function validate(string $xmlContent): array - { - $errors = []; - - $dom = new DOMDocument(); - libxml_use_internal_errors(true); - - if (!$dom->loadXML($xmlContent)) { - foreach (libxml_get_errors() as $error) { - $errors[] = "XML Error: {$error->message}"; - } - libxml_clear_errors(); - return ['valid' => false, 'errors' => $errors]; - } - - // Validate structure - $updates = $dom->getElementsByTagName('updates')->item(0); - if (!$updates) { - $errors[] = "Missing root element"; - return ['valid' => false, 'errors' => $errors]; - } - - $updateElements = $updates->getElementsByTagName('update'); - if ($updateElements->length === 0) { - $errors[] = "No elements found"; - return ['valid' => false, 'errors' => $errors]; - } - - // Validate each update entry - foreach ($updateElements as $update) { - $required = ['name', 'element', 'type', 'version']; - foreach ($required as $field) { - if ($update->getElementsByTagName($field)->length === 0) { - $errors[] = "Missing required field: <{$field}>"; - } - } - - // Warn if is missing - if ($update->getElementsByTagName('client')->length === 0) { - $errors[] = "Missing tag — Joomla may not match this update to the installed extension"; - } - - // Check for download URL - $downloads = $update->getElementsByTagName('downloads'); - if ($downloads->length > 0) { - $downloadUrl = $downloads->item(0)->getElementsByTagName('downloadurl'); - if ($downloadUrl->length === 0) { - $errors[] = "Missing in "; - } - } - } - - return [ - 'valid' => empty($errors), - 'errors' => $errors - ]; - } - - /** - * Extract release information from manifest XML - * - * @param string $manifestPath Path to extension manifest XML - * @return array Release information - * @throws Exception If manifest cannot be parsed - */ - public static function extractFromManifest(string $manifestPath): array - { - if (!file_exists($manifestPath)) { - throw new Exception("Manifest file not found: {$manifestPath}"); - } - - $dom = new DOMDocument(); - if (!@$dom->load($manifestPath)) { - throw new Exception("Failed to parse manifest XML: {$manifestPath}"); - } - - $root = $dom->documentElement; - - return [ - 'name' => self::getElementText($dom, 'name') ?: 'Unknown Extension', - 'version' => self::getElementText($dom, 'version') ?: '1.0.0', - 'description' => self::getElementText($dom, 'description') ?: '', - 'author' => self::getElementText($dom, 'author') ?: '', - 'author_url' => self::getElementText($dom, 'authorUrl') ?: '', - 'type' => $root->getAttribute('type') ?: 'component', - 'target_platform' => self::getElementText($dom, 'version', 'targetplatform') ?: '4.0', - ]; - } - - /** - * Get text content of an element - * - * @param DOMDocument $dom DOM document - * @param string $tagName Tag name - * @param string $parentTag Optional parent tag name - * @return string|null Element text content - */ - private static function getElementText( - DOMDocument $dom, - string $tagName, - string $parentTag = '' - ): ?string { - if ($parentTag) { - $parents = $dom->getElementsByTagName($parentTag); - if ($parents->length > 0) { - $elements = $parents->item(0)->getElementsByTagName($tagName); - if ($elements->length > 0) { - return trim($elements->item(0)->textContent); - } - } - } else { - $elements = $dom->getElementsByTagName($tagName); - if ($elements->length > 0) { - return trim($elements->item(0)->textContent); - } - } - - return null; - } -} diff --git a/maintenance/pin_action_shas.php b/maintenance/pin_action_shas.php index 4d3c5f0c..c9400e6b 100644 --- a/maintenance/pin_action_shas.php +++ b/maintenance/pin_action_shas.php @@ -64,7 +64,7 @@ class PinActionShasCli extends CliFramework $this->log('INFO', "Mode: DRY RUN (no files will be modified)\n"); } - // Also check .github/workflows if on Gitea (workflows may exist in both dirs) + // Also check .github/workflows if on MokoGit (workflows may exist in both dirs) $dirs = [$this->workflowsDir]; if ($this->workflowsDir !== '.github/workflows' && is_dir('.github/workflows')) { $dirs[] = '.github/workflows'; diff --git a/maintenance/repo_inventory.php b/maintenance/repo_inventory.php index d019fd81..2c036424 100644 --- a/maintenance/repo_inventory.php +++ b/maintenance/repo_inventory.php @@ -45,8 +45,8 @@ class RepoInventoryCli extends CliFramework $this->log('ERROR', "Platform init failed: " . $e->getMessage()); exit(1); } - $this->token = $this->platformConfig->getString('platform', 'gitea') === 'gitea' - ? $this->platformConfig->getString('gitea.token', '') : $this->platformConfig->getString('github.token', ''); + $this->token = $this->platformConfig->getString('platform', 'mokogit') === 'mokogit' + ? $this->platformConfig->getString('mokogit.token', '') : $this->platformConfig->getString('github.token', ''); } protected function run(): int @@ -213,7 +213,7 @@ class RepoInventoryCli extends CliFramework private function graphql(string $query, array $variables): array { - $pf = $this->platformConfig !== null ? $this->platformConfig->getString('platform', 'gitea') : 'gitea'; + $pf = $this->platformConfig !== null ? $this->platformConfig->getString('platform', 'mokogit') : 'mokogit'; if ($pf !== 'github') { return []; } diff --git a/maintenance/rotate_secrets.php b/maintenance/rotate_secrets.php index 882abf9c..b5bd0d83 100644 --- a/maintenance/rotate_secrets.php +++ b/maintenance/rotate_secrets.php @@ -61,8 +61,8 @@ class RotateSecretsCli extends CliFramework $this->log('ERROR', "Platform init failed: " . $e->getMessage()); exit(1); } - $this->token = $config->getString('platform', 'gitea') === 'gitea' - ? $config->getString('gitea.token', '') + $this->token = $config->getString('platform', 'mokogit') === 'mokogit' + ? $config->getString('mokogit.token', '') : $config->getString('github.token', ''); } diff --git a/maintenance/setup_labels.php b/maintenance/setup_labels.php index cebfd6e2..451f1a44 100644 --- a/maintenance/setup_labels.php +++ b/maintenance/setup_labels.php @@ -29,7 +29,7 @@ use MokoCli\PlatformAdapterFactory; /** * Deploys the standard set of repository labels required by mokocli. * - * Uses the platform adapter (GitHub or Gitea) to create or update each label. + * Uses the platform adapter (GitHub or MokoGit) to create or update each label. * Supports --dry-run mode to preview without making changes. */ class SetupLabels extends CliFramework diff --git a/mcp/config.example.json b/mcp/config.example.json index 339f5a1f..fee997c9 100644 --- a/mcp/config.example.json +++ b/mcp/config.example.json @@ -1,6 +1,6 @@ { "apiPath": "A:/mokocli", "standardsPath": "A:/mokocli", - "giteaUrl": "https://git.mokoconsulting.tech", - "giteaToken": "your-gitea-api-token" + "mokogitUrl": "https://git.mokoconsulting.tech", + "mokogitToken": "your-mokogit-api-token" } diff --git a/mcp/servers/mokobackup/.mokogitea/CLAUDE.md b/mcp/servers/mokobackup/.mokogit/CLAUDE.md similarity index 87% rename from mcp/servers/mokobackup/.mokogitea/CLAUDE.md rename to mcp/servers/mokobackup/.mokogit/CLAUDE.md index 7b51297b..96063c85 100644 --- a/mcp/servers/mokobackup/.mokogitea/CLAUDE.md +++ b/mcp/servers/mokobackup/.mokogit/CLAUDE.md @@ -1,6 +1,6 @@ # mcp_mokobackup -MCP server for database and file backups across Dolibarr, Joomla/Akeeba, Gitea, and file-based environments. +MCP server for database and file backups across Dolibarr, Joomla/Akeeba, MokoGit, and file-based environments. ## Quick Reference @@ -32,7 +32,7 @@ src/ └── types.ts # BackupConfig, BackupTarget types ``` -- Config defines **targets** — each target has a type (akeeba, dolibarr, mysql, files, gitea-db, gitea-files) +- Config defines **targets** — each target has a type (akeeba, dolibarr, mysql, files, mokogit-db, mokogit-files) - Client-specific targets go in client repo configs, not global - Dolibarr backups read `conf.php` via SSH to get DB credentials @@ -44,6 +44,6 @@ Default config at `~/.mcp_mokobackup.json`. Client repos override via `BACKUP_MC - **Never commit** `.claude/`, `.mcp.json`, `TODO.md`, `*.min.css`/`*.min.js` - **Attribution**: `Authored-by: Moko Consulting` -- **Workflow directory**: `.mokogitea/` (not `.gitea/` or `.github/`) -- **Wiki**: documentation lives in the Gitea wiki, not `docs/` files +- **Workflow directory**: `.mokogit/` (not `.mokogit/` or `.github/`) +- **Wiki**: documentation lives in the MokoGit wiki, not `docs/` files - **Standards**: [MokoCli](https://git.mokoconsulting.tech/MokoConsulting/mokocli/wiki/Home) diff --git a/mcp/servers/mokobackup/.mokogitea/workflows/pr-check.yml b/mcp/servers/mokobackup/.mokogit/workflows/pr-check.yml similarity index 86% rename from mcp/servers/mokobackup/.mokogitea/workflows/pr-check.yml rename to mcp/servers/mokobackup/.mokogit/workflows/pr-check.yml index fe936371..a1cb3ac5 100644 --- a/mcp/servers/mokobackup/.mokogitea/workflows/pr-check.yml +++ b/mcp/servers/mokobackup/.mokogit/workflows/pr-check.yml @@ -3,7 +3,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later # # FILE INFORMATION -# DEFGROUP: Gitea.Workflow +# DEFGROUP: MokoGit.Workflow # INGROUP: mokocli.CI # REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/mokocli # PATH: /templates/workflows/universal/pr-check.yml.template @@ -109,8 +109,8 @@ jobs: id: platform run: | # Read platform from XML manifest ( tag) or plain text fallback - PLATFORM=$(sed -n 's/.*\([^<]*\)<\/platform>.*/\1/p' .mokogitea/manifest.xml 2>/dev/null | head -1) - [ -z "$PLATFORM" ] && PLATFORM=$(cat .mokogitea/manifest.xml 2>/dev/null | tr -d '[:space:]') + PLATFORM=$(sed -n 's/.*\([^<]*\)<\/platform>.*/\1/p' .mokogit/manifest.xml 2>/dev/null | head -1) + [ -z "$PLATFORM" ] && PLATFORM=$(cat .mokogit/manifest.xml 2>/dev/null | tr -d '[:space:]') [ -z "$PLATFORM" ] && PLATFORM="generic" echo "platform=$PLATFORM" >> "$GITHUB_OUTPUT" @@ -166,23 +166,6 @@ jobs: ;; esac - - name: Check update stream format - run: | - PLATFORM="${{ steps.platform.outputs.platform }}" - case "$PLATFORM" in - joomla) - if [ -f "updates.xml" ]; then - if command -v php &> /dev/null; then - php -r "libxml_use_internal_errors(true); \$x = simplexml_load_file('updates.xml'); if(!\$x){foreach(libxml_get_errors() as \$e) echo \$e->message; exit(1);}" || { echo "::error::updates.xml is malformed"; exit 1; } - fi - echo "updates.xml valid" - fi - ;; - dolibarr) - [ -f "update.txt" ] && echo "update.txt present" || echo "::warning::No update.txt" - ;; - esac - - name: Check changelog has unreleased entry run: | if [ ! -f "CHANGELOG.md" ]; then @@ -226,11 +209,11 @@ jobs: steps: - name: Trigger RC pre-release env: - GA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }} + GA_TOKEN: ${{ secrets.MOKOGIT_TOKEN }} REPO: ${{ github.repository }} BRANCH: ${{ github.head_ref }} - GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }} + MOKOGIT_URL: ${{ vars.MOKOGIT_URL || 'https://git.mokoconsulting.tech' }} run: | - curl -s -X POST "${GITEA_URL}/api/v1/repos/${REPO}/actions/workflows/pre-release.yml/dispatches" -H "Authorization: token ${GITEA_TOKEN}" -H "Content-Type: application/json" -d "{\"ref\":\"${BRANCH}\",\"inputs\":{\"stability\":\"release-candidate\"}}" + curl -s -X POST "${MOKOGIT_URL}/api/v1/repos/${REPO}/actions/workflows/pre-release.yml/dispatches" -H "Authorization: token ${MOKOGIT_TOKEN}" -H "Content-Type: application/json" -d "{\"ref\":\"${BRANCH}\",\"inputs\":{\"stability\":\"release-candidate\"}}" echo "### Pre-Release" >> $GITHUB_STEP_SUMMARY echo "Triggered RC build on branch \`${BRANCH}\`" >> $GITHUB_STEP_SUMMARY diff --git a/mcp/servers/mokobackup/README.md b/mcp/servers/mokobackup/README.md index 73c6de40..8f057a5b 100644 --- a/mcp/servers/mokobackup/README.md +++ b/mcp/servers/mokobackup/README.md @@ -15,7 +15,7 @@ Model Context Protocol server for database dumps, file backups, and Akeeba Backu | **Language** | Node.js | | **Tools** | 11 tools (6 SSH-based + 5 Akeeba API) | | **License** | GPL-3.0-or-later | -| **Platform** | [Gitea](https://git.mokoconsulting.tech/MokoConsulting/backup-mcp) (primary) | +| **Platform** | [MokoGit](https://git.mokoconsulting.tech/MokoConsulting/backup-mcp) (primary) | --- diff --git a/mcp/servers/mokocrm_api/.mokogitea/CLAUDE.md b/mcp/servers/mokocrm_api/.mokogit/CLAUDE.md similarity index 91% rename from mcp/servers/mokocrm_api/.mokogitea/CLAUDE.md rename to mcp/servers/mokocrm_api/.mokogit/CLAUDE.md index 56a31681..ffa37d0f 100644 --- a/mcp/servers/mokocrm_api/.mokogitea/CLAUDE.md +++ b/mcp/servers/mokocrm_api/.mokogit/CLAUDE.md @@ -39,6 +39,6 @@ src/ - **Never commit** `.claude/`, `.mcp.json`, `TODO.md`, `*.min.css`/`*.min.js` - **Attribution**: `Authored-by: Moko Consulting` -- **Workflow directory**: `.mokogitea/` (not `.gitea/` or `.github/`) -- **Wiki**: documentation lives in the Gitea wiki, not `docs/` files +- **Workflow directory**: `.mokogit/` (not `.mokogit/` or `.github/`) +- **Wiki**: documentation lives in the MokoGit wiki, not `docs/` files - **Standards**: [MokoCli](https://git.mokoconsulting.tech/MokoConsulting/mokocli/wiki/Home) diff --git a/mcp/servers/mokocrm_api/CHANGELOG.md b/mcp/servers/mokocrm_api/CHANGELOG.md index 16f075c6..3c1af6e7 100644 --- a/mcp/servers/mokocrm_api/CHANGELOG.md +++ b/mcp/servers/mokocrm_api/CHANGELOG.md @@ -53,7 +53,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - SQL filter builder (`buildSqlFilter`, `searchFilter`) for safe query construction - Full documentation: README, INSTALLATION, ARCHITECTURE, API reference - MokoCli-compliant project structure -- 12 Gitea Actions CI/CD workflows +- 12 MokoGit Actions CI/CD workflows ## Revision History diff --git a/mcp/servers/mokocrm_api/CONTRIBUTING.md b/mcp/servers/mokocrm_api/CONTRIBUTING.md index f11a528b..afadb25d 100644 --- a/mcp/servers/mokocrm_api/CONTRIBUTING.md +++ b/mcp/servers/mokocrm_api/CONTRIBUTING.md @@ -48,7 +48,7 @@ This project adheres to the Contributor Covenant Code of Conduct. By participati ### Reporting Bugs -- Use the Gitea issue tracker +- Use the MokoGit issue tracker - Describe the bug clearly with steps to reproduce - Include the Dolibarr version you're connecting to - Include relevant logs or error messages @@ -143,8 +143,8 @@ Every repo maintains 5 standard release channel tags: ### CI/CD -- Gitea Actions runs all CI workflows -- Workflows live in `.gitea/workflows/` +- MokoGit Actions runs all CI workflows +- Workflows live in `.mokogit/workflows/` ### Secrets diff --git a/mcp/servers/mokocrm_api/README.md b/mcp/servers/mokocrm_api/README.md index 2eda4bef..1fe728f7 100644 --- a/mcp/servers/mokocrm_api/README.md +++ b/mcp/servers/mokocrm_api/README.md @@ -8,7 +8,7 @@ MCP server for Dolibarr ERP/CRM REST API operations |---|---| | **Language** | TypeScript | | **License** | GPL-3.0-or-later | -| **Platform** | [Gitea](https://git.mokoconsulting.tech/MokoConsulting/dolibarr-api-mcp) | +| **Platform** | [MokoGit](https://git.mokoconsulting.tech/MokoConsulting/dolibarr-api-mcp) | | **Node.js** | >= 20.0.0 | | **MCP SDK** | @modelcontextprotocol/sdk ^1.12.1 | diff --git a/mcp/servers/mokocrm_api/SECURITY.md b/mcp/servers/mokocrm_api/SECURITY.md index df1a3a5c..280e19f3 100644 --- a/mcp/servers/mokocrm_api/SECURITY.md +++ b/mcp/servers/mokocrm_api/SECURITY.md @@ -31,7 +31,7 @@ Only the current major version receives security updates. ## Reporting a Vulnerability -Report security vulnerabilities via Gitea issue (preferred): +Report security vulnerabilities via MokoGit issue (preferred): https://git.mokoconsulting.tech/MokoConsulting/dolibarr-api-mcp/issues/new?template=security.yaml Or email: hello@mokoconsulting.tech diff --git a/mcp/servers/mokodreamhost/.mokogitea/CLAUDE.md b/mcp/servers/mokodreamhost/.mokogit/CLAUDE.md similarity index 89% rename from mcp/servers/mokodreamhost/.mokogitea/CLAUDE.md rename to mcp/servers/mokodreamhost/.mokogit/CLAUDE.md index 53833987..66545195 100644 --- a/mcp/servers/mokodreamhost/.mokogitea/CLAUDE.md +++ b/mcp/servers/mokodreamhost/.mokogit/CLAUDE.md @@ -37,6 +37,6 @@ src/ - **Never commit** `.claude/`, `.mcp.json`, `TODO.md`, `*.min.css`/`*.min.js` - **Attribution**: `Authored-by: Moko Consulting` -- **Workflow directory**: `.mokogitea/` (not `.gitea/` or `.github/`) -- **Wiki**: documentation lives in the Gitea wiki, not `docs/` files +- **Workflow directory**: `.mokogit/` (not `.mokogit/` or `.github/`) +- **Wiki**: documentation lives in the MokoGit wiki, not `docs/` files - **Standards**: [MokoCli](https://git.mokoconsulting.tech/MokoConsulting/mokocli/wiki/Home) diff --git a/mcp/servers/mokogitea_api b/mcp/servers/mokogit_api similarity index 100% rename from mcp/servers/mokogitea_api rename to mcp/servers/mokogit_api diff --git a/mcp/servers/mokogitea_skill/commands/deploy.md b/mcp/servers/mokogit_skill/commands/deploy.md similarity index 92% rename from mcp/servers/mokogitea_skill/commands/deploy.md rename to mcp/servers/mokogit_skill/commands/deploy.md index c080ca63..0f963064 100644 --- a/mcp/servers/mokogitea_skill/commands/deploy.md +++ b/mcp/servers/mokogit_skill/commands/deploy.md @@ -12,7 +12,7 @@ Build the current project and deploy to a target server. - Current directory: !`pwd` - Git status: !`git status --short` -- Platform manifest: !`cat .mokogitea/manifest.xml 2>/dev/null | head -10` +- Platform manifest: !`cat .mokogit/manifest.xml 2>/dev/null | head -10` ## Target Servers @@ -26,7 +26,7 @@ Build the current project and deploy to a target server. ## Instructions -1. **Identify platform** from `.mokogitea/manifest.xml`: +1. **Identify platform** from `.mokogit/manifest.xml`: - `joomla` → build ZIP, install via Joomla API or SFTP - `dolibarr` → SFTP module files to `htdocs/custom/` - `mcp-server` → npm build, no remote deploy needed diff --git a/mcp/servers/mokogitea_skill/commands/mcp-rebuild.md b/mcp/servers/mokogit_skill/commands/mcp-rebuild.md similarity index 94% rename from mcp/servers/mokogitea_skill/commands/mcp-rebuild.md rename to mcp/servers/mokogit_skill/commands/mcp-rebuild.md index 32e31bf3..0cbca5dd 100644 --- a/mcp/servers/mokogitea_skill/commands/mcp-rebuild.md +++ b/mcp/servers/mokogit_skill/commands/mcp-rebuild.md @@ -20,7 +20,7 @@ Rebuild MCP server(s) by running `npm install` and `npm run build`. | mcp_mokobackup | A:/MCP/mcp_mokobackup | Yes (TypeScript) | | mcp_mokocrm | A:/MCP/mcp_mokocrm | Yes (TypeScript) | | mcp_mokodreamhost | A:/MCP/mcp_mokodreamhost | Yes (TypeScript) | -| mcp_mokogitea_api | A:/MCP/mcp_mokogitea_api | Yes (TypeScript) | +| mcp_mokogit_api | A:/MCP/mcp_mokogit_api | Yes (TypeScript) | | mcp_mokomonitor | A:/MCP/mcp_mokomonitor | Yes (TypeScript) | | mcp_mokossh | A:/MCP/mcp_mokossh | No (plain JS) | | mcp_mokowaas | A:/MCP/mcp_mokowaas | Yes (TypeScript) | diff --git a/mcp/servers/mokogitea_skill/commands/new-client.md b/mcp/servers/mokogit_skill/commands/new-client.md similarity index 71% rename from mcp/servers/mokogitea_skill/commands/new-client.md rename to mcp/servers/mokogit_skill/commands/new-client.md index 1580686d..a583ccaf 100644 --- a/mcp/servers/mokogitea_skill/commands/new-client.md +++ b/mcp/servers/mokogit_skill/commands/new-client.md @@ -1,6 +1,6 @@ --- name: new-client -description: Scaffold a new WaaS client — Gitea org, theme repo, MCP config, wiki, SSH key +description: Scaffold a new WaaS client — MokoGit org, theme repo, MCP config, wiki, SSH key allowed-tools: Bash, Read, Write, Edit, Glob, Grep --- @@ -22,13 +22,13 @@ Ask the user for: Then execute these steps: -### 1. Create Gitea Organization -- Use `mcp_mokogitea_api` tool `gitea_org_create` +### 1. Create MokoGit Organization +- Use `mcp_mokogit_api` tool `mokogit_org_create` - Org name: PascalCase of slug (e.g. "AcmeCorp") - Description: "WaaS client: {Client name}" ### 2. Create Client Repository -- Use `mcp_mokogitea_api` tool `gitea_repo_create` in the new org +- Use `mcp_mokogit_api` tool `mokogit_repo_create` in the new org - Repo name: `client-waas-{slug}` - Initialize from Template-Client-WaaS if possible, otherwise create empty and copy files @@ -38,22 +38,22 @@ Then execute these steps: - Update `src/*.xml` manifest: - `MokoOnyx Theme — {Client Name}` - `file_mokoonyx_{slug}` -- Create `.mokogitea/CLAUDE.md` with client-specific content +- Create `.mokogit/CLAUDE.md` with client-specific content - Create initial `CHANGELOG.md` - Commit and push ### 4. Create SSH Key - Generate key pair at `C:/Users/jmill/OneDrive/Documents/Keys/repos/client-{slug}` -- Add public key as deploy key on the Gitea repo +- Add public key as deploy key on the MokoGit repo ### 5. Setup GitHub Mirror -- Use `gitea_repo_mirror_setup_github_backup_full` to create GitHub backup mirror +- Use `mokogit_repo_mirror_setup_github_backup_full` to create GitHub backup mirror ### 6. Initialize Wiki -- Create Home page with client info using `mcp_mokogitea_wiki` tools +- Create Home page with client info using `mcp_mokogit_wiki` tools ### 7. Apply Labels -- Apply standard label set using `mcp_mokogitea_api` tools +- Apply standard label set using `mcp_mokogit_api` tools - Labels use colon-style (e.g. "priority: critical") ### 8. Report diff --git a/mcp/servers/mokogitea_skill/commands/release.md b/mcp/servers/mokogit_skill/commands/release.md similarity index 64% rename from mcp/servers/mokogitea_skill/commands/release.md rename to mcp/servers/mokogit_skill/commands/release.md index 9a8812d2..42ff08ae 100644 --- a/mcp/servers/mokogitea_skill/commands/release.md +++ b/mcp/servers/mokogit_skill/commands/release.md @@ -1,6 +1,6 @@ --- name: release -description: Create a release — build ZIP, tag, update updates.xml, create Gitea release +description: Create a release — build ZIP, tag, create MokoGit release allowed-tools: Bash, Read, Write, Edit, Glob, Grep --- @@ -14,7 +14,7 @@ Create a release for the current repository. - Git status: !`git status --short` - Current branch: !`git rev-parse --abbrev-ref HEAD` - Recent tags: !`git tag --sort=-creatordate | head -5` -- Platform manifest: !`cat .mokogitea/manifest.xml 2>/dev/null | head -10` +- Platform manifest: !`cat .mokogit/manifest.xml 2>/dev/null | head -10` ## Instructions @@ -33,7 +33,7 @@ Create a release for the current repository. - **Dolibarr** (`make build`): packages module 4. **Update version files:** - - Joomla: update `` in manifest XML, update `updates.xml` in repo root + - Joomla: update `` in manifest XML - Node: update `version` in `package.json` - Update CHANGELOG.md with release date @@ -42,19 +42,14 @@ Create a release for the current repository. - Create annotated tag: `git tag -a vX.Y.Z -m "Release X.Y.Z"` - Push commits and tags: `git push origin && git push origin --tags` -6. **Create Gitea release:** - - Use `mcp_mokogitea_api` tool `gitea_release_create` with the tag - - Upload the built ZIP as a release asset via `gitea_release_upload_asset` +6. **Create MokoGit release:** + - Use `mcp_mokogit_api` tool `mokogit_release_create` with the tag + - Upload the built ZIP as a release asset via `mokogit_release_upload_asset` -7. **Joomla-specific: update updates.xml:** - - Prepend new `` block with version, download URL pointing to Gitea release asset - - ZIP filename follows Joomla convention from feedback_joomla_release_naming memory - - Commit and push the updates.xml change - -8. **Report:** show the release URL and confirm success. +7. **Report:** show the release URL and confirm success. ## Important Rules - Release ZIP filenames follow Joomla conventions (see feedback_joomla_release_naming) -- updates.xml goes in repo root, not src/ +- MokoGit generates update feeds dynamically — no static updates.xml needed - GitHub mirrors sync automatically — do NOT push to GitHub diff --git a/mcp/servers/mokogitea_skill/commands/server-health.md b/mcp/servers/mokogit_skill/commands/server-health.md similarity index 84% rename from mcp/servers/mokogitea_skill/commands/server-health.md rename to mcp/servers/mokogit_skill/commands/server-health.md index 1f8d042d..11997021 100644 --- a/mcp/servers/mokogitea_skill/commands/server-health.md +++ b/mcp/servers/mokogit_skill/commands/server-health.md @@ -1,6 +1,6 @@ --- name: server-health -description: Run health checks across all MokoGitea infrastructure servers +description: Run health checks across all MokoGit infrastructure servers allowed-tools: Bash, Read, Glob, Grep --- @@ -17,10 +17,10 @@ Run health checks across all infrastructure servers using SSH. Use `mcp_mokossh` MCP tools to run health checks on each server: ### 1. GIT Server (git.mokoconsulting.tech) -- `systemctl status gitea` — is Gitea running? +- `systemctl status mokogit` — is MokoGit running? - `systemctl status act_runner` — is the Actions runner running? - `df -h /` — disk space -- `du -sh /var/lib/gitea/repositories/ /var/lib/gitea/data/ /var/lib/gitea/log/` — Gitea storage breakdown +- `du -sh /var/lib/mokogit/repositories/ /var/lib/mokogit/data/ /var/lib/mokogit/log/` — MokoGit storage breakdown - `uptime` — load average - `free -h` — memory usage - `certbot certificates 2>/dev/null | grep -E "Expiry|Domains"` — SSL cert expiry diff --git a/mcp/servers/mokogitea_skill/skills/mokogitea/SKILL.md b/mcp/servers/mokogit_skill/skills/mokogit/SKILL.md similarity index 51% rename from mcp/servers/mokogitea_skill/skills/mokogitea/SKILL.md rename to mcp/servers/mokogit_skill/skills/mokogit/SKILL.md index f4af8ee7..561a7ce5 100644 --- a/mcp/servers/mokogitea_skill/skills/mokogitea/SKILL.md +++ b/mcp/servers/mokogit_skill/skills/mokogit/SKILL.md @@ -1,18 +1,18 @@ --- -name: mokogitea -description: "MokoGitea server infrastructure, SSH commands, deployment, backup, and administration. Use when the user mentions: gitea, mokogitea, git server, deploy, deployment, restart gitea, ssh into, server status, backup gitea, restore, mirror, github backup, update server, gitea actions, CI/CD, runner, waas server, crm server, server health, disk space, systemctl, nginx, certbot, fail2ban, firewall, server logs, gitea logs, or any remote server operation." -when_to_use: "Auto-trigger when discussing: server management, SSH operations, Gitea administration, deployments, backups, mirrors, CI runners, or any infrastructure task involving git.mokoconsulting.tech or the MokoGitea instance." +name: mokogit +description: "MokoGit server infrastructure, SSH commands, deployment, backup, and administration. Use when the user mentions: mokogit, mokogit, git server, deploy, deployment, restart mokogit, ssh into, server status, backup mokogit, restore, mirror, github backup, update server, mokogit actions, CI/CD, runner, waas server, crm server, server health, disk space, systemctl, nginx, certbot, fail2ban, firewall, server logs, mokogit logs, or any remote server operation." +when_to_use: "Auto-trigger when discussing: server management, SSH operations, MokoGit administration, deployments, backups, mirrors, CI runners, or any infrastructure task involving git.mokoconsulting.tech or the MokoGit instance." --- -# MokoGitea Infrastructure Reference +# MokoGit Infrastructure Reference -You are helping with MokoGitea server infrastructure. Use the `mcp_mokossh` MCP tools for SSH commands and `mcp_mokogitea_api` tools for Gitea API operations. +You are helping with MokoGit server infrastructure. Use the `mcp_mokossh` MCP tools for SSH commands and `mcp_mokogit_api` tools for MokoGit API operations. ## Server Map | Name | Host | User | Port | Purpose | |---|---|---|---|---| -| GIT | git.mokoconsulting.tech | mokoconsulting | 2918 | MokoGitea instance (Gitea fork) | +| GIT | git.mokoconsulting.tech | mokoconsulting | 2918 | MokoGit instance (MokoGit fork) | | WAAS_DEV | waas.dev.mokoconsulting.tech | mokoconsulting_dev | 22 | WaaS dev (Joomla + Dolibarr) | | WAAS_DEMO | waas.demo.mokoconsulting.tech | mokoconsulting_demo | 22 | WaaS demo | | WAAS_LIVE | mokoconsulting.tech | mokoconsulting | 22 | WaaS production | @@ -23,45 +23,45 @@ SSH key: `jmiller_private.openssh` (all MCP connections) ## Common SSH Commands -### Gitea Server (GIT) +### MokoGit Server (GIT) ```bash # Service management -sudo systemctl status gitea -sudo systemctl restart gitea -sudo systemctl stop gitea +sudo systemctl status mokogit +sudo systemctl restart mokogit +sudo systemctl stop mokogit # Logs -sudo journalctl -u gitea -f # Follow live logs -sudo journalctl -u gitea --since "1 hour ago" # Recent logs +sudo journalctl -u mokogit -f # Follow live logs +sudo journalctl -u mokogit --since "1 hour ago" # Recent logs -# Gitea CLI (run as git user) -sudo -u git /usr/local/bin/gitea admin user list -sudo -u git /usr/local/bin/gitea admin auth list -sudo -u git /usr/local/bin/gitea doctor check +# MokoGit CLI (run as git user) +sudo -u git /usr/local/bin/mokogit admin user list +sudo -u git /usr/local/bin/mokogit admin auth list +sudo -u git /usr/local/bin/mokogit doctor check -# Gitea Actions runner +# MokoGit Actions runner sudo systemctl status act_runner sudo systemctl restart act_runner sudo journalctl -u act_runner -f # Config -cat /etc/gitea/app.ini # Main config -sudo -u git /usr/local/bin/gitea admin config # Dump effective config +cat /etc/mokogit/app.ini # Main config +sudo -u git /usr/local/bin/mokogit admin config # Dump effective config # Database -sudo mysql -u root gitea -e "SELECT name FROM repository ORDER BY updated_unix DESC LIMIT 10;" +sudo mysql -u root mokogit -e "SELECT name FROM repository ORDER BY updated_unix DESC LIMIT 10;" # Disk space df -h -du -sh /var/lib/gitea/repositories/ -du -sh /var/lib/gitea/data/ -du -sh /var/lib/gitea/log/ +du -sh /var/lib/mokogit/repositories/ +du -sh /var/lib/mokogit/data/ +du -sh /var/lib/mokogit/log/ # Nginx sudo nginx -t # Test config sudo systemctl reload nginx -cat /etc/nginx/sites-enabled/gitea.conf +cat /etc/nginx/sites-enabled/mokogit.conf # SSL sudo certbot certificates @@ -125,18 +125,18 @@ ls htdocs/custom/ mysql -u root dolibarr -e "SELECT name, value FROM llx_const WHERE name LIKE '%VERSION%';" ``` -## Gitea API Operations +## MokoGit API Operations -Use `mcp_mokogitea_api` MCP tools for API operations: +Use `mcp_mokogit_api` MCP tools for API operations: -- **Repos**: `gitea_repo_list`, `gitea_repo_create`, `gitea_repo_delete`, `gitea_repo_get` -- **Issues**: `gitea_issue_create`, `gitea_issue_list`, `gitea_issue_comment` -- **PRs**: `gitea_pr_create`, `gitea_pr_list`, `gitea_pr_merge` -- **Releases**: `gitea_release_create`, `gitea_release_list`, `gitea_release_upload_asset` -- **Mirrors**: `gitea_repo_mirror_create`, `gitea_repo_mirror_setup_github_backup`, `gitea_repo_mirror_setup_github_backup_full` -- **Actions**: `gitea_actions_list_runs`, `gitea_actions_get_run` -- **Orgs**: `gitea_org_list`, `gitea_org_create`, `gitea_org_get` -- **Wiki**: use `mcp_mokogitea_wiki` tools for wiki CRUD +- **Repos**: `mokogit_repo_list`, `mokogit_repo_create`, `mokogit_repo_delete`, `mokogit_repo_get` +- **Issues**: `mokogit_issue_create`, `mokogit_issue_list`, `mokogit_issue_comment` +- **PRs**: `mokogit_pr_create`, `mokogit_pr_list`, `mokogit_pr_merge` +- **Releases**: `mokogit_release_create`, `mokogit_release_list`, `mokogit_release_upload_asset` +- **Mirrors**: `mokogit_repo_mirror_create`, `mokogit_repo_mirror_setup_github_backup`, `mokogit_repo_mirror_setup_github_backup_full` +- **Actions**: `mokogit_actions_list_runs`, `mokogit_actions_get_run` +- **Orgs**: `mokogit_org_list`, `mokogit_org_create`, `mokogit_org_get` +- **Wiki**: use `mcp_mokogit_wiki` tools for wiki CRUD ## Backup Operations @@ -144,8 +144,8 @@ Use `mcp_mokobackup` MCP tools: | Target | Type | What it backs up | |---|---|---| -| gitea-db | mysql | Gitea MySQL database | -| gitea-files | files | `/var/lib/gitea/` (repos, data, avatars) | +| mokogit-db | mysql | MokoGit MySQL database | +| mokogit-files | files | `/var/lib/mokogit/` (repos, data, avatars) | | waas-dev | akeeba | Joomla dev site via Akeeba API | | waas-demo | akeeba | Joomla demo site | | waas-live | akeeba | Joomla production site | @@ -154,7 +154,7 @@ Use `mcp_mokobackup` MCP tools: ## Deployment -Deployments are handled by **Gitea Actions workflows** (not manual SSH): +Deployments are handled by **MokoGit Actions workflows** (not manual SSH): - Push to `dev` → CI runs (lint, build, validate) - Merge PR to `main` → release workflow builds ZIP, creates release, deploys via SFTP - Client sites: `client-release.yml` workflow handles theme package deployment @@ -164,27 +164,27 @@ Deployments are handled by **Gitea Actions workflows** (not manual SSH): All repos mirror to GitHub (mokoconsulting-tech org) as backup: - Code + wiki mirrors, synced every 8 hours + on commit -- Use `gitea_repo_mirror_setup_github_backup_full` for new repos +- Use `mokogit_repo_mirror_setup_github_backup_full` for new repos - GitHub is **backup only** — never create PRs or enable Actions on GitHub ## Key Paths on GIT Server | Path | Contents | |---|---| -| `/usr/local/bin/gitea` | Gitea binary | -| `/etc/gitea/app.ini` | Main configuration | -| `/var/lib/gitea/` | All Gitea data | -| `/var/lib/gitea/repositories/` | Git bare repos | -| `/var/lib/gitea/data/` | Attachments, avatars, LFS | -| `/var/lib/gitea/log/` | Gitea logs | -| `/var/lib/gitea/custom/` | Custom templates, public files | -| `/etc/nginx/sites-enabled/gitea.conf` | Nginx reverse proxy config | +| `/usr/local/bin/mokogit` | MokoGit binary | +| `/etc/mokogit/app.ini` | Main configuration | +| `/var/lib/mokogit/` | All MokoGit data | +| `/var/lib/mokogit/repositories/` | Git bare repos | +| `/var/lib/mokogit/data/` | Attachments, avatars, LFS | +| `/var/lib/mokogit/log/` | MokoGit logs | +| `/var/lib/mokogit/custom/` | Custom templates, public files | +| `/etc/nginx/sites-enabled/mokogit.conf` | Nginx reverse proxy config | | `/home/git/.act_runner/` | Actions runner config | ## Important Notes - Port 2918 on GIT server is **shell SSH** (not just git protocol) — full command execution -- Gitea repo names on server use **hyphens** (e.g. `mcp-mokobackup`), local dirs use **underscores** +- MokoGit repo names on server use **hyphens** (e.g. `mcp-mokobackup`), local dirs use **underscores** - `mokocli` CLI tools handle CI checks — don't inline bash in workflows -- All infra docs live in **mokogitea-private wiki**, not public repos +- All infra docs live in **mokogit-private wiki**, not public repos - Two master SSH keys (jmiller + moko) on all servers diff --git a/mcp/servers/mokomonitor/.mokogitea/.moko-platform b/mcp/servers/mokomonitor/.mokogit/.moko-platform similarity index 100% rename from mcp/servers/mokomonitor/.mokogitea/.moko-platform rename to mcp/servers/mokomonitor/.mokogit/.moko-platform diff --git a/mcp/servers/mokomonitor/mcp_mokomonitor/.mokogitea/CLAUDE.md b/mcp/servers/mokomonitor/.mokogit/CLAUDE.md similarity index 91% rename from mcp/servers/mokomonitor/mcp_mokomonitor/.mokogitea/CLAUDE.md rename to mcp/servers/mokomonitor/.mokogit/CLAUDE.md index de7166dd..7dc857f0 100644 --- a/mcp/servers/mokomonitor/mcp_mokomonitor/.mokogitea/CLAUDE.md +++ b/mcp/servers/mokomonitor/.mokogit/CLAUDE.md @@ -39,6 +39,6 @@ src/ - **Never commit** `.claude/`, `.mcp.json`, `TODO.md`, `*.min.css`/`*.min.js` - **Attribution**: `Authored-by: Moko Consulting` -- **Workflow directory**: `.mokogitea/` (not `.gitea/` or `.github/`) -- **Wiki**: documentation lives in the Gitea wiki, not `docs/` files +- **Workflow directory**: `.mokogit/` (not `.mokogit/` or `.github/`) +- **Wiki**: documentation lives in the MokoGit wiki, not `docs/` files - **Standards**: [MokoCli](https://git.mokoconsulting.tech/MokoConsulting/mokocli/wiki/Home) diff --git a/mcp/servers/mokomonitor/.mokogitea/ISSUE_TEMPLATE/mcp_api_integration.md b/mcp/servers/mokomonitor/.mokogit/ISSUE_TEMPLATE/mcp_api_integration.md similarity index 100% rename from mcp/servers/mokomonitor/.mokogitea/ISSUE_TEMPLATE/mcp_api_integration.md rename to mcp/servers/mokomonitor/.mokogit/ISSUE_TEMPLATE/mcp_api_integration.md diff --git a/mcp/servers/mokomonitor/.mokogitea/ISSUE_TEMPLATE/mcp_connection_issue.md b/mcp/servers/mokomonitor/.mokogit/ISSUE_TEMPLATE/mcp_connection_issue.md similarity index 100% rename from mcp/servers/mokomonitor/.mokogitea/ISSUE_TEMPLATE/mcp_connection_issue.md rename to mcp/servers/mokomonitor/.mokogit/ISSUE_TEMPLATE/mcp_connection_issue.md diff --git a/mcp/servers/mokomonitor/.mokogitea/ISSUE_TEMPLATE/mcp_tool_request.md b/mcp/servers/mokomonitor/.mokogit/ISSUE_TEMPLATE/mcp_tool_request.md similarity index 100% rename from mcp/servers/mokomonitor/.mokogitea/ISSUE_TEMPLATE/mcp_tool_request.md rename to mcp/servers/mokomonitor/.mokogit/ISSUE_TEMPLATE/mcp_tool_request.md diff --git a/mcp/servers/mokomonitor/.mokogitea/workflows/deploy-manual.yml b/mcp/servers/mokomonitor/.mokogit/workflows/deploy-manual.yml similarity index 100% rename from mcp/servers/mokomonitor/.mokogitea/workflows/deploy-manual.yml rename to mcp/servers/mokomonitor/.mokogit/workflows/deploy-manual.yml diff --git a/mcp/servers/mokomonitor/mcp_mokomonitor/.mokogitea/workflows/gitleaks.yml b/mcp/servers/mokomonitor/.mokogit/workflows/gitleaks.yml similarity index 97% rename from mcp/servers/mokomonitor/mcp_mokomonitor/.mokogitea/workflows/gitleaks.yml rename to mcp/servers/mokomonitor/.mokogit/workflows/gitleaks.yml index f95b1add..a9299a2c 100644 --- a/mcp/servers/mokomonitor/mcp_mokomonitor/.mokogitea/workflows/gitleaks.yml +++ b/mcp/servers/mokomonitor/.mokogit/workflows/gitleaks.yml @@ -3,7 +3,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later # # FILE INFORMATION -# DEFGROUP: Gitea.Workflow +# DEFGROUP: MokoGit.Workflow # INGROUP: MokoCli.Security # REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/MokoCli-API # PATH: /templates/workflows/gitleaks.yml.template @@ -38,7 +38,7 @@ permissions: env: NTFY_URL: ${{ vars.NTFY_URL || 'https://ntfy.mokoconsulting.tech' }} - NTFY_TOPIC: ${{ vars.NTFY_TOPIC || 'gitea-security' }} + NTFY_TOPIC: ${{ vars.NTFY_TOPIC || 'mokogit-security' }} jobs: gitleaks: diff --git a/mcp/servers/mokomonitor/.mokogitea/workflows/pr-branch-check.yml b/mcp/servers/mokomonitor/.mokogit/workflows/pr-branch-check.yml similarity index 100% rename from mcp/servers/mokomonitor/.mokogitea/workflows/pr-branch-check.yml rename to mcp/servers/mokomonitor/.mokogit/workflows/pr-branch-check.yml diff --git a/mcp/servers/mokomonitor/.mokogitea/workflows/repo-health.yml b/mcp/servers/mokomonitor/.mokogit/workflows/repo-health.yml similarity index 98% rename from mcp/servers/mokomonitor/.mokogitea/workflows/repo-health.yml rename to mcp/servers/mokomonitor/.mokogit/workflows/repo-health.yml index 94c04417..07787b79 100644 --- a/mcp/servers/mokomonitor/.mokogitea/workflows/repo-health.yml +++ b/mcp/servers/mokomonitor/.mokogit/workflows/repo-health.yml @@ -6,7 +6,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later # # FILE INFORMATION -# DEFGROUP: Gitea.Workflow +# DEFGROUP: MokoGit.Workflow # INGROUP: MokoCli.Validation # REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/MokoCli-API # PATH: /templates/workflows/joomla/repo_health.yml.template @@ -53,7 +53,7 @@ env: SCRIPTS_ALLOWED_DIRS: scripts,scripts/fix,scripts/lib,scripts/release,scripts/run,scripts/validate # Repo health policy - REPO_REQUIRED_ARTIFACTS: README.md,LICENSE,CHANGELOG.md,CONTRIBUTING.md,CODE_OF_CONDUCT.md,.gitea/workflows/ + REPO_REQUIRED_ARTIFACTS: README.md,LICENSE,CHANGELOG.md,CONTRIBUTING.md,CODE_OF_CONDUCT.md,.mokogit/workflows/ REPO_OPTIONAL_FILES: SECURITY.md,GOVERNANCE.md,.editorconfig,.gitattributes,.gitignore,README.md REPO_DISALLOWED_DIRS: REPO_DISALLOWED_FILES: TODO.md,todo.md @@ -64,7 +64,7 @@ env: # File / directory variables DOCS_INDEX: "" SCRIPT_DIR: scripts - WORKFLOWS_DIR: .gitea/workflows + WORKFLOWS_DIR: .mokogit/workflows SHELLCHECK_PATTERN: '*.sh' SPDX_FILE_GLOBS: '*.sh,*.php,*.js,*.ts,*.css,*.xml,*.yml,*.yaml' FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true @@ -85,7 +85,7 @@ jobs: - name: Check actor permission (admin only) id: perm env: - TOKEN: ${{ secrets.MOKOGITEA_TOKEN || secrets.MOKOGITEA_TOKEN || github.token }} + TOKEN: ${{ secrets.MOKOGIT_TOKEN || secrets.MOKOGIT_TOKEN || github.token }} REPO: ${{ github.repository }} ACTOR: ${{ github.actor }} run: | @@ -96,14 +96,14 @@ jobs: # Hardcoded authorized users — always allowed case "$ACTOR" in - jmiller|gitea-actions[bot]) + jmiller|mokogit-actions[bot]) ALLOWED=true PERMISSION=admin METHOD="hardcoded allowlist" ;; *) # Detect platform and check permissions via API - API_BASE="${GITHUB_API_URL:-${GITEA_API_URL:-https://api.github.com}}" + API_BASE="${GITHUB_API_URL:-${MOKOGIT_API_URL:-https://api.github.com}}" RESP=$(curl -sf -H "Authorization: token ${TOKEN}" \ "${API_BASE}/repos/${REPO}/collaborators/${ACTOR}/permission" 2>/dev/null || echo '{}') PERMISSION=$(echo "$RESP" | grep -oP '"permission"\s*:\s*"\K[^"]+' || echo "unknown") @@ -573,10 +573,6 @@ jobs: joomla_findings+=("No .ini language files found") fi - if [ ! -f 'updates.xml' ]; then - joomla_findings+=("updates.xml missing in root (required for Joomla update server)") - fi - INDEX_DIRS=("${SOURCE_DIR}" "${SOURCE_DIR}/admin" "${SOURCE_DIR}/site") for dir in "${INDEX_DIRS[@]}"; do if [ -d "${dir}" ] && [ ! -f "${dir}/index.html" ]; then diff --git a/mcp/servers/mokomonitor/README.md b/mcp/servers/mokomonitor/README.md index 44eba648..83bd9681 100644 --- a/mcp/servers/mokomonitor/README.md +++ b/mcp/servers/mokomonitor/README.md @@ -15,7 +15,7 @@ MCP server for infrastructure monitoring -- server health, Grafana dashboards, a | **Language** | Node.js | | **License** | GPL-3.0-or-later | | **Config** | `~/.monitor-mcp.json` | -| **Platform** | [Gitea](https://git.mokoconsulting.tech/MokoConsulting/monitor-mcp) (primary) | +| **Platform** | [MokoGit](https://git.mokoconsulting.tech/MokoConsulting/monitor-mcp) (primary) | --- diff --git a/mcp/servers/mokomonitor/mcp_mokomonitor/.gitignore b/mcp/servers/mokomonitor/mcp_mokomonitor/.gitignore index 566bddd8..1f90377a 100644 --- a/mcp/servers/mokomonitor/mcp_mokomonitor/.gitignore +++ b/mcp/servers/mokomonitor/mcp_mokomonitor/.gitignore @@ -1,8 +1,213 @@ -node_modules/ -dist/ -.env -*.log +# ============================================================ +# Local task tracking (not version controlled) +# ============================================================ +TODO.md -# Local config (contains secrets) -config.json +# ============================================================ +# Environment and secrets +# ============================================================ .env +.env.local +.env.*.local +*.local.php +*.secret.php +configuration.php +configuration.*.php +configuration.local.php +conf/conf.php +conf/conf*.php +secrets/ +*.secrets.* + +# ============================================================ +# Logs, dumps and databases +# ============================================================ +*.db +*.db-journal +*.dump +*.log +*.pid +*.seed + + +# ============================================================ +# OS / Editor / IDE cruft +# ============================================================ +.DS_Store +Thumbs.db +desktop.ini +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db +$RECYCLE.BIN/ +System Volume Information/ +*.lnk +Icon? +.idea/ +.settings/ +.claude/ +.gemini/ +.vscode/* +!.vscode/tasks.json +!.vscode/settings.json.example +!.vscode/extensions.json +*.code-workspace +*.sublime* +.project +.buildpath +.classpath +*.bak +*.swp +*.swo +*.tmp +*.old +*.orig + +# ============================================================ +# Dev scripts and scratch +# ============================================================ +TODO.md +todo* +*ffs* + +# ============================================================ +# SFTP / sync tools +# ============================================================ +sftp-config*.json +sftp-config.json.template +sftp-settings.json + +# ============================================================ +# Sublime SFTP / FTP sync +# ============================================================ +*.sublime-project +*.sublime-workspace +*.sublime-settings +.libsass.json +*.ffs* + +# ============================================================ +# Replit / cloud IDE +# ============================================================ +.replit +replit.md + +# ============================================================ +# Archives / release artifacts +# ============================================================ +*.7z +*.rar +*.tar +*.tar.gz +*.tgz +*.zip +artifacts/ +release/ +releases/ + +# ============================================================ +# Build outputs and site generators +# ============================================================ +.mkdocs-build/ +.cache/ +.parcel-cache/ +build/ +dist/ +out/ +/site/ +*.map +*.css.map +*.js.map +*.min.css +*.min.js +*.tsbuildinfo + +# ============================================================ +# CI / test artifacts +# ============================================================ +.coverage +.coverage.* +coverage/ +coverage.xml +htmlcov/ +junit.xml +reports/ +test-results/ +tests/_output/ +.github/local/ +.github/workflows/*.log + +# ============================================================ +# Node / JavaScript +# ============================================================ +node_modules/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +.pnpm-store/ +.yarn/ +.npmrc +.eslintcache +package-lock.json + +# ============================================================ +# PHP / Composer tooling +# ============================================================ +vendor/ +!src/media/vendor/ +composer.lock +*.phar +codeception.phar +.phpunit.result.cache +.php_cs.cache +.php-cs-fixer.cache +.phpstan.cache +.phplint-cache +phpmd-cache/ +.psalm/ +.rector/ + +# ============================================================ +# Python +# ============================================================ +__pycache__/ +*.py[cod] +*.pyc +*$py.class +*.so +.Python +.eggs/ +*.egg +*.egg-info/ +.installed.cfg +/MANIFEST +develop-eggs/ +downloads/ +eggs/ +parts/ +sdist/ +var/ +wheels/ +ENV/ +env/ +.venv/ +venv/ +.pytest_cache/ +.mypy_cache/ +.ruff_cache/ +.pyright/ +.tox/ +.nox/ +*.cover +*.coverage +hypothesis/ + +profile.ps1 +.mcp.json + +# ============================================================ +# Local wiki clone (not version controlled) +# ============================================================ +wiki/ +docs/ diff --git a/mcp/servers/mokomonitor/mcp_mokomonitor/.mokogitea/.moko-platform b/mcp/servers/mokomonitor/mcp_mokomonitor/.mokogit/.moko-platform similarity index 100% rename from mcp/servers/mokomonitor/mcp_mokomonitor/.mokogitea/.moko-platform rename to mcp/servers/mokomonitor/mcp_mokomonitor/.mokogit/.moko-platform diff --git a/mcp/servers/mokomonitor/.mokogitea/CLAUDE.md b/mcp/servers/mokomonitor/mcp_mokomonitor/.mokogit/CLAUDE.md similarity index 91% rename from mcp/servers/mokomonitor/.mokogitea/CLAUDE.md rename to mcp/servers/mokomonitor/mcp_mokomonitor/.mokogit/CLAUDE.md index de7166dd..7dc857f0 100644 --- a/mcp/servers/mokomonitor/.mokogitea/CLAUDE.md +++ b/mcp/servers/mokomonitor/mcp_mokomonitor/.mokogit/CLAUDE.md @@ -39,6 +39,6 @@ src/ - **Never commit** `.claude/`, `.mcp.json`, `TODO.md`, `*.min.css`/`*.min.js` - **Attribution**: `Authored-by: Moko Consulting` -- **Workflow directory**: `.mokogitea/` (not `.gitea/` or `.github/`) -- **Wiki**: documentation lives in the Gitea wiki, not `docs/` files +- **Workflow directory**: `.mokogit/` (not `.mokogit/` or `.github/`) +- **Wiki**: documentation lives in the MokoGit wiki, not `docs/` files - **Standards**: [MokoCli](https://git.mokoconsulting.tech/MokoConsulting/mokocli/wiki/Home) diff --git a/mcp/servers/mokomonitor/mcp_mokomonitor/.mokogitea/ISSUE_TEMPLATE/mcp_api_integration.md b/mcp/servers/mokomonitor/mcp_mokomonitor/.mokogit/ISSUE_TEMPLATE/mcp_api_integration.md similarity index 100% rename from mcp/servers/mokomonitor/mcp_mokomonitor/.mokogitea/ISSUE_TEMPLATE/mcp_api_integration.md rename to mcp/servers/mokomonitor/mcp_mokomonitor/.mokogit/ISSUE_TEMPLATE/mcp_api_integration.md diff --git a/mcp/servers/mokomonitor/mcp_mokomonitor/.mokogitea/ISSUE_TEMPLATE/mcp_connection_issue.md b/mcp/servers/mokomonitor/mcp_mokomonitor/.mokogit/ISSUE_TEMPLATE/mcp_connection_issue.md similarity index 100% rename from mcp/servers/mokomonitor/mcp_mokomonitor/.mokogitea/ISSUE_TEMPLATE/mcp_connection_issue.md rename to mcp/servers/mokomonitor/mcp_mokomonitor/.mokogit/ISSUE_TEMPLATE/mcp_connection_issue.md diff --git a/mcp/servers/mokomonitor/mcp_mokomonitor/.mokogitea/ISSUE_TEMPLATE/mcp_tool_request.md b/mcp/servers/mokomonitor/mcp_mokomonitor/.mokogit/ISSUE_TEMPLATE/mcp_tool_request.md similarity index 100% rename from mcp/servers/mokomonitor/mcp_mokomonitor/.mokogitea/ISSUE_TEMPLATE/mcp_tool_request.md rename to mcp/servers/mokomonitor/mcp_mokomonitor/.mokogit/ISSUE_TEMPLATE/mcp_tool_request.md diff --git a/mcp/servers/mokomonitor/mcp_mokomonitor/.mokogitea/workflows/deploy-manual.yml b/mcp/servers/mokomonitor/mcp_mokomonitor/.mokogit/workflows/deploy-manual.yml similarity index 100% rename from mcp/servers/mokomonitor/mcp_mokomonitor/.mokogitea/workflows/deploy-manual.yml rename to mcp/servers/mokomonitor/mcp_mokomonitor/.mokogit/workflows/deploy-manual.yml diff --git a/mcp/servers/mokosuite_api/.mokogitea/gitleaks.yml b/mcp/servers/mokomonitor/mcp_mokomonitor/.mokogit/workflows/gitleaks.yml similarity index 97% rename from mcp/servers/mokosuite_api/.mokogitea/gitleaks.yml rename to mcp/servers/mokomonitor/mcp_mokomonitor/.mokogit/workflows/gitleaks.yml index f95b1add..a9299a2c 100644 --- a/mcp/servers/mokosuite_api/.mokogitea/gitleaks.yml +++ b/mcp/servers/mokomonitor/mcp_mokomonitor/.mokogit/workflows/gitleaks.yml @@ -3,7 +3,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later # # FILE INFORMATION -# DEFGROUP: Gitea.Workflow +# DEFGROUP: MokoGit.Workflow # INGROUP: MokoCli.Security # REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/MokoCli-API # PATH: /templates/workflows/gitleaks.yml.template @@ -38,7 +38,7 @@ permissions: env: NTFY_URL: ${{ vars.NTFY_URL || 'https://ntfy.mokoconsulting.tech' }} - NTFY_TOPIC: ${{ vars.NTFY_TOPIC || 'gitea-security' }} + NTFY_TOPIC: ${{ vars.NTFY_TOPIC || 'mokogit-security' }} jobs: gitleaks: diff --git a/mcp/servers/mokomonitor/mcp_mokomonitor/.mokogitea/workflows/pr-branch-check.yml b/mcp/servers/mokomonitor/mcp_mokomonitor/.mokogit/workflows/pr-branch-check.yml similarity index 100% rename from mcp/servers/mokomonitor/mcp_mokomonitor/.mokogitea/workflows/pr-branch-check.yml rename to mcp/servers/mokomonitor/mcp_mokomonitor/.mokogit/workflows/pr-branch-check.yml diff --git a/mcp/servers/mokomonitor/mcp_mokomonitor/.mokogitea/workflows/repo-health.yml b/mcp/servers/mokomonitor/mcp_mokomonitor/.mokogit/workflows/repo-health.yml similarity index 98% rename from mcp/servers/mokomonitor/mcp_mokomonitor/.mokogitea/workflows/repo-health.yml rename to mcp/servers/mokomonitor/mcp_mokomonitor/.mokogit/workflows/repo-health.yml index 94c04417..07787b79 100644 --- a/mcp/servers/mokomonitor/mcp_mokomonitor/.mokogitea/workflows/repo-health.yml +++ b/mcp/servers/mokomonitor/mcp_mokomonitor/.mokogit/workflows/repo-health.yml @@ -6,7 +6,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later # # FILE INFORMATION -# DEFGROUP: Gitea.Workflow +# DEFGROUP: MokoGit.Workflow # INGROUP: MokoCli.Validation # REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/MokoCli-API # PATH: /templates/workflows/joomla/repo_health.yml.template @@ -53,7 +53,7 @@ env: SCRIPTS_ALLOWED_DIRS: scripts,scripts/fix,scripts/lib,scripts/release,scripts/run,scripts/validate # Repo health policy - REPO_REQUIRED_ARTIFACTS: README.md,LICENSE,CHANGELOG.md,CONTRIBUTING.md,CODE_OF_CONDUCT.md,.gitea/workflows/ + REPO_REQUIRED_ARTIFACTS: README.md,LICENSE,CHANGELOG.md,CONTRIBUTING.md,CODE_OF_CONDUCT.md,.mokogit/workflows/ REPO_OPTIONAL_FILES: SECURITY.md,GOVERNANCE.md,.editorconfig,.gitattributes,.gitignore,README.md REPO_DISALLOWED_DIRS: REPO_DISALLOWED_FILES: TODO.md,todo.md @@ -64,7 +64,7 @@ env: # File / directory variables DOCS_INDEX: "" SCRIPT_DIR: scripts - WORKFLOWS_DIR: .gitea/workflows + WORKFLOWS_DIR: .mokogit/workflows SHELLCHECK_PATTERN: '*.sh' SPDX_FILE_GLOBS: '*.sh,*.php,*.js,*.ts,*.css,*.xml,*.yml,*.yaml' FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true @@ -85,7 +85,7 @@ jobs: - name: Check actor permission (admin only) id: perm env: - TOKEN: ${{ secrets.MOKOGITEA_TOKEN || secrets.MOKOGITEA_TOKEN || github.token }} + TOKEN: ${{ secrets.MOKOGIT_TOKEN || secrets.MOKOGIT_TOKEN || github.token }} REPO: ${{ github.repository }} ACTOR: ${{ github.actor }} run: | @@ -96,14 +96,14 @@ jobs: # Hardcoded authorized users — always allowed case "$ACTOR" in - jmiller|gitea-actions[bot]) + jmiller|mokogit-actions[bot]) ALLOWED=true PERMISSION=admin METHOD="hardcoded allowlist" ;; *) # Detect platform and check permissions via API - API_BASE="${GITHUB_API_URL:-${GITEA_API_URL:-https://api.github.com}}" + API_BASE="${GITHUB_API_URL:-${MOKOGIT_API_URL:-https://api.github.com}}" RESP=$(curl -sf -H "Authorization: token ${TOKEN}" \ "${API_BASE}/repos/${REPO}/collaborators/${ACTOR}/permission" 2>/dev/null || echo '{}') PERMISSION=$(echo "$RESP" | grep -oP '"permission"\s*:\s*"\K[^"]+' || echo "unknown") @@ -573,10 +573,6 @@ jobs: joomla_findings+=("No .ini language files found") fi - if [ ! -f 'updates.xml' ]; then - joomla_findings+=("updates.xml missing in root (required for Joomla update server)") - fi - INDEX_DIRS=("${SOURCE_DIR}" "${SOURCE_DIR}/admin" "${SOURCE_DIR}/site") for dir in "${INDEX_DIRS[@]}"; do if [ -d "${dir}" ] && [ ! -f "${dir}/index.html" ]; then diff --git a/mcp/servers/mokomonitor/src/index.ts b/mcp/servers/mokomonitor/src/index.ts index ab92a473..b0964bb3 100644 --- a/mcp/servers/mokomonitor/src/index.ts +++ b/mcp/servers/mokomonitor/src/index.ts @@ -41,7 +41,7 @@ server.tool('monitor_processes', 'Top processes by CPU or memory', { }, async ({ connection, sort_by, count }) => text(await clientFor(connection).processes(sort_by ?? 'cpu', count ?? 15))); server.tool('monitor_service', 'Check systemd service status', { - ...Conn, service: z.string().describe('Service name (e.g. gitea, nginx, mysql)'), + ...Conn, service: z.string().describe('Service name (e.g. mokogit, nginx, mysql)'), }, async ({ connection, service }) => text(await clientFor(connection).serviceStatus(service))); server.tool('monitor_logs', 'Tail a log file', { @@ -222,7 +222,7 @@ server.tool('monitor_journal', 'Query systemd journal for a service', { server.tool('monitor_waas_heartbeats', 'List registered MokoWaaS heartbeat provisioning files', { ...Conn }, async ({ connection }) => text(await clientFor(connection).exec( - 'ls -la /opt/gitea-server-setup/docker/monitoring/grafana/provisioning/datasources/mokowaas-*.yml 2>/dev/null || echo "No heartbeat files"'))); + 'ls -la /opt/mokogit-server-setup/docker/monitoring/grafana/provisioning/datasources/mokowaas-*.yml 2>/dev/null || echo "No heartbeat files"'))); server.tool('monitor_docker_containers', 'List Docker containers with status and ports', { ...Conn }, async ({ connection }) => text(await clientFor(connection).exec( @@ -230,7 +230,7 @@ server.tool('monitor_docker_containers', 'List Docker containers with status and server.tool('monitor_prometheus_targets', 'List Prometheus target files and entries', { ...Conn }, async ({ connection }) => text(await clientFor(connection).exec( - 'for f in /opt/gitea-server-setup/docker/monitoring/targets/*.json; do echo "=== $(basename $f) ==="; cat "$f" 2>/dev/null; echo; done'))); + 'for f in /opt/mokogit-server-setup/docker/monitoring/targets/*.json; do echo "=== $(basename $f) ==="; cat "$f" 2>/dev/null; echo; done'))); server.tool('monitor_nginx_status', 'Get nginx connection and request stats', { ...Conn }, async ({ connection }) => text(await clientFor(connection).exec( diff --git a/mcp/servers/mokossh/.env.example b/mcp/servers/mokossh/.env.example index e11b4997..5a22c35b 100644 --- a/mcp/servers/mokossh/.env.example +++ b/mcp/servers/mokossh/.env.example @@ -2,12 +2,12 @@ # Copy to .env and fill in your values # Auth: use KEYPATH (recommended) or PASSWORD -# Gitea Server -SSH_SERVER_GITEA_HOST=git.mokoconsulting.tech -SSH_SERVER_GITEA_USER=root -SSH_SERVER_GITEA_KEYPATH=~/.ssh/id_ed25519 -SSH_SERVER_GITEA_PORT=22 -SSH_SERVER_GITEA_DEFAULT_DIR=/opt +# MokoGit Server +SSH_SERVER_MOKOGIT_HOST=git.mokoconsulting.tech +SSH_SERVER_MOKOGIT_USER=root +SSH_SERVER_MOKOGIT_KEYPATH=~/.ssh/id_ed25519 +SSH_SERVER_MOKOGIT_PORT=22 +SSH_SERVER_MOKOGIT_DEFAULT_DIR=/opt # CRM / Dolibarr Server SSH_SERVER_CRM_HOST=crm.mokoconsulting.tech diff --git a/mcp/servers/mokossh/.gitattributes b/mcp/servers/mokossh/.gitattributes index b01309bd..616dbdc5 100644 --- a/mcp/servers/mokossh/.gitattributes +++ b/mcp/servers/mokossh/.gitattributes @@ -41,7 +41,7 @@ # CI and automation .github/ export-ignore .github/workflows/ export-ignore -.gitea/ export-ignore +.mokogit/ export-ignore .gitlab/ export-ignore # Development and tooling diff --git a/mcp/servers/mokossh/.mokogitea/.mokostandards b/mcp/servers/mokossh/.mokogit/.mokostandards similarity index 100% rename from mcp/servers/mokossh/.mokogitea/.mokostandards rename to mcp/servers/mokossh/.mokogit/.mokostandards diff --git a/mcp/servers/mokossh/.mokogitea/CLAUDE.md b/mcp/servers/mokossh/.mokogit/CLAUDE.md similarity index 97% rename from mcp/servers/mokossh/.mokogitea/CLAUDE.md rename to mcp/servers/mokossh/.mokogit/CLAUDE.md index b53d270b..57004d1d 100644 --- a/mcp/servers/mokossh/.mokogitea/CLAUDE.md +++ b/mcp/servers/mokossh/.mokogit/CLAUDE.md @@ -64,5 +64,5 @@ SSH key: `jmiller_private.openssh` - **Never commit** `.env`, `.claude/`, `.mcp.json`, `TODO.md` - **Attribution**: `Authored-by: Moko Consulting` -- **Workflow directory**: `.mokogitea/` (not `.gitea/` or `.github/`) +- **Workflow directory**: `.mokogit/` (not `.mokogit/` or `.github/`) - **Standards**: [MokoCli](https://git.mokoconsulting.tech/MokoConsulting/mokocli/wiki/Home) diff --git a/mcp/servers/mokossh/.mokogitea/ISSUE_TEMPLATE/adr.md b/mcp/servers/mokossh/.mokogit/ISSUE_TEMPLATE/adr.md similarity index 100% rename from mcp/servers/mokossh/.mokogitea/ISSUE_TEMPLATE/adr.md rename to mcp/servers/mokossh/.mokogit/ISSUE_TEMPLATE/adr.md diff --git a/mcp/servers/mokossh/.mokogitea/ISSUE_TEMPLATE/bug_report.md b/mcp/servers/mokossh/.mokogit/ISSUE_TEMPLATE/bug_report.md similarity index 100% rename from mcp/servers/mokossh/.mokogitea/ISSUE_TEMPLATE/bug_report.md rename to mcp/servers/mokossh/.mokogit/ISSUE_TEMPLATE/bug_report.md diff --git a/mcp/servers/mokossh/.mokogitea/ISSUE_TEMPLATE/config.yml b/mcp/servers/mokossh/.mokogit/ISSUE_TEMPLATE/config.yml similarity index 100% rename from mcp/servers/mokossh/.mokogitea/ISSUE_TEMPLATE/config.yml rename to mcp/servers/mokossh/.mokogit/ISSUE_TEMPLATE/config.yml diff --git a/mcp/servers/mokossh/.mokogitea/ISSUE_TEMPLATE/documentation.md b/mcp/servers/mokossh/.mokogit/ISSUE_TEMPLATE/documentation.md similarity index 100% rename from mcp/servers/mokossh/.mokogitea/ISSUE_TEMPLATE/documentation.md rename to mcp/servers/mokossh/.mokogit/ISSUE_TEMPLATE/documentation.md diff --git a/mcp/servers/mokossh/.mokogitea/ISSUE_TEMPLATE/enterprise_support.md b/mcp/servers/mokossh/.mokogit/ISSUE_TEMPLATE/enterprise_support.md similarity index 100% rename from mcp/servers/mokossh/.mokogitea/ISSUE_TEMPLATE/enterprise_support.md rename to mcp/servers/mokossh/.mokogit/ISSUE_TEMPLATE/enterprise_support.md diff --git a/mcp/servers/mokossh/.mokogitea/ISSUE_TEMPLATE/feature_request.md b/mcp/servers/mokossh/.mokogit/ISSUE_TEMPLATE/feature_request.md similarity index 100% rename from mcp/servers/mokossh/.mokogitea/ISSUE_TEMPLATE/feature_request.md rename to mcp/servers/mokossh/.mokogit/ISSUE_TEMPLATE/feature_request.md diff --git a/mcp/servers/mokossh/.mokogitea/ISSUE_TEMPLATE/firewall-request.md b/mcp/servers/mokossh/.mokogit/ISSUE_TEMPLATE/firewall-request.md similarity index 100% rename from mcp/servers/mokossh/.mokogitea/ISSUE_TEMPLATE/firewall-request.md rename to mcp/servers/mokossh/.mokogit/ISSUE_TEMPLATE/firewall-request.md diff --git a/mcp/servers/mokossh/.mokogitea/ISSUE_TEMPLATE/mcp_api_integration.md b/mcp/servers/mokossh/.mokogit/ISSUE_TEMPLATE/mcp_api_integration.md similarity index 100% rename from mcp/servers/mokossh/.mokogitea/ISSUE_TEMPLATE/mcp_api_integration.md rename to mcp/servers/mokossh/.mokogit/ISSUE_TEMPLATE/mcp_api_integration.md diff --git a/mcp/servers/mokossh/.mokogitea/ISSUE_TEMPLATE/mcp_connection_issue.md b/mcp/servers/mokossh/.mokogit/ISSUE_TEMPLATE/mcp_connection_issue.md similarity index 100% rename from mcp/servers/mokossh/.mokogitea/ISSUE_TEMPLATE/mcp_connection_issue.md rename to mcp/servers/mokossh/.mokogit/ISSUE_TEMPLATE/mcp_connection_issue.md diff --git a/mcp/servers/mokossh/.mokogitea/ISSUE_TEMPLATE/mcp_tool_request.md b/mcp/servers/mokossh/.mokogit/ISSUE_TEMPLATE/mcp_tool_request.md similarity index 100% rename from mcp/servers/mokossh/.mokogitea/ISSUE_TEMPLATE/mcp_tool_request.md rename to mcp/servers/mokossh/.mokogit/ISSUE_TEMPLATE/mcp_tool_request.md diff --git a/mcp/servers/mokossh/.mokogitea/ISSUE_TEMPLATE/question.md b/mcp/servers/mokossh/.mokogit/ISSUE_TEMPLATE/question.md similarity index 100% rename from mcp/servers/mokossh/.mokogitea/ISSUE_TEMPLATE/question.md rename to mcp/servers/mokossh/.mokogit/ISSUE_TEMPLATE/question.md diff --git a/mcp/servers/mokossh/.mokogitea/ISSUE_TEMPLATE/rfc.md b/mcp/servers/mokossh/.mokogit/ISSUE_TEMPLATE/rfc.md similarity index 100% rename from mcp/servers/mokossh/.mokogitea/ISSUE_TEMPLATE/rfc.md rename to mcp/servers/mokossh/.mokogit/ISSUE_TEMPLATE/rfc.md diff --git a/mcp/servers/mokossh/.mokogitea/ISSUE_TEMPLATE/security.md b/mcp/servers/mokossh/.mokogit/ISSUE_TEMPLATE/security.md similarity index 100% rename from mcp/servers/mokossh/.mokogitea/ISSUE_TEMPLATE/security.md rename to mcp/servers/mokossh/.mokogit/ISSUE_TEMPLATE/security.md diff --git a/mcp/servers/mokossh/.mokogitea/ISSUE_TEMPLATE/version.md b/mcp/servers/mokossh/.mokogit/ISSUE_TEMPLATE/version.md similarity index 100% rename from mcp/servers/mokossh/.mokogitea/ISSUE_TEMPLATE/version.md rename to mcp/servers/mokossh/.mokogit/ISSUE_TEMPLATE/version.md diff --git a/mcp/servers/mokossh/.mokogitea/pr-branch-check.yml b/mcp/servers/mokossh/.mokogit/pr-branch-check.yml similarity index 100% rename from mcp/servers/mokossh/.mokogitea/pr-branch-check.yml rename to mcp/servers/mokossh/.mokogit/pr-branch-check.yml diff --git a/mcp/servers/windows/.mokogitea/workflows/auto-assign.yml b/mcp/servers/mokossh/.mokogit/workflows/auto-assign.yml similarity index 98% rename from mcp/servers/windows/.mokogitea/workflows/auto-assign.yml rename to mcp/servers/mokossh/.mokogit/workflows/auto-assign.yml index ab7f5737..b9008a4b 100644 --- a/mcp/servers/windows/.mokogitea/workflows/auto-assign.yml +++ b/mcp/servers/mokossh/.mokogit/workflows/auto-assign.yml @@ -5,7 +5,7 @@ # DEFGROUP: GitHub.Workflow # INGROUP: MokoCli.Workflows.Shared # REPO: https://github.com/mokoconsulting-tech/MokoCli -# PATH: /.mokogitea/workflows/auto-assign.yml +# PATH: /.mokogit/workflows/auto-assign.yml # VERSION: 04.06.00 # BRIEF: Auto-assign jmiller to unassigned issues and PRs every 15 minutes diff --git a/mcp/servers/windows/.mokogitea/workflows/auto-dev-issue.yml b/mcp/servers/mokossh/.mokogit/workflows/auto-dev-issue.yml similarity index 98% rename from mcp/servers/windows/.mokogitea/workflows/auto-dev-issue.yml rename to mcp/servers/mokossh/.mokogit/workflows/auto-dev-issue.yml index a8774aba..f48dac0b 100644 --- a/mcp/servers/windows/.mokogitea/workflows/auto-dev-issue.yml +++ b/mcp/servers/mokossh/.mokogit/workflows/auto-dev-issue.yml @@ -11,7 +11,7 @@ # PATH: /templates/workflows/shared/auto-dev-issue.yml.template # VERSION: 04.06.00 # BRIEF: Auto-create tracking issue with sub-issues for dev/rc branch workflow -# NOTE: Synced via bulk-repo-sync to .mokogitea/workflows/auto-dev-issue.yml in all governed repos. +# NOTE: Synced via bulk-repo-sync to .mokogit/workflows/auto-dev-issue.yml in all governed repos. name: "Universal: Dev/RC Branch Issue" diff --git a/mcp/servers/mokossh/.mokogitea/workflows/auto-release.yml b/mcp/servers/mokossh/.mokogit/workflows/auto-release.yml similarity index 82% rename from mcp/servers/mokossh/.mokogitea/workflows/auto-release.yml rename to mcp/servers/mokossh/.mokogit/workflows/auto-release.yml index 29caa72c..f048f4f4 100644 --- a/mcp/servers/mokossh/.mokogitea/workflows/auto-release.yml +++ b/mcp/servers/mokossh/.mokogit/workflows/auto-release.yml @@ -3,7 +3,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later # # FILE INFORMATION -# DEFGROUP: Gitea.Workflow +# DEFGROUP: MokoGit.Workflow # INGROUP: mokocli.Release # REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/mokocli # PATH: /templates/workflows/universal/auto-release.yml.template @@ -17,7 +17,7 @@ # | Reads manifest.xml (joomla|dolibarr|generic) to branch logic. | # | | # | Platform-specific: | -# | joomla: XML manifest, updates.xml, type-prefixed packages | +# | joomla: XML manifest, type-prefixed packages | # | dolibarr: mod*.class.php, update.txt, dev version reset | # | generic: README-only, no update stream | # | | @@ -37,9 +37,9 @@ on: env: FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true - GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }} - GITEA_ORG: ${{ vars.GITEA_ORG || github.repository_owner }} - GITEA_REPO: ${{ vars.GITEA_REPO || github.event.repository.name }} + MOKOGIT_URL: ${{ vars.MOKOGIT_URL || 'https://git.mokoconsulting.tech' }} + MOKOGIT_ORG: ${{ vars.MOKOGIT_ORG || github.repository_owner }} + MOKOGIT_REPO: ${{ vars.MOKOGIT_REPO || github.event.repository.name }} permissions: contents: write @@ -55,12 +55,12 @@ jobs: - name: Checkout repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: - token: ${{ secrets.MOKOGITEA_TOKEN }} + token: ${{ secrets.MOKOGIT_TOKEN }} fetch-depth: 0 - name: Setup mokocli tools env: - MOKO_CLONE_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }} + MOKO_CLONE_TOKEN: ${{ secrets.MOKOGIT_TOKEN }} MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GH_PAT }}"}}' run: | @@ -263,17 +263,6 @@ jobs: VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" php /tmp/mokocli-api/cli/badge_update.php --path . --version "${VERSION}" 2>/dev/null || true - - name: "Step 5: Write update stream" - if: >- - steps.version.outputs.skip != 'true' && - steps.platform.outputs.platform == 'joomla' - run: | - VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" - php /tmp/mokocli-api/cli/updates_xml_build.php \ - --path . --version "${VERSION}" --stability stable \ - --gitea-url "${GITEA_URL}" --org "${GITEA_ORG}" --repo "${GITEA_REPO}" \ - --github-output - - name: Commit release changes if: >- steps.version.outputs.skip != 'true' && @@ -284,13 +273,13 @@ jobs: exit 0 fi VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" - git config --local user.email "gitea-actions[bot]@mokoconsulting.tech" - git config --local user.name "gitea-actions[bot]" + git config --local user.email "mokogit-actions[bot]@mokoconsulting.tech" + git config --local user.name "mokogit-actions[bot]" # Set push URL with token for branch-protected repos - git remote set-url origin "https://jmiller:${{ secrets.MOKOGITEA_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git" + git remote set-url origin "https://jmiller:${{ secrets.MOKOGIT_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git" git add -A git commit -m "chore(release): build ${VERSION} [skip ci]" \ - --author="gitea-actions[bot] " + --author="mokogit-actions[bot] " git push -u origin HEAD # -- STEP 6: Create tag --------------------------------------------------- @@ -311,8 +300,8 @@ jobs: fi echo "Tag: ${TAG}" >> $GITHUB_STEP_SUMMARY - # -- STEP 7: Create or update Gitea Release -------------------------------- - - name: "Step 7: Gitea Release" + # -- STEP 7: Create or update MokoGit Release -------------------------------- + - name: "Step 7: MokoGit Release" if: >- steps.version.outputs.skip != 'true' run: | @@ -320,7 +309,7 @@ jobs: RELEASE_TAG="${{ steps.version.outputs.release_tag }}" BRANCH="${{ steps.version.outputs.branch }}" MAJOR="${{ steps.version.outputs.major }}" - API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" + API_BASE="${MOKOGIT_URL}/api/v1/repos/${MOKOGIT_ORG}/${MOKOGIT_REPO}" # Reuse metadata from Step 5 (single source of truth) EXT_ELEMENT="${{ steps.updates.outputs.ext_element }}" @@ -330,9 +319,9 @@ jobs: # Fallbacks if Step 5 was skipped if [ -z "$EXT_ELEMENT" ]; then - EXT_ELEMENT=$(echo "${GITEA_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -') + EXT_ELEMENT=$(echo "${MOKOGIT_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -') fi - [ -z "$EXT_NAME" ] && EXT_NAME="${GITEA_REPO}" + [ -z "$EXT_NAME" ] && EXT_NAME="${MOKOGIT_REPO}" NOTES=$(php /tmp/mokocli-api/cli/release_notes.php --path . --version "$VERSION" 2>/dev/null) [ -z "$NOTES" ] && NOTES="Release ${VERSION}" @@ -350,20 +339,20 @@ jobs: RELEASE_NAME="${EXT_NAME} ${VERSION} (${TYPE_PREFIX}${EXT_ELEMENT}-${VERSION})" # Delete existing release if present (overwrite, not append) - EXISTING=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \ + EXISTING=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGIT_TOKEN }}" \ "${API_BASE}/releases/tags/${RELEASE_TAG}" 2>/dev/null || true) EXISTING_ID=$(echo "$EXISTING" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('id',''))" 2>/dev/null || true) if [ -n "$EXISTING_ID" ]; then - curl -sS -X DELETE -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \ + curl -sS -X DELETE -H "Authorization: token ${{ secrets.MOKOGIT_TOKEN }}" \ "${API_BASE}/releases/${EXISTING_ID}" 2>/dev/null || true - curl -sS -X DELETE -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \ + curl -sS -X DELETE -H "Authorization: token ${{ secrets.MOKOGIT_TOKEN }}" \ "${API_BASE}/tags/${RELEASE_TAG}" 2>/dev/null || true echo "Deleted previous stable release (id: ${EXISTING_ID})" fi # Create fresh release - curl -sf -X POST -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \ + curl -sf -X POST -H "Authorization: token ${{ secrets.MOKOGIT_TOKEN }}" \ -H "Content-Type: application/json" \ "${API_BASE}/releases" \ -d "$(python3 -c "import json; print(json.dumps({ @@ -382,10 +371,10 @@ jobs: VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" RELEASE_TAG="${{ steps.version.outputs.release_tag }}" REPO="${{ github.repository }}" - API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" + API_BASE="${MOKOGIT_URL}/api/v1/repos/${MOKOGIT_ORG}/${MOKOGIT_REPO}" # All ZIPs upload to the major release tag (vXX) - RELEASE_JSON=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \ + RELEASE_JSON=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGIT_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 @@ -403,7 +392,7 @@ jobs: EXT_ELEMENT=$(sed -n 's/.*\([^<]*\)<\/element>.*/\1/p' "$MANIFEST" 2>/dev/null | head -1) [ -z "$EXT_ELEMENT" ] && EXT_ELEMENT=$(sed -n 's/.*plugin="\([^"]*\)".*/\1/p' "$MANIFEST" 2>/dev/null | head -1) [ -z "$EXT_ELEMENT" ] && EXT_ELEMENT=$(basename "$MANIFEST" .xml | tr '[:upper:]' '[:lower:]') - [ -z "$EXT_ELEMENT" ] && EXT_ELEMENT=$(echo "${GITEA_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -') + [ -z "$EXT_ELEMENT" ] && EXT_ELEMENT=$(echo "${MOKOGIT_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -') fi # ZIP name: type_folder_element-VERSION (e.g. plg_system_mokojgdpc-01.01.00.zip) EXT_TYPE=$(sed -n 's/.*]*type="\([^"]*\)".*/\1/p' "$MANIFEST" | head -1) @@ -444,7 +433,7 @@ jobs: SHA256_TAR=$(sha256sum "/tmp/${TAR_NAME}" | cut -d' ' -f1) # -- Delete existing assets with same name before uploading ------ - ASSETS=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \ + ASSETS=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGIT_TOKEN }}" \ "${API_BASE}/releases/${RELEASE_ID}/assets" 2>/dev/null || echo "[]") for ASSET_NAME in "$ZIP_NAME" "$TAR_NAME"; do ASSET_ID=$(echo "$ASSETS" | python3 -c " @@ -455,99 +444,22 @@ jobs: print(a['id']); break " 2>/dev/null || true) if [ -n "$ASSET_ID" ]; then - curl -sf -X DELETE -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \ + curl -sf -X DELETE -H "Authorization: token ${{ secrets.MOKOGIT_TOKEN }}" \ "${API_BASE}/releases/${RELEASE_ID}/assets/${ASSET_ID}" 2>/dev/null || true fi done # -- Upload both to release tag ---------------------------------- - curl -sf -X POST -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \ + curl -sf -X POST -H "Authorization: token ${{ secrets.MOKOGIT_TOKEN }}" \ -H "Content-Type: application/octet-stream" \ --data-binary @"/tmp/${ZIP_NAME}" \ "${API_BASE}/releases/${RELEASE_ID}/assets?name=${ZIP_NAME}" > /dev/null 2>&1 || true - curl -sf -X POST -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \ + curl -sf -X POST -H "Authorization: token ${{ secrets.MOKOGIT_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 - # -- Update updates.xml with both download formats --------------- - if [ -f "updates.xml" ]; then - ZIP_URL="${GITEA_URL}/${GITEA_ORG}/${GITEA_REPO}/releases/download/${RELEASE_TAG}/${ZIP_NAME}" - TAR_URL="${GITEA_URL}/${GITEA_ORG}/${GITEA_REPO}/releases/download/${RELEASE_TAG}/${TAR_NAME}" - - # Use Python to update only the stable entry's downloads + sha256 - export PY_ZIP_URL="$ZIP_URL" PY_TAR_URL="$TAR_URL" PY_SHA="$SHA256_ZIP" - python3 << 'PYEOF' - import re, os - - with open("updates.xml") as f: - content = f.read() - - zip_url = os.environ["PY_ZIP_URL"] - tar_url = os.environ["PY_TAR_URL"] - sha = os.environ["PY_SHA"] - - # Find the stable update block and replace its downloads + sha256 - def replace_stable(m): - block = m.group(0) - # Replace downloads block - new_downloads = ( - " \n" - f" {zip_url}\n" - " " - ) - block = re.sub(r' .*?', new_downloads, block, flags=re.DOTALL) - # Add or replace sha256 - if '' in block: - block = re.sub(r' .*?', f' {sha}', block) - else: - block = block.replace('', f'\n {sha}') - return block - - content = re.sub( - r' .*?stable.*?', - replace_stable, - content, - flags=re.DOTALL - ) - - with open("updates.xml", "w") as f: - f.write(content) - PYEOF - - CURRENT_BRANCH="${{ github.ref_name }}" - git add updates.xml - git commit -m "chore(release): ZIP + tar.gz for ${VERSION} [skip ci]" \ - --author="gitea-actions[bot] " || true - git push || true - - # Sync updates.xml to main via direct API (always runs — may be on version/XX branch) - GA_TOKEN="${{ secrets.MOKOGITEA_TOKEN }}" - API="${GITEA_URL:-https://git.mokoconsulting.tech}/api/v1/repos/${{ github.repository }}" - - FILE_SHA=$(curl -sf -H "Authorization: token ${GA_TOKEN}" \ - "${API}/contents/updates.xml?ref=main" | jq -r '.sha // empty') - - if [ -n "$FILE_SHA" ]; then - CONTENT=$(base64 -w0 updates.xml) - curl -sf -X PUT -H "Authorization: token ${GA_TOKEN}" \ - -H "Content-Type: application/json" \ - "${API}/contents/updates.xml" \ - -d "$(jq -n \ - --arg content "$CONTENT" \ - --arg sha "$FILE_SHA" \ - --arg msg "chore: sync updates.xml ${VERSION} [skip ci]" \ - --arg branch "main" \ - '{content: $content, sha: $sha, message: $msg, branch: $branch}' - )" > /dev/null 2>&1 \ - && echo "updates.xml synced to main via API" \ - || echo "WARNING: failed to sync updates.xml to main" - else - echo "WARNING: could not get updates.xml SHA from main" - fi - fi - echo "### Packages" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "| Package | Size | SHA-256 |" >> $GITHUB_STEP_SUMMARY @@ -555,7 +467,7 @@ jobs: echo "| \`${ZIP_NAME}\` | ${ZIP_SIZE} | \`${SHA256_ZIP}\` |" >> $GITHUB_STEP_SUMMARY echo "| \`${TAR_NAME}\` | ${TAR_SIZE} | \`${SHA256_TAR}\` |" >> $GITHUB_STEP_SUMMARY echo "| Release | \`${RELEASE_TAG}\` | |" >> $GITHUB_STEP_SUMMARY - echo "| Download | [${ZIP_NAME}](${GITEA_URL}/${GITEA_ORG}/${GITEA_REPO}/releases/download/${RELEASE_TAG}/${ZIP_NAME}) |" >> $GITHUB_STEP_SUMMARY + echo "| Download | [${ZIP_NAME}](${MOKOGIT_URL}/${MOKOGIT_ORG}/${MOKOGIT_REPO}/releases/download/${RELEASE_TAG}/${ZIP_NAME}) |" >> $GITHUB_STEP_SUMMARY # -- STEP 8b: Update release description with changelog + SHA ---------------- - name: "Step 8b: Update release body with changelog and SHA" @@ -563,7 +475,7 @@ jobs: run: | VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" RELEASE_TAG="${{ steps.version.outputs.release_tag }}" - API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" + API_BASE="${MOKOGIT_URL}/api/v1/repos/${MOKOGIT_ORG}/${MOKOGIT_REPO}" EXT_ELEMENT="${{ steps.updates.outputs.ext_element }}" EXT_TYPE="${{ steps.updates.outputs.ext_type }}" EXT_FOLDER="${{ steps.updates.outputs.ext_folder }}" @@ -605,7 +517,7 @@ jobs: [ -n "$SHA256_TAR" ] && BODY="${BODY}| \`${TAR_NAME}\` | \`${SHA256_TAR}\` |\n" # Get release ID and update body - RELEASE_ID=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \ + RELEASE_ID=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGIT_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) @@ -617,7 +529,7 @@ jobs: req = urllib.request.Request( '${API_BASE}/releases/${RELEASE_ID}', data=data, - headers={'Authorization': 'token ${{ secrets.MOKOGITEA_TOKEN }}', 'Content-Type': 'application/json'}, + headers={'Authorization': 'token ${{ secrets.MOKOGIT_TOKEN }}', 'Content-Type': 'application/json'}, method='PATCH' ) urllib.request.urlopen(req) @@ -644,7 +556,7 @@ jobs: [ -z "$NOTES" ] && NOTES="Release ${VERSION}" echo "$NOTES" > /tmp/release_notes.md - EXISTING=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" "${GITEA_URL:-https://git.mokoconsulting.tech}/api/v1/repos/${{ github.repository }}/releases/tags/$RELEASE_TAG" 2>/dev/null | jq -r ".tag_name // empty" || true) + EXISTING=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGIT_TOKEN }}" "${MOKOGIT_URL:-https://git.mokoconsulting.tech}/api/v1/repos/${{ github.repository }}/releases/tags/$RELEASE_TAG" 2>/dev/null | jq -r ".tag_name // empty" || true) if [ -z "$EXISTING" ]; then gh release create "$RELEASE_TAG" \ @@ -661,8 +573,8 @@ jobs: # Upload assets to GitHub mirror for PKG in /tmp/${EXT_ELEMENT:-pkg}-${VERSION}.*; do if [ -f "$PKG" ]; then - _RELID=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" "${GITEA_URL:-https://git.mokoconsulting.tech}/api/v1/repos/${{ github.repository }}/releases/tags/$RELEASE_TAG" 2>/dev/null | jq -r ".id // empty") - [ -n "$_RELID" ] && curl -sf -X POST -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" -H "Content-Type: application/octet-stream" "${GITEA_URL:-https://git.mokoconsulting.tech}/api/v1/repos/${{ github.repository }}/releases/${_RELID}/assets?name=$(basename $PKG)" --data-binary "@$PKG" > /dev/null 2>&1 || true + _RELID=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGIT_TOKEN }}" "${MOKOGIT_URL:-https://git.mokoconsulting.tech}/api/v1/repos/${{ github.repository }}/releases/tags/$RELEASE_TAG" 2>/dev/null | jq -r ".id // empty") + [ -n "$_RELID" ] && curl -sf -X POST -H "Authorization: token ${{ secrets.MOKOGIT_TOKEN }}" -H "Content-Type: application/octet-stream" "${MOKOGIT_URL:-https://git.mokoconsulting.tech}/api/v1/repos/${{ github.repository }}/releases/${_RELID}/assets?name=$(basename $PKG)" --data-binary "@$PKG" > /dev/null 2>&1 || true fi done echo "GitHub mirror updated: ${GH_REPO} ${RELEASE_TAG}" >> $GITHUB_STEP_SUMMARY @@ -691,16 +603,16 @@ jobs: run: | php /tmp/mokocli-api/cli/release_cascade.php \ --stability stable \ - --token "${{ secrets.MOKOGITEA_TOKEN }}" \ - --org "${GITEA_ORG}" --repo "${GITEA_REPO}" \ - --gitea-url "${GITEA_URL}" 2>/dev/null || true + --token "${{ secrets.MOKOGIT_TOKEN }}" \ + --org "${MOKOGIT_ORG}" --repo "${MOKOGIT_REPO}" \ + --mokogit-url "${MOKOGIT_URL}" 2>/dev/null || true - name: "Step 11: Delete and recreate dev 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 }}" + API_BASE="${MOKOGIT_URL}/api/v1/repos/${MOKOGIT_ORG}/${MOKOGIT_REPO}" + TOKEN="${{ secrets.MOKOGIT_TOKEN }}" # Delete dev branch curl -sf -X DELETE -H "Authorization: token ${TOKEN}" \ @@ -723,8 +635,8 @@ jobs: steps.platform.outputs.mod_file != '' continue-on-error: true run: | - API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" - TOKEN="${{ secrets.MOKOGITEA_TOKEN }}" + API_BASE="${MOKOGIT_URL}/api/v1/repos/${MOKOGIT_ORG}/${MOKOGIT_REPO}" + TOKEN="${{ secrets.MOKOGIT_TOKEN }}" MOD_FILE="${{ steps.platform.outputs.mod_file }}" ENCODED_PATH=$(echo "$MOD_FILE" | sed 's|^\./||' | python3 -c "import sys,urllib.parse; print(urllib.parse.quote(sys.stdin.read().strip()))") FILE_RESP=$(curl -sf -H "Authorization: token ${TOKEN}" "${API_BASE}/contents/${ENCODED_PATH}?ref=dev" 2>/dev/null || true) @@ -758,5 +670,5 @@ jobs: echo "| Version | \`${VERSION}\` |" >> $GITHUB_STEP_SUMMARY echo "| Branch | \`${{ steps.version.outputs.branch }}\` |" >> $GITHUB_STEP_SUMMARY echo "| Tag | \`${{ steps.version.outputs.tag }}\` |" >> $GITHUB_STEP_SUMMARY - echo "| Release | [View](${GITEA_URL}/${GITEA_ORG}/${GITEA_REPO}/releases/tag/${{ steps.version.outputs.tag }}) |" >> $GITHUB_STEP_SUMMARY + echo "| Release | [View](${MOKOGIT_URL}/${MOKOGIT_ORG}/${MOKOGIT_REPO}/releases/tag/${{ steps.version.outputs.tag }}) |" >> $GITHUB_STEP_SUMMARY fi diff --git a/mcp/servers/mokosuite_api/.mokogitea/workflows/cascade-dev.yml b/mcp/servers/mokossh/.mokogit/workflows/cascade-dev.yml similarity index 92% rename from mcp/servers/mokosuite_api/.mokogitea/workflows/cascade-dev.yml rename to mcp/servers/mokossh/.mokogit/workflows/cascade-dev.yml index e47d4262..5160ef52 100644 --- a/mcp/servers/mokosuite_api/.mokogitea/workflows/cascade-dev.yml +++ b/mcp/servers/mokossh/.mokogit/workflows/cascade-dev.yml @@ -3,7 +3,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later # # FILE INFORMATION -# DEFGROUP: Gitea.Workflow +# DEFGROUP: MokoGit.Workflow # INGROUP: mokocli.Maintenance # REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/mokocli # PATH: /templates/workflows/cascade-dev.yml.template @@ -32,9 +32,9 @@ on: env: FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true - GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }} - GITEA_ORG: ${{ vars.GITEA_ORG || github.repository_owner }} - GITEA_REPO: ${{ vars.GITEA_REPO || github.event.repository.name }} + MOKOGIT_URL: ${{ vars.MOKOGIT_URL || 'https://git.mokoconsulting.tech' }} + MOKOGIT_ORG: ${{ vars.MOKOGIT_ORG || github.repository_owner }} + MOKOGIT_REPO: ${{ vars.MOKOGIT_REPO || github.event.repository.name }} permissions: contents: write @@ -52,9 +52,9 @@ jobs: - name: Discover target branches id: branches env: - GA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }} + GA_TOKEN: ${{ secrets.MOKOGIT_TOKEN }} run: | - API="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" + API="${MOKOGIT_URL}/api/v1/repos/${MOKOGIT_ORG}/${MOKOGIT_REPO}" # Fetch all branches (paginated) PAGE=1 @@ -93,9 +93,9 @@ jobs: - name: Cascade to all target branches if: steps.branches.outputs.targets != '' env: - GA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }} + GA_TOKEN: ${{ secrets.MOKOGIT_TOKEN }} run: | - API="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" + API="${MOKOGIT_URL}/api/v1/repos/${MOKOGIT_ORG}/${MOKOGIT_REPO}" SHORT_SHA="${GITHUB_SHA:0:7}" TARGETS="${{ steps.branches.outputs.targets }}" @@ -127,7 +127,7 @@ jobs: # Check for existing cascade PR EXISTING=$(curl -sS \ -H "Authorization: token ${GA_TOKEN}" \ - "${API}/pulls?state=open&head=${GITEA_ORG}:main&base=${ENCODED_BRANCH}&limit=1") + "${API}/pulls?state=open&head=${MOKOGIT_ORG}:main&base=${ENCODED_BRANCH}&limit=1") EXISTING_COUNT=$(echo "$EXISTING" | jq 'length') PR_NUMBER="" diff --git a/mcp/servers/mokossh/.mokogitea/workflows/changelog-validation.yml b/mcp/servers/mokossh/.mokogit/workflows/changelog-validation.yml similarity index 97% rename from mcp/servers/mokossh/.mokogitea/workflows/changelog-validation.yml rename to mcp/servers/mokossh/.mokogit/workflows/changelog-validation.yml index f104937c..3bf54b28 100644 --- a/mcp/servers/mokossh/.mokogitea/workflows/changelog-validation.yml +++ b/mcp/servers/mokossh/.mokogit/workflows/changelog-validation.yml @@ -11,7 +11,7 @@ # PATH: /templates/workflows/shared/changelog-validation.yml.template # VERSION: 04.06.00 # BRIEF: Validates CHANGELOG.md format and version consistency -# NOTE: Deployed to .mokogitea/workflows/changelog-validation.yml in governed repos. +# NOTE: Deployed to .mokogit/workflows/changelog-validation.yml in governed repos. name: "Universal: Changelog Validation" diff --git a/mcp/servers/mokosuite_api/.mokogitea/workflows/cleanup.yml b/mcp/servers/mokossh/.mokogit/workflows/cleanup.yml similarity index 84% rename from mcp/servers/mokosuite_api/.mokogitea/workflows/cleanup.yml rename to mcp/servers/mokossh/.mokogit/workflows/cleanup.yml index 85206066..0b941f23 100644 --- a/mcp/servers/mokosuite_api/.mokogitea/workflows/cleanup.yml +++ b/mcp/servers/mokossh/.mokogit/workflows/cleanup.yml @@ -3,10 +3,10 @@ # SPDX-License-Identifier: GPL-3.0-or-later # # FILE INFORMATION -# DEFGROUP: Gitea.Workflow +# DEFGROUP: MokoGit.Workflow # INGROUP: mokocli.Maintenance # REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli -# PATH: /.gitea/workflows/cleanup.yml +# PATH: /.mokogit/workflows/cleanup.yml # VERSION: 01.00.00 # BRIEF: Scheduled cleanup — delete merged branches and old workflow runs @@ -21,7 +21,7 @@ permissions: contents: write env: - GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }} + MOKOGIT_URL: ${{ vars.MOKOGIT_URL || 'https://git.mokoconsulting.tech' }} jobs: cleanup: @@ -33,14 +33,14 @@ jobs: uses: actions/checkout@v4 with: fetch-depth: 0 - token: ${{ secrets.MOKOGITEA_TOKEN }} + token: ${{ secrets.MOKOGIT_TOKEN }} - name: Delete merged branches env: - GA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }} + GA_TOKEN: ${{ secrets.MOKOGIT_TOKEN }} run: | echo "=== Merged Branch Cleanup ===" - API="${GITEA_URL}/api/v1/repos/${{ github.repository }}" + API="${MOKOGIT_URL}/api/v1/repos/${{ github.repository }}" # List branches via API BRANCHES=$(curl -sS -H "Authorization: token ${GA_TOKEN}" \ @@ -66,10 +66,10 @@ jobs: - name: Clean old workflow runs env: - GA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }} + GA_TOKEN: ${{ secrets.MOKOGIT_TOKEN }} run: | echo "=== Workflow Run Cleanup ===" - API="${GITEA_URL}/api/v1/repos/${{ github.repository }}" + API="${MOKOGIT_URL}/api/v1/repos/${{ github.repository }}" CUTOFF=$(date -d "30 days ago" +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -v-30d +%Y-%m-%dT%H:%M:%SZ) # Get old completed runs diff --git a/mcp/servers/mokosuite_api/.mokogitea/workflows/codeql-analysis.yml b/mcp/servers/mokossh/.mokogit/workflows/codeql-analysis.yml similarity index 97% rename from mcp/servers/mokosuite_api/.mokogitea/workflows/codeql-analysis.yml rename to mcp/servers/mokossh/.mokogit/workflows/codeql-analysis.yml index 0e4c7353..ed9de887 100644 --- a/mcp/servers/mokosuite_api/.mokogitea/workflows/codeql-analysis.yml +++ b/mcp/servers/mokossh/.mokogit/workflows/codeql-analysis.yml @@ -11,7 +11,7 @@ # PATH: /templates/workflows/generic/codeql-analysis.yml.template # VERSION: 04.05.00 # BRIEF: CodeQL security scanning workflow (generic — all repo types) -# NOTE: Deployed to .mokogitea/workflows/codeql-analysis.yml in governed repos. +# NOTE: Deployed to .mokogit/workflows/codeql-analysis.yml in governed repos. # CodeQL does not support PHP directly; JavaScript scans JSON/YAML/shell. # For PHP-specific security scanning see standards-compliance.yml. diff --git a/mcp/servers/mokossh/.mokogitea/workflows/copilot-agent.yml b/mcp/servers/mokossh/.mokogit/workflows/copilot-agent.yml similarity index 100% rename from mcp/servers/mokossh/.mokogitea/workflows/copilot-agent.yml rename to mcp/servers/mokossh/.mokogit/workflows/copilot-agent.yml diff --git a/mcp/servers/mokosuite_api/.mokogitea/workflows/deploy-manual.yml b/mcp/servers/mokossh/.mokogit/workflows/deploy-manual.yml similarity index 92% rename from mcp/servers/mokosuite_api/.mokogitea/workflows/deploy-manual.yml rename to mcp/servers/mokossh/.mokogit/workflows/deploy-manual.yml index 4ebd21eb..f49bf444 100644 --- a/mcp/servers/mokosuite_api/.mokogitea/workflows/deploy-manual.yml +++ b/mcp/servers/mokossh/.mokogit/workflows/deploy-manual.yml @@ -3,7 +3,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later # # FILE INFORMATION -# DEFGROUP: Gitea.Workflow +# DEFGROUP: MokoGit.Workflow # INGROUP: mokocli.Deploy # REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli # PATH: /templates/workflows/joomla/deploy-manual.yml.template @@ -42,10 +42,10 @@ jobs: - name: Setup mokocli tools env: - GA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN || secrets.MOKOGITEA_TOKEN || github.token }} - MOKO_CLONE_TOKEN: ${{ secrets.MOKOGITEA_TOKEN || secrets.MOKOGITEA_TOKEN || github.token }} - MOKO_CLONE_HOST: ${{ secrets.MOKOGITEA_TOKEN && 'git.mokoconsulting.tech/MokoConsulting' || 'github.com/mokoconsulting-tech' }} - COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.MOKOGITEA_TOKEN || github.token }}"}}' + GA_TOKEN: ${{ secrets.MOKOGIT_TOKEN || secrets.MOKOGIT_TOKEN || github.token }} + MOKO_CLONE_TOKEN: ${{ secrets.MOKOGIT_TOKEN || secrets.MOKOGIT_TOKEN || github.token }} + MOKO_CLONE_HOST: ${{ secrets.MOKOGIT_TOKEN && 'git.mokoconsulting.tech/MokoConsulting' || 'github.com/mokoconsulting-tech' }} + COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.MOKOGIT_TOKEN || github.token }}"}}' run: | git clone --depth 1 --branch main --quiet \ "https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/mokocli.git" \ diff --git a/mcp/servers/mokossh/.mokogitea/workflows/enterprise-firewall-setup.yml b/mcp/servers/mokossh/.mokogit/workflows/enterprise-firewall-setup.yml similarity index 100% rename from mcp/servers/mokossh/.mokogitea/workflows/enterprise-firewall-setup.yml rename to mcp/servers/mokossh/.mokogit/workflows/enterprise-firewall-setup.yml diff --git a/mcp/servers/mokosuite_api/.mokogitea/workflows/gitleaks.yml b/mcp/servers/mokossh/.mokogit/workflows/gitleaks.yml similarity index 97% rename from mcp/servers/mokosuite_api/.mokogitea/workflows/gitleaks.yml rename to mcp/servers/mokossh/.mokogit/workflows/gitleaks.yml index 9739b1f4..7ed6d0b6 100644 --- a/mcp/servers/mokosuite_api/.mokogitea/workflows/gitleaks.yml +++ b/mcp/servers/mokossh/.mokogit/workflows/gitleaks.yml @@ -3,7 +3,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later # # FILE INFORMATION -# DEFGROUP: Gitea.Workflow +# DEFGROUP: MokoGit.Workflow # INGROUP: mokocli.Security # REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/mokocli # PATH: /templates/workflows/gitleaks.yml.template @@ -38,7 +38,7 @@ permissions: env: NTFY_URL: ${{ vars.NTFY_URL || 'https://ntfy.mokoconsulting.tech' }} - NTFY_TOPIC: ${{ vars.NTFY_TOPIC || 'gitea-security' }} + NTFY_TOPIC: ${{ vars.NTFY_TOPIC || 'mokogit-security' }} jobs: gitleaks: diff --git a/mcp/servers/mokossh/.mokogitea/workflows/mcp-auto-release.yml b/mcp/servers/mokossh/.mokogit/workflows/mcp-auto-release.yml similarity index 100% rename from mcp/servers/mokossh/.mokogitea/workflows/mcp-auto-release.yml rename to mcp/servers/mokossh/.mokogit/workflows/mcp-auto-release.yml diff --git a/mcp/servers/mokossh/.mokogitea/workflows/mcp-build-test.yml b/mcp/servers/mokossh/.mokogit/workflows/mcp-build-test.yml similarity index 100% rename from mcp/servers/mokossh/.mokogitea/workflows/mcp-build-test.yml rename to mcp/servers/mokossh/.mokogit/workflows/mcp-build-test.yml diff --git a/mcp/servers/mokossh/.mokogitea/workflows/mcp-sdk-check.yml b/mcp/servers/mokossh/.mokogit/workflows/mcp-sdk-check.yml similarity index 100% rename from mcp/servers/mokossh/.mokogitea/workflows/mcp-sdk-check.yml rename to mcp/servers/mokossh/.mokogit/workflows/mcp-sdk-check.yml diff --git a/mcp/servers/mokossh/.mokogitea/workflows/mcp-tool-inventory.yml b/mcp/servers/mokossh/.mokogit/workflows/mcp-tool-inventory.yml similarity index 100% rename from mcp/servers/mokossh/.mokogitea/workflows/mcp-tool-inventory.yml rename to mcp/servers/mokossh/.mokogit/workflows/mcp-tool-inventory.yml diff --git a/mcp/servers/mokosuite_api/.mokogitea/workflows/notify.yml b/mcp/servers/mokossh/.mokogit/workflows/notify.yml similarity index 94% rename from mcp/servers/mokosuite_api/.mokogitea/workflows/notify.yml rename to mcp/servers/mokossh/.mokogit/workflows/notify.yml index 0e3ad8ec..d69d4021 100644 --- a/mcp/servers/mokosuite_api/.mokogitea/workflows/notify.yml +++ b/mcp/servers/mokossh/.mokogit/workflows/notify.yml @@ -3,10 +3,10 @@ # SPDX-License-Identifier: GPL-3.0-or-later # # FILE INFORMATION -# DEFGROUP: Gitea.Workflow +# DEFGROUP: MokoGit.Workflow # INGROUP: mokocli.Notifications # REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli -# PATH: /.gitea/workflows/notify.yml +# PATH: /.mokogit/workflows/notify.yml # VERSION: 01.00.00 # BRIEF: Push notifications via ntfy on release success or workflow failure @@ -26,7 +26,7 @@ permissions: env: NTFY_URL: ${{ vars.NTFY_URL || 'https://ntfy.mokoconsulting.tech' }} - NTFY_TOPIC: ${{ vars.NTFY_TOPIC || 'gitea-releases' }} + NTFY_TOPIC: ${{ vars.NTFY_TOPIC || 'mokogit-releases' }} jobs: notify: diff --git a/mcp/servers/mokossh/.mokogitea/workflows/pr-check.yml b/mcp/servers/mokossh/.mokogit/workflows/pr-check.yml similarity index 87% rename from mcp/servers/mokossh/.mokogitea/workflows/pr-check.yml rename to mcp/servers/mokossh/.mokogit/workflows/pr-check.yml index 573efeda..ca0819c4 100644 --- a/mcp/servers/mokossh/.mokogitea/workflows/pr-check.yml +++ b/mcp/servers/mokossh/.mokogit/workflows/pr-check.yml @@ -3,7 +3,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later # # FILE INFORMATION -# DEFGROUP: Gitea.Workflow +# DEFGROUP: MokoGit.Workflow # INGROUP: mokocli.CI # REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/mokocli # PATH: /templates/workflows/universal/pr-check.yml.template @@ -109,8 +109,8 @@ jobs: id: platform run: | # Read platform from XML manifest ( tag) or plain text fallback - PLATFORM=$(sed -n 's/.*\([^<]*\)<\/platform>.*/\1/p' .mokogitea/manifest.xml 2>/dev/null | head -1) - [ -z "$PLATFORM" ] && PLATFORM=$(cat .mokogitea/manifest.xml 2>/dev/null | tr -d '[:space:]') + PLATFORM=$(sed -n 's/.*\([^<]*\)<\/platform>.*/\1/p' .mokogit/manifest.xml 2>/dev/null | head -1) + [ -z "$PLATFORM" ] && PLATFORM=$(cat .mokogit/manifest.xml 2>/dev/null | tr -d '[:space:]') [ -z "$PLATFORM" ] && PLATFORM="generic" echo "platform=$PLATFORM" >> "$GITHUB_OUTPUT" @@ -166,23 +166,6 @@ jobs: ;; esac - - name: Check update stream format - run: | - PLATFORM="${{ steps.platform.outputs.platform }}" - case "$PLATFORM" in - joomla) - if [ -f "updates.xml" ]; then - if command -v php &> /dev/null; then - php -r "libxml_use_internal_errors(true); \$x = simplexml_load_file('updates.xml'); if(!\$x){foreach(libxml_get_errors() as \$e) echo \$e->message; exit(1);}" || { echo "::error::updates.xml is malformed"; exit 1; } - fi - echo "updates.xml valid" - fi - ;; - dolibarr) - [ -f "update.txt" ] && echo "update.txt present" || echo "::warning::No update.txt" - ;; - esac - - name: Verify package source run: | SOURCE_DIR="src" diff --git a/mcp/servers/mokosuite_api/.mokogitea/workflows/pre-release.yml b/mcp/servers/mokossh/.mokogit/workflows/pre-release.yml similarity index 78% rename from mcp/servers/mokosuite_api/.mokogitea/workflows/pre-release.yml rename to mcp/servers/mokossh/.mokogit/workflows/pre-release.yml index 257763cb..a598ceb2 100644 --- a/mcp/servers/mokosuite_api/.mokogitea/workflows/pre-release.yml +++ b/mcp/servers/mokossh/.mokogit/workflows/pre-release.yml @@ -3,7 +3,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later # # FILE INFORMATION -# DEFGROUP: Gitea.Workflow +# DEFGROUP: MokoGit.Workflow # INGROUP: mokocli.Release # REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli # PATH: /templates/workflows/universal/pre-release.yml.template @@ -29,9 +29,9 @@ permissions: contents: write env: - GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }} - GITEA_ORG: ${{ vars.GITEA_ORG || github.repository_owner }} - GITEA_REPO: ${{ vars.GITEA_REPO || github.event.repository.name }} + MOKOGIT_URL: ${{ vars.MOKOGIT_URL || 'https://git.mokoconsulting.tech' }} + MOKOGIT_ORG: ${{ vars.MOKOGIT_ORG || github.repository_owner }} + MOKOGIT_REPO: ${{ vars.MOKOGIT_REPO || github.event.repository.name }} jobs: build: @@ -43,7 +43,7 @@ jobs: uses: actions/checkout@v4 with: fetch-depth: 0 - token: ${{ secrets.MOKOGITEA_TOKEN }} + token: ${{ secrets.MOKOGIT_TOKEN }} - name: Setup PHP run: | @@ -54,7 +54,7 @@ jobs: - name: Setup mokocli tools env: - MOKO_CLONE_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }} + MOKO_CLONE_TOKEN: ${{ secrets.MOKOGIT_TOKEN }} MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting run: | git clone --depth 1 --branch main --quiet "https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/mokocli.git" /tmp/mokocli-api @@ -87,9 +87,9 @@ jobs: php ${MOKO_API}/version_set_platform.php --path . --version "${VERSION}" # Commit version bump - git config --local user.email "gitea-actions[bot]@mokoconsulting.tech" - git config --local user.name "gitea-actions[bot]" - git remote set-url origin "https://jmiller:${{ secrets.MOKOGITEA_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git" + git config --local user.email "mokogit-actions[bot]@mokoconsulting.tech" + git config --local user.name "mokogit-actions[bot]" + git remote set-url origin "https://jmiller:${{ secrets.MOKOGIT_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git" git add -A git diff --cached --quiet || { git commit -m "chore(version): bump to ${VERSION} [skip ci]" @@ -107,7 +107,7 @@ jobs: [ -n "$ELEM" ] && EXT_ELEMENT="$ELEM" fi fi - [ -z "$EXT_ELEMENT" ] && EXT_ELEMENT=$(echo "${GITEA_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -') + [ -z "$EXT_ELEMENT" ] && EXT_ELEMENT=$(echo "${MOKOGIT_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -') ZIP_NAME="${EXT_ELEMENT}-${VERSION}${SUFFIX}.zip" @@ -144,7 +144,7 @@ jobs: echo "sha256=${SHA256}" >> "$GITHUB_OUTPUT" fi - - name: Create or replace Gitea release + - name: Create or replace MokoGit release id: release continue-on-error: true run: | @@ -154,8 +154,8 @@ jobs: SHA256="${{ steps.zip.outputs.sha256 }}" ZIP_NAME="${{ steps.zip.outputs.zip_name }}" EXT_ELEMENT="${{ steps.meta.outputs.ext_element }}" - TOKEN="${{ secrets.MOKOGITEA_TOKEN }}" - API="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" + TOKEN="${{ secrets.MOKOGIT_TOKEN }}" + API="${MOKOGIT_URL}/api/v1/repos/${MOKOGIT_ORG}/${MOKOGIT_REPO}" BRANCH=$(git branch --show-current) BODY="## ${VERSION} ($(date +%Y-%m-%d)) @@ -194,31 +194,11 @@ jobs: echo "Released: ${EXT_ELEMENT} ${VERSION} (${STABILITY})" - - name: "Update updates.xml" - if: steps.platform.outputs.platform == 'joomla' - run: | - VERSION="${{ steps.meta.outputs.version }}" - STABILITY="${{ steps.meta.outputs.stability }}" - SHA256="${{ steps.zip.outputs.sha256 }}" - php /tmp/mokocli-api/cli/updates_xml_build.php --path . --version "$VERSION" --stability "$STABILITY" --sha "$SHA256" --gitea-url "$GITEA_URL" --org "$GITEA_ORG" --repo "$GITEA_REPO" - 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 add updates.xml - git commit -m "chore: update $STABILITY channel $VERSION [skip ci]" - git push origin HEAD 2>&1 || echo "WARNING: push failed" - fi - - - name: "Sync updates.xml to all branches" - if: steps.platform.outputs.platform == 'joomla' - run: | - php /tmp/mokocli-api/cli/updates_xml_sync.php --path . --current "${{ github.ref_name }}" --branches main,dev --version "${{ steps.meta.outputs.version }}" --token "${{ secrets.MOKOGITEA_TOKEN }}" --org "${GITEA_ORG}" --repo "${GITEA_REPO}" --gitea-url "${GITEA_URL}" - - name: "Delete lesser pre-release channels (cascade)" continue-on-error: true run: | - API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" - TOKEN="${{ secrets.MOKOGITEA_TOKEN }}" + API_BASE="${MOKOGIT_URL}/api/v1/repos/${MOKOGIT_ORG}/${MOKOGIT_REPO}" + TOKEN="${{ secrets.MOKOGIT_TOKEN }}" STABILITY="${{ steps.meta.outputs.stability }}" # Cascade: rc → beta,alpha,dev | beta → alpha,dev | alpha → dev | dev → nothing diff --git a/mcp/servers/mokosuite_api/.mokogitea/workflows/repo-health.yml b/mcp/servers/mokossh/.mokogit/workflows/repo-health.yml similarity index 98% rename from mcp/servers/mokosuite_api/.mokogitea/workflows/repo-health.yml rename to mcp/servers/mokossh/.mokogit/workflows/repo-health.yml index 48f27ab2..08cd303c 100644 --- a/mcp/servers/mokosuite_api/.mokogitea/workflows/repo-health.yml +++ b/mcp/servers/mokossh/.mokogit/workflows/repo-health.yml @@ -6,7 +6,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later # # FILE INFORMATION -# DEFGROUP: Gitea.Workflow +# DEFGROUP: MokoGit.Workflow # INGROUP: mokocli.Validation # REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/mokocli # PATH: /templates/workflows/joomla/repo_health.yml.template @@ -49,7 +49,7 @@ env: SCRIPTS_ALLOWED_DIRS: scripts,scripts/fix,scripts/lib,scripts/release,scripts/run,scripts/validate # Repo health policy - REPO_REQUIRED_ARTIFACTS: README.md,LICENSE,CHANGELOG.md,CONTRIBUTING.md,CODE_OF_CONDUCT.md,.gitea/workflows/ + REPO_REQUIRED_ARTIFACTS: README.md,LICENSE,CHANGELOG.md,CONTRIBUTING.md,CODE_OF_CONDUCT.md,.mokogit/workflows/ REPO_OPTIONAL_FILES: SECURITY.md,GOVERNANCE.md,.editorconfig,.gitattributes,.gitignore,README.md,docs/ REPO_DISALLOWED_DIRS: REPO_DISALLOWED_FILES: TODO.md,todo.md @@ -60,7 +60,7 @@ env: # File / directory variables DOCS_INDEX: docs/docs-index.md SCRIPT_DIR: scripts - WORKFLOWS_DIR: .gitea/workflows + WORKFLOWS_DIR: .mokogit/workflows SHELLCHECK_PATTERN: '*.sh' SPDX_FILE_GLOBS: '*.sh,*.php,*.js,*.ts,*.css,*.xml,*.yml,*.yaml' FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true @@ -81,7 +81,7 @@ jobs: - name: Check actor permission (admin only) id: perm env: - TOKEN: ${{ secrets.MOKOGITEA_TOKEN || secrets.MOKOGITEA_TOKEN || github.token }} + TOKEN: ${{ secrets.MOKOGIT_TOKEN || secrets.MOKOGIT_TOKEN || github.token }} REPO: ${{ github.repository }} ACTOR: ${{ github.actor }} run: | @@ -92,14 +92,14 @@ jobs: # Hardcoded authorized users — always allowed case "$ACTOR" in - jmiller|gitea-actions[bot]) + jmiller|mokogit-actions[bot]) ALLOWED=true PERMISSION=admin METHOD="hardcoded allowlist" ;; *) # Detect platform and check permissions via API - API_BASE="${GITHUB_API_URL:-${GITEA_API_URL:-https://api.github.com}}" + API_BASE="${GITHUB_API_URL:-${MOKOGIT_API_URL:-https://api.github.com}}" RESP=$(curl -sf -H "Authorization: token ${TOKEN}" \ "${API_BASE}/repos/${REPO}/collaborators/${ACTOR}/permission" 2>/dev/null || echo '{}') PERMISSION=$(echo "$RESP" | grep -oP '"permission"\s*:\s*"\K[^"]+' || echo "unknown") @@ -551,10 +551,6 @@ jobs: joomla_findings+=("No .ini language files found") fi - if [ ! -f 'updates.xml' ]; then - joomla_findings+=("updates.xml missing in root (required for Joomla update server)") - fi - if [ -n "${SOURCE_DIR}" ]; then INDEX_DIRS=("${SOURCE_DIR}" "${SOURCE_DIR}/admin" "${SOURCE_DIR}/site") for dir in "${INDEX_DIRS[@]}"; do diff --git a/mcp/servers/windows/.mokogitea/workflows/repository-cleanup.yml b/mcp/servers/mokossh/.mokogit/workflows/repository-cleanup.yml similarity index 99% rename from mcp/servers/windows/.mokogitea/workflows/repository-cleanup.yml rename to mcp/servers/mokossh/.mokogit/workflows/repository-cleanup.yml index 0468b176..bce1b895 100644 --- a/mcp/servers/windows/.mokogitea/workflows/repository-cleanup.yml +++ b/mcp/servers/mokossh/.mokogit/workflows/repository-cleanup.yml @@ -11,7 +11,7 @@ # PATH: /templates/workflows/shared/repository-cleanup.yml.template # VERSION: 04.06.00 # BRIEF: Recurring repository maintenance — labels, branches, workflows, logs, doc indexes -# NOTE: Synced via bulk-repo-sync to .mokogitea/workflows/repository-cleanup.yml in all governed repos. +# NOTE: Synced via bulk-repo-sync to .mokogit/workflows/repository-cleanup.yml in all governed repos. # Runs on the 1st and 15th of each month at 6:00 AM UTC, and on manual dispatch. name: "Universal: Repository Cleanup" diff --git a/mcp/servers/mokosuite_api/.mokogitea/workflows/security-audit.yml b/mcp/servers/mokossh/.mokogit/workflows/security-audit.yml similarity index 95% rename from mcp/servers/mokosuite_api/.mokogitea/workflows/security-audit.yml rename to mcp/servers/mokossh/.mokogit/workflows/security-audit.yml index 2406a072..30811344 100644 --- a/mcp/servers/mokosuite_api/.mokogitea/workflows/security-audit.yml +++ b/mcp/servers/mokossh/.mokogit/workflows/security-audit.yml @@ -3,10 +3,10 @@ # SPDX-License-Identifier: GPL-3.0-or-later # # FILE INFORMATION -# DEFGROUP: Gitea.Workflow +# DEFGROUP: MokoGit.Workflow # INGROUP: mokocli.Security # REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli -# PATH: /.gitea/workflows/security-audit.yml +# PATH: /.mokogit/workflows/security-audit.yml # VERSION: 01.00.00 # BRIEF: Dependency vulnerability scanning for composer and npm packages @@ -30,7 +30,7 @@ permissions: env: NTFY_URL: ${{ vars.NTFY_URL || 'https://ntfy.mokoconsulting.tech' }} - NTFY_TOPIC: ${{ vars.NTFY_TOPIC || 'gitea-security' }} + NTFY_TOPIC: ${{ vars.NTFY_TOPIC || 'mokogit-security' }} jobs: audit: diff --git a/mcp/servers/mokossh/.mokogitea/workflows/standards-compliance.yml b/mcp/servers/mokossh/.mokogit/workflows/standards-compliance.yml similarity index 99% rename from mcp/servers/mokossh/.mokogitea/workflows/standards-compliance.yml rename to mcp/servers/mokossh/.mokogit/workflows/standards-compliance.yml index 77741610..19197e37 100644 --- a/mcp/servers/mokossh/.mokogitea/workflows/standards-compliance.yml +++ b/mcp/servers/mokossh/.mokogit/workflows/standards-compliance.yml @@ -4,7 +4,7 @@ # DEFGROUP: GitHub.Workflow # INGROUP: MokoCli.Compliance # REPO: https://github.com/mokoconsulting-tech/MokoCli -# PATH: /.mokogitea/workflows/standards-compliance.yml +# PATH: /.mokogit/workflows/standards-compliance.yml # VERSION: 04.06.00 # BRIEF: MokoCli compliance validation workflow # NOTE: Validates repository structure, documentation, and coding standards diff --git a/mcp/servers/mokossh/.mokogitea/workflows/sync-version-on-merge.yml b/mcp/servers/mokossh/.mokogit/workflows/sync-version-on-merge.yml similarity index 97% rename from mcp/servers/mokossh/.mokogitea/workflows/sync-version-on-merge.yml rename to mcp/servers/mokossh/.mokogit/workflows/sync-version-on-merge.yml index a3238bdb..af1a686d 100644 --- a/mcp/servers/mokossh/.mokogitea/workflows/sync-version-on-merge.yml +++ b/mcp/servers/mokossh/.mokogit/workflows/sync-version-on-merge.yml @@ -11,7 +11,7 @@ # PATH: /templates/workflows/shared/sync-version-on-merge.yml.template # VERSION: 04.06.00 # BRIEF: Auto-bump patch version on every push to main and propagate to all file headers -# NOTE: Synced via bulk-repo-sync to .mokogitea/workflows/sync-version-on-merge.yml in all governed repos. +# NOTE: Synced via bulk-repo-sync to .mokogit/workflows/sync-version-on-merge.yml in all governed repos. # README.md is the single source of truth for the repository version. name: "Universal: Sync Version on Merge" diff --git a/mcp/servers/mokossh/README.md b/mcp/servers/mokossh/README.md index d51cfb98..6be5b810 100644 --- a/mcp/servers/mokossh/README.md +++ b/mcp/servers/mokossh/README.md @@ -16,7 +16,7 @@ Model Context Protocol server for SSH remote server management -- execute comman | **Tools** | 37 tools across 6 groups | | **License** | MIT | | **Upstream** | [bvisible/mcp-ssh-manager](https://github.com/bvisible/mcp-ssh-manager) v3.4.0 | -| **Platform** | [Gitea](https://git.mokoconsulting.tech/MokoConsulting/ssh-mcp) (primary) | +| **Platform** | [MokoGit](https://git.mokoconsulting.tech/MokoConsulting/ssh-mcp) (primary) | --- diff --git a/mcp/servers/mokosuite_api/.mokogitea/CLAUDE.md b/mcp/servers/mokosuite_api/.mokogit/CLAUDE.md similarity index 91% rename from mcp/servers/mokosuite_api/.mokogitea/CLAUDE.md rename to mcp/servers/mokosuite_api/.mokogit/CLAUDE.md index 25486045..75410a95 100644 --- a/mcp/servers/mokosuite_api/.mokogitea/CLAUDE.md +++ b/mcp/servers/mokosuite_api/.mokogit/CLAUDE.md @@ -38,6 +38,6 @@ src/ - **Never commit** `.claude/`, `.mcp.json`, `TODO.md`, `*.min.css`/`*.min.js` - **Attribution**: `Authored-by: Moko Consulting` -- **Workflow directory**: `.mokogitea/` (not `.gitea/` or `.github/`) -- **Wiki**: documentation lives in the Gitea wiki, not `docs/` files +- **Workflow directory**: `.mokogit/` (not `.mokogit/` or `.github/`) +- **Wiki**: documentation lives in the MokoGit wiki, not `docs/` files - **Standards**: [MokoCli](https://git.mokoconsulting.tech/MokoConsulting/mokocli/wiki/Home) diff --git a/mcp/servers/mokosuite_api/.mokogitea/ISSUE_TEMPLATE/adr.md b/mcp/servers/mokosuite_api/.mokogit/ISSUE_TEMPLATE/adr.md similarity index 100% rename from mcp/servers/mokosuite_api/.mokogitea/ISSUE_TEMPLATE/adr.md rename to mcp/servers/mokosuite_api/.mokogit/ISSUE_TEMPLATE/adr.md diff --git a/mcp/servers/mokosuite_api/.mokogitea/ISSUE_TEMPLATE/bug_report.md b/mcp/servers/mokosuite_api/.mokogit/ISSUE_TEMPLATE/bug_report.md similarity index 100% rename from mcp/servers/mokosuite_api/.mokogitea/ISSUE_TEMPLATE/bug_report.md rename to mcp/servers/mokosuite_api/.mokogit/ISSUE_TEMPLATE/bug_report.md diff --git a/mcp/servers/mokosuite_api/.mokogitea/ISSUE_TEMPLATE/config.yml b/mcp/servers/mokosuite_api/.mokogit/ISSUE_TEMPLATE/config.yml similarity index 100% rename from mcp/servers/mokosuite_api/.mokogitea/ISSUE_TEMPLATE/config.yml rename to mcp/servers/mokosuite_api/.mokogit/ISSUE_TEMPLATE/config.yml diff --git a/mcp/servers/mokosuite_api/.mokogitea/ISSUE_TEMPLATE/documentation.md b/mcp/servers/mokosuite_api/.mokogit/ISSUE_TEMPLATE/documentation.md similarity index 100% rename from mcp/servers/mokosuite_api/.mokogitea/ISSUE_TEMPLATE/documentation.md rename to mcp/servers/mokosuite_api/.mokogit/ISSUE_TEMPLATE/documentation.md diff --git a/mcp/servers/mokosuite_api/.mokogitea/ISSUE_TEMPLATE/enterprise_support.md b/mcp/servers/mokosuite_api/.mokogit/ISSUE_TEMPLATE/enterprise_support.md similarity index 100% rename from mcp/servers/mokosuite_api/.mokogitea/ISSUE_TEMPLATE/enterprise_support.md rename to mcp/servers/mokosuite_api/.mokogit/ISSUE_TEMPLATE/enterprise_support.md diff --git a/mcp/servers/mokosuite_api/.mokogitea/ISSUE_TEMPLATE/feature_request.md b/mcp/servers/mokosuite_api/.mokogit/ISSUE_TEMPLATE/feature_request.md similarity index 100% rename from mcp/servers/mokosuite_api/.mokogitea/ISSUE_TEMPLATE/feature_request.md rename to mcp/servers/mokosuite_api/.mokogit/ISSUE_TEMPLATE/feature_request.md diff --git a/mcp/servers/mokosuite_api/.mokogitea/ISSUE_TEMPLATE/firewall-request.md b/mcp/servers/mokosuite_api/.mokogit/ISSUE_TEMPLATE/firewall-request.md similarity index 100% rename from mcp/servers/mokosuite_api/.mokogitea/ISSUE_TEMPLATE/firewall-request.md rename to mcp/servers/mokosuite_api/.mokogit/ISSUE_TEMPLATE/firewall-request.md diff --git a/mcp/servers/mokosuite_api/.mokogitea/ISSUE_TEMPLATE/mcp_api_integration.md b/mcp/servers/mokosuite_api/.mokogit/ISSUE_TEMPLATE/mcp_api_integration.md similarity index 100% rename from mcp/servers/mokosuite_api/.mokogitea/ISSUE_TEMPLATE/mcp_api_integration.md rename to mcp/servers/mokosuite_api/.mokogit/ISSUE_TEMPLATE/mcp_api_integration.md diff --git a/mcp/servers/mokosuite_api/.mokogitea/ISSUE_TEMPLATE/mcp_connection_issue.md b/mcp/servers/mokosuite_api/.mokogit/ISSUE_TEMPLATE/mcp_connection_issue.md similarity index 100% rename from mcp/servers/mokosuite_api/.mokogitea/ISSUE_TEMPLATE/mcp_connection_issue.md rename to mcp/servers/mokosuite_api/.mokogit/ISSUE_TEMPLATE/mcp_connection_issue.md diff --git a/mcp/servers/mokosuite_api/.mokogitea/ISSUE_TEMPLATE/mcp_tool_request.md b/mcp/servers/mokosuite_api/.mokogit/ISSUE_TEMPLATE/mcp_tool_request.md similarity index 100% rename from mcp/servers/mokosuite_api/.mokogitea/ISSUE_TEMPLATE/mcp_tool_request.md rename to mcp/servers/mokosuite_api/.mokogit/ISSUE_TEMPLATE/mcp_tool_request.md diff --git a/mcp/servers/mokosuite_api/.mokogitea/ISSUE_TEMPLATE/question.md b/mcp/servers/mokosuite_api/.mokogit/ISSUE_TEMPLATE/question.md similarity index 100% rename from mcp/servers/mokosuite_api/.mokogitea/ISSUE_TEMPLATE/question.md rename to mcp/servers/mokosuite_api/.mokogit/ISSUE_TEMPLATE/question.md diff --git a/mcp/servers/mokosuite_api/.mokogitea/ISSUE_TEMPLATE/rfc.md b/mcp/servers/mokosuite_api/.mokogit/ISSUE_TEMPLATE/rfc.md similarity index 100% rename from mcp/servers/mokosuite_api/.mokogitea/ISSUE_TEMPLATE/rfc.md rename to mcp/servers/mokosuite_api/.mokogit/ISSUE_TEMPLATE/rfc.md diff --git a/mcp/servers/mokosuite_api/.mokogitea/ISSUE_TEMPLATE/security.md b/mcp/servers/mokosuite_api/.mokogit/ISSUE_TEMPLATE/security.md similarity index 100% rename from mcp/servers/mokosuite_api/.mokogitea/ISSUE_TEMPLATE/security.md rename to mcp/servers/mokosuite_api/.mokogit/ISSUE_TEMPLATE/security.md diff --git a/mcp/servers/mokosuite_api/.mokogitea/ISSUE_TEMPLATE/version.md b/mcp/servers/mokosuite_api/.mokogit/ISSUE_TEMPLATE/version.md similarity index 100% rename from mcp/servers/mokosuite_api/.mokogitea/ISSUE_TEMPLATE/version.md rename to mcp/servers/mokosuite_api/.mokogit/ISSUE_TEMPLATE/version.md diff --git a/mcp/servers/mokosuite_api/.mokogitea/auto-assign.yml b/mcp/servers/mokosuite_api/.mokogit/auto-assign.yml similarity index 100% rename from mcp/servers/mokosuite_api/.mokogitea/auto-assign.yml rename to mcp/servers/mokosuite_api/.mokogit/auto-assign.yml diff --git a/mcp/servers/mokosuite_api/.mokogitea/auto-dev-issue.yml b/mcp/servers/mokosuite_api/.mokogit/auto-dev-issue.yml similarity index 100% rename from mcp/servers/mokosuite_api/.mokogitea/auto-dev-issue.yml rename to mcp/servers/mokosuite_api/.mokogit/auto-dev-issue.yml diff --git a/mcp/servers/mokosuite_api/.mokogitea/auto-release.yml b/mcp/servers/mokosuite_api/.mokogit/auto-release.yml similarity index 100% rename from mcp/servers/mokosuite_api/.mokogitea/auto-release.yml rename to mcp/servers/mokosuite_api/.mokogit/auto-release.yml diff --git a/mcp/servers/mokosuite_api/.mokogitea/cascade-dev.yml b/mcp/servers/mokosuite_api/.mokogit/cascade-dev.yml similarity index 92% rename from mcp/servers/mokosuite_api/.mokogitea/cascade-dev.yml rename to mcp/servers/mokosuite_api/.mokogit/cascade-dev.yml index 52fc38f9..63ba96dd 100644 --- a/mcp/servers/mokosuite_api/.mokogitea/cascade-dev.yml +++ b/mcp/servers/mokosuite_api/.mokogit/cascade-dev.yml @@ -3,7 +3,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later # # FILE INFORMATION -# DEFGROUP: Gitea.Workflow +# DEFGROUP: MokoGit.Workflow # INGROUP: MokoCli.Maintenance # REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/MokoCli-API # PATH: /templates/workflows/cascade-dev.yml.template @@ -32,9 +32,9 @@ on: env: FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true - GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }} - GITEA_ORG: ${{ vars.GITEA_ORG || github.repository_owner }} - GITEA_REPO: ${{ vars.GITEA_REPO || github.event.repository.name }} + MOKOGIT_URL: ${{ vars.MOKOGIT_URL || 'https://git.mokoconsulting.tech' }} + MOKOGIT_ORG: ${{ vars.MOKOGIT_ORG || github.repository_owner }} + MOKOGIT_REPO: ${{ vars.MOKOGIT_REPO || github.event.repository.name }} permissions: contents: write @@ -52,9 +52,9 @@ jobs: - name: Discover target branches id: branches env: - GA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }} + GA_TOKEN: ${{ secrets.MOKOGIT_TOKEN }} run: | - API="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" + API="${MOKOGIT_URL}/api/v1/repos/${MOKOGIT_ORG}/${MOKOGIT_REPO}" # Fetch all branches (paginated) PAGE=1 @@ -93,9 +93,9 @@ jobs: - name: Cascade to all target branches if: steps.branches.outputs.targets != '' env: - GA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }} + GA_TOKEN: ${{ secrets.MOKOGIT_TOKEN }} run: | - API="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" + API="${MOKOGIT_URL}/api/v1/repos/${MOKOGIT_ORG}/${MOKOGIT_REPO}" SHORT_SHA="${GITHUB_SHA:0:7}" TARGETS="${{ steps.branches.outputs.targets }}" @@ -127,7 +127,7 @@ jobs: # Check for existing cascade PR EXISTING=$(curl -sS \ -H "Authorization: token ${GA_TOKEN}" \ - "${API}/pulls?state=open&head=${GITEA_ORG}:main&base=${ENCODED_BRANCH}&limit=1") + "${API}/pulls?state=open&head=${MOKOGIT_ORG}:main&base=${ENCODED_BRANCH}&limit=1") EXISTING_COUNT=$(echo "$EXISTING" | jq 'length') PR_NUMBER="" diff --git a/mcp/servers/mokosuite_api/.mokogitea/changelog-validation.yml b/mcp/servers/mokosuite_api/.mokogit/changelog-validation.yml similarity index 100% rename from mcp/servers/mokosuite_api/.mokogitea/changelog-validation.yml rename to mcp/servers/mokosuite_api/.mokogit/changelog-validation.yml diff --git a/mcp/servers/mokosuite_api/.mokogitea/codeql-analysis.yml b/mcp/servers/mokosuite_api/.mokogit/codeql-analysis.yml similarity index 100% rename from mcp/servers/mokosuite_api/.mokogitea/codeql-analysis.yml rename to mcp/servers/mokosuite_api/.mokogit/codeql-analysis.yml diff --git a/mcp/servers/mokosuite_api/.mokogitea/copilot-agent.yml b/mcp/servers/mokosuite_api/.mokogit/copilot-agent.yml similarity index 100% rename from mcp/servers/mokosuite_api/.mokogitea/copilot-agent.yml rename to mcp/servers/mokosuite_api/.mokogit/copilot-agent.yml diff --git a/mcp/servers/mokosuite_api/.mokogitea/deploy-demo.yml b/mcp/servers/mokosuite_api/.mokogit/deploy-demo.yml similarity index 100% rename from mcp/servers/mokosuite_api/.mokogitea/deploy-demo.yml rename to mcp/servers/mokosuite_api/.mokogit/deploy-demo.yml diff --git a/mcp/servers/mokosuite_api/.mokogitea/deploy-dev.yml b/mcp/servers/mokosuite_api/.mokogit/deploy-dev.yml similarity index 100% rename from mcp/servers/mokosuite_api/.mokogitea/deploy-dev.yml rename to mcp/servers/mokosuite_api/.mokogit/deploy-dev.yml diff --git a/mcp/servers/mokosuite_api/.mokogitea/enterprise-firewall-setup.yml b/mcp/servers/mokosuite_api/.mokogit/enterprise-firewall-setup.yml similarity index 100% rename from mcp/servers/mokosuite_api/.mokogitea/enterprise-firewall-setup.yml rename to mcp/servers/mokosuite_api/.mokogit/enterprise-firewall-setup.yml diff --git a/mcp/servers/mokomonitor/.mokogitea/workflows/gitleaks.yml b/mcp/servers/mokosuite_api/.mokogit/gitleaks.yml similarity index 97% rename from mcp/servers/mokomonitor/.mokogitea/workflows/gitleaks.yml rename to mcp/servers/mokosuite_api/.mokogit/gitleaks.yml index f95b1add..a9299a2c 100644 --- a/mcp/servers/mokomonitor/.mokogitea/workflows/gitleaks.yml +++ b/mcp/servers/mokosuite_api/.mokogit/gitleaks.yml @@ -3,7 +3,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later # # FILE INFORMATION -# DEFGROUP: Gitea.Workflow +# DEFGROUP: MokoGit.Workflow # INGROUP: MokoCli.Security # REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/MokoCli-API # PATH: /templates/workflows/gitleaks.yml.template @@ -38,7 +38,7 @@ permissions: env: NTFY_URL: ${{ vars.NTFY_URL || 'https://ntfy.mokoconsulting.tech' }} - NTFY_TOPIC: ${{ vars.NTFY_TOPIC || 'gitea-security' }} + NTFY_TOPIC: ${{ vars.NTFY_TOPIC || 'mokogit-security' }} jobs: gitleaks: diff --git a/mcp/servers/mokosuite_api/.mokogitea/manifest.xml b/mcp/servers/mokosuite_api/.mokogit/manifest.xml similarity index 100% rename from mcp/servers/mokosuite_api/.mokogitea/manifest.xml rename to mcp/servers/mokosuite_api/.mokogit/manifest.xml diff --git a/mcp/servers/mokosuite_api/.mokogitea/mcp-auto-release.yml b/mcp/servers/mokosuite_api/.mokogit/mcp-auto-release.yml similarity index 100% rename from mcp/servers/mokosuite_api/.mokogitea/mcp-auto-release.yml rename to mcp/servers/mokosuite_api/.mokogit/mcp-auto-release.yml diff --git a/mcp/servers/mokosuite_api/.mokogitea/mcp-build-test.yml b/mcp/servers/mokosuite_api/.mokogit/mcp-build-test.yml similarity index 100% rename from mcp/servers/mokosuite_api/.mokogitea/mcp-build-test.yml rename to mcp/servers/mokosuite_api/.mokogit/mcp-build-test.yml diff --git a/mcp/servers/mokosuite_api/.mokogitea/mcp-sdk-check.yml b/mcp/servers/mokosuite_api/.mokogit/mcp-sdk-check.yml similarity index 100% rename from mcp/servers/mokosuite_api/.mokogitea/mcp-sdk-check.yml rename to mcp/servers/mokosuite_api/.mokogit/mcp-sdk-check.yml diff --git a/mcp/servers/mokosuite_api/.mokogitea/mcp-tool-inventory.yml b/mcp/servers/mokosuite_api/.mokogit/mcp-tool-inventory.yml similarity index 100% rename from mcp/servers/mokosuite_api/.mokogitea/mcp-tool-inventory.yml rename to mcp/servers/mokosuite_api/.mokogit/mcp-tool-inventory.yml diff --git a/mcp/servers/mokosuite_api/.mokogitea/pr-branch-check.yml b/mcp/servers/mokosuite_api/.mokogit/pr-branch-check.yml similarity index 100% rename from mcp/servers/mokosuite_api/.mokogitea/pr-branch-check.yml rename to mcp/servers/mokosuite_api/.mokogit/pr-branch-check.yml diff --git a/mcp/servers/mokosuite_api/.mokogitea/repository-cleanup.yml b/mcp/servers/mokosuite_api/.mokogit/repository-cleanup.yml similarity index 100% rename from mcp/servers/mokosuite_api/.mokogitea/repository-cleanup.yml rename to mcp/servers/mokosuite_api/.mokogit/repository-cleanup.yml diff --git a/mcp/servers/mokosuite_api/.mokogitea/standards-compliance.yml b/mcp/servers/mokosuite_api/.mokogit/standards-compliance.yml similarity index 100% rename from mcp/servers/mokosuite_api/.mokogitea/standards-compliance.yml rename to mcp/servers/mokosuite_api/.mokogit/standards-compliance.yml diff --git a/mcp/servers/mokosuite_api/.mokogitea/sync-version-on-merge.yml b/mcp/servers/mokosuite_api/.mokogit/sync-version-on-merge.yml similarity index 100% rename from mcp/servers/mokosuite_api/.mokogitea/sync-version-on-merge.yml rename to mcp/servers/mokosuite_api/.mokogit/sync-version-on-merge.yml diff --git a/mcp/servers/mokosuite_api/.mokogitea/workflows/auto-assign.yml b/mcp/servers/mokosuite_api/.mokogit/workflows/auto-assign.yml similarity index 98% rename from mcp/servers/mokosuite_api/.mokogitea/workflows/auto-assign.yml rename to mcp/servers/mokosuite_api/.mokogit/workflows/auto-assign.yml index ab7f5737..b9008a4b 100644 --- a/mcp/servers/mokosuite_api/.mokogitea/workflows/auto-assign.yml +++ b/mcp/servers/mokosuite_api/.mokogit/workflows/auto-assign.yml @@ -5,7 +5,7 @@ # DEFGROUP: GitHub.Workflow # INGROUP: MokoCli.Workflows.Shared # REPO: https://github.com/mokoconsulting-tech/MokoCli -# PATH: /.mokogitea/workflows/auto-assign.yml +# PATH: /.mokogit/workflows/auto-assign.yml # VERSION: 04.06.00 # BRIEF: Auto-assign jmiller to unassigned issues and PRs every 15 minutes diff --git a/mcp/servers/mokosuite_api/.mokogitea/workflows/auto-dev-issue.yml b/mcp/servers/mokosuite_api/.mokogit/workflows/auto-dev-issue.yml similarity index 98% rename from mcp/servers/mokosuite_api/.mokogitea/workflows/auto-dev-issue.yml rename to mcp/servers/mokosuite_api/.mokogit/workflows/auto-dev-issue.yml index a8774aba..f48dac0b 100644 --- a/mcp/servers/mokosuite_api/.mokogitea/workflows/auto-dev-issue.yml +++ b/mcp/servers/mokosuite_api/.mokogit/workflows/auto-dev-issue.yml @@ -11,7 +11,7 @@ # PATH: /templates/workflows/shared/auto-dev-issue.yml.template # VERSION: 04.06.00 # BRIEF: Auto-create tracking issue with sub-issues for dev/rc branch workflow -# NOTE: Synced via bulk-repo-sync to .mokogitea/workflows/auto-dev-issue.yml in all governed repos. +# NOTE: Synced via bulk-repo-sync to .mokogit/workflows/auto-dev-issue.yml in all governed repos. name: "Universal: Dev/RC Branch Issue" diff --git a/mcp/servers/mokosuite_api/.mokogitea/workflows/auto-release.yml b/mcp/servers/mokosuite_api/.mokogit/workflows/auto-release.yml similarity index 82% rename from mcp/servers/mokosuite_api/.mokogitea/workflows/auto-release.yml rename to mcp/servers/mokosuite_api/.mokogit/workflows/auto-release.yml index 6ec4a310..5c68b7d1 100644 --- a/mcp/servers/mokosuite_api/.mokogitea/workflows/auto-release.yml +++ b/mcp/servers/mokosuite_api/.mokogit/workflows/auto-release.yml @@ -3,7 +3,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later # # FILE INFORMATION -# DEFGROUP: Gitea.Workflow +# DEFGROUP: MokoGit.Workflow # INGROUP: mokocli.Release # REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/mokocli # PATH: /templates/workflows/universal/auto-release.yml.template @@ -17,7 +17,7 @@ # | Reads manifest.xml (joomla|dolibarr|generic) to branch logic. | # | | # | Platform-specific: | -# | joomla: XML manifest, updates.xml, type-prefixed packages | +# | joomla: XML manifest, type-prefixed packages | # | dolibarr: mod*.class.php, update.txt, dev version reset | # | generic: README-only, no update stream | # | | @@ -37,9 +37,9 @@ on: env: FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true - GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }} - GITEA_ORG: ${{ vars.GITEA_ORG || github.repository_owner }} - GITEA_REPO: ${{ vars.GITEA_REPO || github.event.repository.name }} + MOKOGIT_URL: ${{ vars.MOKOGIT_URL || 'https://git.mokoconsulting.tech' }} + MOKOGIT_ORG: ${{ vars.MOKOGIT_ORG || github.repository_owner }} + MOKOGIT_REPO: ${{ vars.MOKOGIT_REPO || github.event.repository.name }} permissions: contents: write @@ -55,12 +55,12 @@ jobs: - name: Checkout repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: - token: ${{ secrets.MOKOGITEA_TOKEN }} + token: ${{ secrets.MOKOGIT_TOKEN }} fetch-depth: 0 - name: Setup mokocli tools env: - MOKO_CLONE_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }} + MOKO_CLONE_TOKEN: ${{ secrets.MOKOGIT_TOKEN }} MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GH_PAT }}"}}' run: | @@ -263,17 +263,6 @@ jobs: VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" php /tmp/mokocli-api/cli/badge_update.php --path . --version "${VERSION}" 2>/dev/null || true - - name: "Step 5: Write update stream" - if: >- - steps.version.outputs.skip != 'true' && - steps.platform.outputs.platform == 'joomla' - run: | - VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" - php /tmp/mokocli-api/cli/updates_xml_build.php \ - --path . --version "${VERSION}" --stability stable \ - --gitea-url "${GITEA_URL}" --org "${GITEA_ORG}" --repo "${GITEA_REPO}" \ - --github-output - - name: Commit release changes if: >- steps.version.outputs.skip != 'true' && @@ -284,13 +273,13 @@ jobs: exit 0 fi VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" - git config --local user.email "gitea-actions[bot]@mokoconsulting.tech" - git config --local user.name "gitea-actions[bot]" + git config --local user.email "mokogit-actions[bot]@mokoconsulting.tech" + git config --local user.name "mokogit-actions[bot]" # Set push URL with token for branch-protected repos - git remote set-url origin "https://jmiller:${{ secrets.MOKOGITEA_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git" + git remote set-url origin "https://jmiller:${{ secrets.MOKOGIT_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git" git add -A git commit -m "chore(release): build ${VERSION} [skip ci]" \ - --author="gitea-actions[bot] " + --author="mokogit-actions[bot] " git push -u origin HEAD # -- STEP 6: Create tag --------------------------------------------------- @@ -311,8 +300,8 @@ jobs: fi echo "Tag: ${TAG}" >> $GITHUB_STEP_SUMMARY - # -- STEP 7: Create or update Gitea Release -------------------------------- - - name: "Step 7: Gitea Release" + # -- STEP 7: Create or update MokoGit Release -------------------------------- + - name: "Step 7: MokoGit Release" if: >- steps.version.outputs.skip != 'true' run: | @@ -320,7 +309,7 @@ jobs: RELEASE_TAG="${{ steps.version.outputs.release_tag }}" BRANCH="${{ steps.version.outputs.branch }}" MAJOR="${{ steps.version.outputs.major }}" - API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" + API_BASE="${MOKOGIT_URL}/api/v1/repos/${MOKOGIT_ORG}/${MOKOGIT_REPO}" # Reuse metadata from Step 5 (single source of truth) EXT_ELEMENT="${{ steps.updates.outputs.ext_element }}" @@ -330,9 +319,9 @@ jobs: # Fallbacks if Step 5 was skipped if [ -z "$EXT_ELEMENT" ]; then - EXT_ELEMENT=$(echo "${GITEA_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -') + EXT_ELEMENT=$(echo "${MOKOGIT_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -') fi - [ -z "$EXT_NAME" ] && EXT_NAME="${GITEA_REPO}" + [ -z "$EXT_NAME" ] && EXT_NAME="${MOKOGIT_REPO}" NOTES=$(php /tmp/mokocli-api/cli/release_notes.php --path . --version "$VERSION" 2>/dev/null) [ -z "$NOTES" ] && NOTES="Release ${VERSION}" @@ -350,20 +339,20 @@ jobs: RELEASE_NAME="${EXT_NAME} ${VERSION} (${TYPE_PREFIX}${EXT_ELEMENT}-${VERSION})" # Delete existing release if present (overwrite, not append) - EXISTING=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \ + EXISTING=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGIT_TOKEN }}" \ "${API_BASE}/releases/tags/${RELEASE_TAG}" 2>/dev/null || true) EXISTING_ID=$(echo "$EXISTING" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('id',''))" 2>/dev/null || true) if [ -n "$EXISTING_ID" ]; then - curl -sS -X DELETE -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \ + curl -sS -X DELETE -H "Authorization: token ${{ secrets.MOKOGIT_TOKEN }}" \ "${API_BASE}/releases/${EXISTING_ID}" 2>/dev/null || true - curl -sS -X DELETE -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \ + curl -sS -X DELETE -H "Authorization: token ${{ secrets.MOKOGIT_TOKEN }}" \ "${API_BASE}/tags/${RELEASE_TAG}" 2>/dev/null || true echo "Deleted previous stable release (id: ${EXISTING_ID})" fi # Create fresh release - curl -sf -X POST -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \ + curl -sf -X POST -H "Authorization: token ${{ secrets.MOKOGIT_TOKEN }}" \ -H "Content-Type: application/json" \ "${API_BASE}/releases" \ -d "$(python3 -c "import json; print(json.dumps({ @@ -382,10 +371,10 @@ jobs: VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" RELEASE_TAG="${{ steps.version.outputs.release_tag }}" REPO="${{ github.repository }}" - API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" + API_BASE="${MOKOGIT_URL}/api/v1/repos/${MOKOGIT_ORG}/${MOKOGIT_REPO}" # All ZIPs upload to the major release tag (vXX) - RELEASE_JSON=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \ + RELEASE_JSON=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGIT_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 @@ -403,7 +392,7 @@ jobs: EXT_ELEMENT=$(sed -n 's/.*\([^<]*\)<\/element>.*/\1/p' "$MANIFEST" 2>/dev/null | head -1) [ -z "$EXT_ELEMENT" ] && EXT_ELEMENT=$(sed -n 's/.*plugin="\([^"]*\)".*/\1/p' "$MANIFEST" 2>/dev/null | head -1) [ -z "$EXT_ELEMENT" ] && EXT_ELEMENT=$(basename "$MANIFEST" .xml | tr '[:upper:]' '[:lower:]') - [ -z "$EXT_ELEMENT" ] && EXT_ELEMENT=$(echo "${GITEA_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -') + [ -z "$EXT_ELEMENT" ] && EXT_ELEMENT=$(echo "${MOKOGIT_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -') fi # ZIP name: type_folder_element-VERSION (e.g. plg_system_mokojgdpc-01.01.00.zip) EXT_TYPE=$(sed -n 's/.*]*type="\([^"]*\)".*/\1/p' "$MANIFEST" | head -1) @@ -444,7 +433,7 @@ jobs: SHA256_TAR=$(sha256sum "/tmp/${TAR_NAME}" | cut -d' ' -f1) # -- Delete existing assets with same name before uploading ------ - ASSETS=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \ + ASSETS=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGIT_TOKEN }}" \ "${API_BASE}/releases/${RELEASE_ID}/assets" 2>/dev/null || echo "[]") for ASSET_NAME in "$ZIP_NAME" "$TAR_NAME"; do ASSET_ID=$(echo "$ASSETS" | python3 -c " @@ -455,99 +444,22 @@ jobs: print(a['id']); break " 2>/dev/null || true) if [ -n "$ASSET_ID" ]; then - curl -sf -X DELETE -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \ + curl -sf -X DELETE -H "Authorization: token ${{ secrets.MOKOGIT_TOKEN }}" \ "${API_BASE}/releases/${RELEASE_ID}/assets/${ASSET_ID}" 2>/dev/null || true fi done # -- Upload both to release tag ---------------------------------- - curl -sf -X POST -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \ + curl -sf -X POST -H "Authorization: token ${{ secrets.MOKOGIT_TOKEN }}" \ -H "Content-Type: application/octet-stream" \ --data-binary @"/tmp/${ZIP_NAME}" \ "${API_BASE}/releases/${RELEASE_ID}/assets?name=${ZIP_NAME}" > /dev/null 2>&1 || true - curl -sf -X POST -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \ + curl -sf -X POST -H "Authorization: token ${{ secrets.MOKOGIT_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 - # -- Update updates.xml with both download formats --------------- - if [ -f "updates.xml" ]; then - ZIP_URL="${GITEA_URL}/${GITEA_ORG}/${GITEA_REPO}/releases/download/${RELEASE_TAG}/${ZIP_NAME}" - TAR_URL="${GITEA_URL}/${GITEA_ORG}/${GITEA_REPO}/releases/download/${RELEASE_TAG}/${TAR_NAME}" - - # Use Python to update only the stable entry's downloads + sha256 - export PY_ZIP_URL="$ZIP_URL" PY_TAR_URL="$TAR_URL" PY_SHA="$SHA256_ZIP" - python3 << 'PYEOF' - import re, os - - with open("updates.xml") as f: - content = f.read() - - zip_url = os.environ["PY_ZIP_URL"] - tar_url = os.environ["PY_TAR_URL"] - sha = os.environ["PY_SHA"] - - # Find the stable update block and replace its downloads + sha256 - def replace_stable(m): - block = m.group(0) - # Replace downloads block - new_downloads = ( - " \n" - f" {zip_url}\n" - " " - ) - block = re.sub(r' .*?', new_downloads, block, flags=re.DOTALL) - # Add or replace sha256 - if '' in block: - block = re.sub(r' .*?', f' {sha}', block) - else: - block = block.replace('', f'\n {sha}') - return block - - content = re.sub( - r' .*?stable.*?', - replace_stable, - content, - flags=re.DOTALL - ) - - with open("updates.xml", "w") as f: - f.write(content) - PYEOF - - CURRENT_BRANCH="${{ github.ref_name }}" - git add updates.xml - git commit -m "chore(release): ZIP + tar.gz for ${VERSION} [skip ci]" \ - --author="gitea-actions[bot] " || true - git push || true - - # Sync updates.xml to main via direct API (always runs — may be on version/XX branch) - GA_TOKEN="${{ secrets.MOKOGITEA_TOKEN }}" - API="${GITEA_URL:-https://git.mokoconsulting.tech}/api/v1/repos/${{ github.repository }}" - - FILE_SHA=$(curl -sf -H "Authorization: token ${GA_TOKEN}" \ - "${API}/contents/updates.xml?ref=main" | jq -r '.sha // empty') - - if [ -n "$FILE_SHA" ]; then - CONTENT=$(base64 -w0 updates.xml) - curl -sf -X PUT -H "Authorization: token ${GA_TOKEN}" \ - -H "Content-Type: application/json" \ - "${API}/contents/updates.xml" \ - -d "$(jq -n \ - --arg content "$CONTENT" \ - --arg sha "$FILE_SHA" \ - --arg msg "chore: sync updates.xml ${VERSION} [skip ci]" \ - --arg branch "main" \ - '{content: $content, sha: $sha, message: $msg, branch: $branch}' - )" > /dev/null 2>&1 \ - && echo "updates.xml synced to main via API" \ - || echo "WARNING: failed to sync updates.xml to main" - else - echo "WARNING: could not get updates.xml SHA from main" - fi - fi - echo "### Packages" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "| Package | Size | SHA-256 |" >> $GITHUB_STEP_SUMMARY @@ -555,7 +467,7 @@ jobs: echo "| \`${ZIP_NAME}\` | ${ZIP_SIZE} | \`${SHA256_ZIP}\` |" >> $GITHUB_STEP_SUMMARY echo "| \`${TAR_NAME}\` | ${TAR_SIZE} | \`${SHA256_TAR}\` |" >> $GITHUB_STEP_SUMMARY echo "| Release | \`${RELEASE_TAG}\` | |" >> $GITHUB_STEP_SUMMARY - echo "| Download | [${ZIP_NAME}](${GITEA_URL}/${GITEA_ORG}/${GITEA_REPO}/releases/download/${RELEASE_TAG}/${ZIP_NAME}) |" >> $GITHUB_STEP_SUMMARY + echo "| Download | [${ZIP_NAME}](${MOKOGIT_URL}/${MOKOGIT_ORG}/${MOKOGIT_REPO}/releases/download/${RELEASE_TAG}/${ZIP_NAME}) |" >> $GITHUB_STEP_SUMMARY # -- STEP 8b: Update release description with changelog + SHA ---------------- - name: "Step 8b: Update release body with changelog and SHA" @@ -563,7 +475,7 @@ jobs: run: | VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" RELEASE_TAG="${{ steps.version.outputs.release_tag }}" - API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" + API_BASE="${MOKOGIT_URL}/api/v1/repos/${MOKOGIT_ORG}/${MOKOGIT_REPO}" EXT_ELEMENT="${{ steps.updates.outputs.ext_element }}" EXT_TYPE="${{ steps.updates.outputs.ext_type }}" EXT_FOLDER="${{ steps.updates.outputs.ext_folder }}" @@ -605,7 +517,7 @@ jobs: [ -n "$SHA256_TAR" ] && BODY="${BODY}| \`${TAR_NAME}\` | \`${SHA256_TAR}\` |\n" # Get release ID and update body - RELEASE_ID=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \ + RELEASE_ID=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGIT_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) @@ -617,7 +529,7 @@ jobs: req = urllib.request.Request( '${API_BASE}/releases/${RELEASE_ID}', data=data, - headers={'Authorization': 'token ${{ secrets.MOKOGITEA_TOKEN }}', 'Content-Type': 'application/json'}, + headers={'Authorization': 'token ${{ secrets.MOKOGIT_TOKEN }}', 'Content-Type': 'application/json'}, method='PATCH' ) urllib.request.urlopen(req) @@ -644,7 +556,7 @@ jobs: [ -z "$NOTES" ] && NOTES="Release ${VERSION}" echo "$NOTES" > /tmp/release_notes.md - EXISTING=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" "${GITEA_URL:-https://git.mokoconsulting.tech}/api/v1/repos/${{ github.repository }}/releases/tags/$RELEASE_TAG" 2>/dev/null | jq -r ".tag_name // empty" || true) + EXISTING=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGIT_TOKEN }}" "${MOKOGIT_URL:-https://git.mokoconsulting.tech}/api/v1/repos/${{ github.repository }}/releases/tags/$RELEASE_TAG" 2>/dev/null | jq -r ".tag_name // empty" || true) if [ -z "$EXISTING" ]; then gh release create "$RELEASE_TAG" \ @@ -661,8 +573,8 @@ jobs: # Upload assets to GitHub mirror for PKG in /tmp/${EXT_ELEMENT:-pkg}-${VERSION}.*; do if [ -f "$PKG" ]; then - _RELID=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" "${GITEA_URL:-https://git.mokoconsulting.tech}/api/v1/repos/${{ github.repository }}/releases/tags/$RELEASE_TAG" 2>/dev/null | jq -r ".id // empty") - [ -n "$_RELID" ] && curl -sf -X POST -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" -H "Content-Type: application/octet-stream" "${GITEA_URL:-https://git.mokoconsulting.tech}/api/v1/repos/${{ github.repository }}/releases/${_RELID}/assets?name=$(basename $PKG)" --data-binary "@$PKG" > /dev/null 2>&1 || true + _RELID=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGIT_TOKEN }}" "${MOKOGIT_URL:-https://git.mokoconsulting.tech}/api/v1/repos/${{ github.repository }}/releases/tags/$RELEASE_TAG" 2>/dev/null | jq -r ".id // empty") + [ -n "$_RELID" ] && curl -sf -X POST -H "Authorization: token ${{ secrets.MOKOGIT_TOKEN }}" -H "Content-Type: application/octet-stream" "${MOKOGIT_URL:-https://git.mokoconsulting.tech}/api/v1/repos/${{ github.repository }}/releases/${_RELID}/assets?name=$(basename $PKG)" --data-binary "@$PKG" > /dev/null 2>&1 || true fi done echo "GitHub mirror updated: ${GH_REPO} ${RELEASE_TAG}" >> $GITHUB_STEP_SUMMARY @@ -691,16 +603,16 @@ jobs: run: | php /tmp/mokocli-api/cli/release_cascade.php \ --stability stable \ - --token "${{ secrets.MOKOGITEA_TOKEN }}" \ - --org "${GITEA_ORG}" --repo "${GITEA_REPO}" \ - --gitea-url "${GITEA_URL}" 2>/dev/null || true + --token "${{ secrets.MOKOGIT_TOKEN }}" \ + --org "${MOKOGIT_ORG}" --repo "${MOKOGIT_REPO}" \ + --mokogit-url "${MOKOGIT_URL}" 2>/dev/null || true - name: "Step 11: Delete and recreate dev 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 }}" + API_BASE="${MOKOGIT_URL}/api/v1/repos/${MOKOGIT_ORG}/${MOKOGIT_REPO}" + TOKEN="${{ secrets.MOKOGIT_TOKEN }}" # Delete dev branch curl -sf -X DELETE -H "Authorization: token ${TOKEN}" \ @@ -723,8 +635,8 @@ jobs: steps.platform.outputs.mod_file != '' continue-on-error: true run: | - API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" - TOKEN="${{ secrets.MOKOGITEA_TOKEN }}" + API_BASE="${MOKOGIT_URL}/api/v1/repos/${MOKOGIT_ORG}/${MOKOGIT_REPO}" + TOKEN="${{ secrets.MOKOGIT_TOKEN }}" MOD_FILE="${{ steps.platform.outputs.mod_file }}" ENCODED_PATH=$(echo "$MOD_FILE" | sed 's|^\./||' | python3 -c "import sys,urllib.parse; print(urllib.parse.quote(sys.stdin.read().strip()))") FILE_RESP=$(curl -sf -H "Authorization: token ${TOKEN}" "${API_BASE}/contents/${ENCODED_PATH}?ref=dev" 2>/dev/null || true) @@ -758,5 +670,5 @@ jobs: echo "| Version | \`${VERSION}\` |" >> $GITHUB_STEP_SUMMARY echo "| Branch | \`${{ steps.version.outputs.branch }}\` |" >> $GITHUB_STEP_SUMMARY echo "| Tag | \`${{ steps.version.outputs.tag }}\` |" >> $GITHUB_STEP_SUMMARY - echo "| Release | [View](${GITEA_URL}/${GITEA_ORG}/${GITEA_REPO}/releases/tag/${{ steps.version.outputs.tag }}) |" >> $GITHUB_STEP_SUMMARY + echo "| Release | [View](${MOKOGIT_URL}/${MOKOGIT_ORG}/${MOKOGIT_REPO}/releases/tag/${{ steps.version.outputs.tag }}) |" >> $GITHUB_STEP_SUMMARY fi diff --git a/mcp/servers/mokossh/.mokogitea/workflows/cascade-dev.yml b/mcp/servers/mokosuite_api/.mokogit/workflows/cascade-dev.yml similarity index 92% rename from mcp/servers/mokossh/.mokogitea/workflows/cascade-dev.yml rename to mcp/servers/mokosuite_api/.mokogit/workflows/cascade-dev.yml index e47d4262..5160ef52 100644 --- a/mcp/servers/mokossh/.mokogitea/workflows/cascade-dev.yml +++ b/mcp/servers/mokosuite_api/.mokogit/workflows/cascade-dev.yml @@ -3,7 +3,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later # # FILE INFORMATION -# DEFGROUP: Gitea.Workflow +# DEFGROUP: MokoGit.Workflow # INGROUP: mokocli.Maintenance # REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/mokocli # PATH: /templates/workflows/cascade-dev.yml.template @@ -32,9 +32,9 @@ on: env: FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true - GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }} - GITEA_ORG: ${{ vars.GITEA_ORG || github.repository_owner }} - GITEA_REPO: ${{ vars.GITEA_REPO || github.event.repository.name }} + MOKOGIT_URL: ${{ vars.MOKOGIT_URL || 'https://git.mokoconsulting.tech' }} + MOKOGIT_ORG: ${{ vars.MOKOGIT_ORG || github.repository_owner }} + MOKOGIT_REPO: ${{ vars.MOKOGIT_REPO || github.event.repository.name }} permissions: contents: write @@ -52,9 +52,9 @@ jobs: - name: Discover target branches id: branches env: - GA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }} + GA_TOKEN: ${{ secrets.MOKOGIT_TOKEN }} run: | - API="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" + API="${MOKOGIT_URL}/api/v1/repos/${MOKOGIT_ORG}/${MOKOGIT_REPO}" # Fetch all branches (paginated) PAGE=1 @@ -93,9 +93,9 @@ jobs: - name: Cascade to all target branches if: steps.branches.outputs.targets != '' env: - GA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }} + GA_TOKEN: ${{ secrets.MOKOGIT_TOKEN }} run: | - API="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" + API="${MOKOGIT_URL}/api/v1/repos/${MOKOGIT_ORG}/${MOKOGIT_REPO}" SHORT_SHA="${GITHUB_SHA:0:7}" TARGETS="${{ steps.branches.outputs.targets }}" @@ -127,7 +127,7 @@ jobs: # Check for existing cascade PR EXISTING=$(curl -sS \ -H "Authorization: token ${GA_TOKEN}" \ - "${API}/pulls?state=open&head=${GITEA_ORG}:main&base=${ENCODED_BRANCH}&limit=1") + "${API}/pulls?state=open&head=${MOKOGIT_ORG}:main&base=${ENCODED_BRANCH}&limit=1") EXISTING_COUNT=$(echo "$EXISTING" | jq 'length') PR_NUMBER="" diff --git a/mcp/servers/mokosuite_api/.mokogitea/workflows/changelog-validation.yml b/mcp/servers/mokosuite_api/.mokogit/workflows/changelog-validation.yml similarity index 97% rename from mcp/servers/mokosuite_api/.mokogitea/workflows/changelog-validation.yml rename to mcp/servers/mokosuite_api/.mokogit/workflows/changelog-validation.yml index f104937c..3bf54b28 100644 --- a/mcp/servers/mokosuite_api/.mokogitea/workflows/changelog-validation.yml +++ b/mcp/servers/mokosuite_api/.mokogit/workflows/changelog-validation.yml @@ -11,7 +11,7 @@ # PATH: /templates/workflows/shared/changelog-validation.yml.template # VERSION: 04.06.00 # BRIEF: Validates CHANGELOG.md format and version consistency -# NOTE: Deployed to .mokogitea/workflows/changelog-validation.yml in governed repos. +# NOTE: Deployed to .mokogit/workflows/changelog-validation.yml in governed repos. name: "Universal: Changelog Validation" diff --git a/mcp/servers/mokossh/.mokogitea/workflows/cleanup.yml b/mcp/servers/mokosuite_api/.mokogit/workflows/cleanup.yml similarity index 84% rename from mcp/servers/mokossh/.mokogitea/workflows/cleanup.yml rename to mcp/servers/mokosuite_api/.mokogit/workflows/cleanup.yml index 85206066..0b941f23 100644 --- a/mcp/servers/mokossh/.mokogitea/workflows/cleanup.yml +++ b/mcp/servers/mokosuite_api/.mokogit/workflows/cleanup.yml @@ -3,10 +3,10 @@ # SPDX-License-Identifier: GPL-3.0-or-later # # FILE INFORMATION -# DEFGROUP: Gitea.Workflow +# DEFGROUP: MokoGit.Workflow # INGROUP: mokocli.Maintenance # REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli -# PATH: /.gitea/workflows/cleanup.yml +# PATH: /.mokogit/workflows/cleanup.yml # VERSION: 01.00.00 # BRIEF: Scheduled cleanup — delete merged branches and old workflow runs @@ -21,7 +21,7 @@ permissions: contents: write env: - GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }} + MOKOGIT_URL: ${{ vars.MOKOGIT_URL || 'https://git.mokoconsulting.tech' }} jobs: cleanup: @@ -33,14 +33,14 @@ jobs: uses: actions/checkout@v4 with: fetch-depth: 0 - token: ${{ secrets.MOKOGITEA_TOKEN }} + token: ${{ secrets.MOKOGIT_TOKEN }} - name: Delete merged branches env: - GA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }} + GA_TOKEN: ${{ secrets.MOKOGIT_TOKEN }} run: | echo "=== Merged Branch Cleanup ===" - API="${GITEA_URL}/api/v1/repos/${{ github.repository }}" + API="${MOKOGIT_URL}/api/v1/repos/${{ github.repository }}" # List branches via API BRANCHES=$(curl -sS -H "Authorization: token ${GA_TOKEN}" \ @@ -66,10 +66,10 @@ jobs: - name: Clean old workflow runs env: - GA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }} + GA_TOKEN: ${{ secrets.MOKOGIT_TOKEN }} run: | echo "=== Workflow Run Cleanup ===" - API="${GITEA_URL}/api/v1/repos/${{ github.repository }}" + API="${MOKOGIT_URL}/api/v1/repos/${{ github.repository }}" CUTOFF=$(date -d "30 days ago" +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -v-30d +%Y-%m-%dT%H:%M:%SZ) # Get old completed runs diff --git a/mcp/servers/mokossh/.mokogitea/workflows/codeql-analysis.yml b/mcp/servers/mokosuite_api/.mokogit/workflows/codeql-analysis.yml similarity index 97% rename from mcp/servers/mokossh/.mokogitea/workflows/codeql-analysis.yml rename to mcp/servers/mokosuite_api/.mokogit/workflows/codeql-analysis.yml index 0e4c7353..ed9de887 100644 --- a/mcp/servers/mokossh/.mokogitea/workflows/codeql-analysis.yml +++ b/mcp/servers/mokosuite_api/.mokogit/workflows/codeql-analysis.yml @@ -11,7 +11,7 @@ # PATH: /templates/workflows/generic/codeql-analysis.yml.template # VERSION: 04.05.00 # BRIEF: CodeQL security scanning workflow (generic — all repo types) -# NOTE: Deployed to .mokogitea/workflows/codeql-analysis.yml in governed repos. +# NOTE: Deployed to .mokogit/workflows/codeql-analysis.yml in governed repos. # CodeQL does not support PHP directly; JavaScript scans JSON/YAML/shell. # For PHP-specific security scanning see standards-compliance.yml. diff --git a/mcp/servers/mokosuite_api/.mokogitea/workflows/copilot-agent.yml b/mcp/servers/mokosuite_api/.mokogit/workflows/copilot-agent.yml similarity index 100% rename from mcp/servers/mokosuite_api/.mokogitea/workflows/copilot-agent.yml rename to mcp/servers/mokosuite_api/.mokogit/workflows/copilot-agent.yml diff --git a/mcp/servers/mokossh/.mokogitea/workflows/deploy-manual.yml b/mcp/servers/mokosuite_api/.mokogit/workflows/deploy-manual.yml similarity index 92% rename from mcp/servers/mokossh/.mokogitea/workflows/deploy-manual.yml rename to mcp/servers/mokosuite_api/.mokogit/workflows/deploy-manual.yml index 4ebd21eb..f49bf444 100644 --- a/mcp/servers/mokossh/.mokogitea/workflows/deploy-manual.yml +++ b/mcp/servers/mokosuite_api/.mokogit/workflows/deploy-manual.yml @@ -3,7 +3,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later # # FILE INFORMATION -# DEFGROUP: Gitea.Workflow +# DEFGROUP: MokoGit.Workflow # INGROUP: mokocli.Deploy # REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli # PATH: /templates/workflows/joomla/deploy-manual.yml.template @@ -42,10 +42,10 @@ jobs: - name: Setup mokocli tools env: - GA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN || secrets.MOKOGITEA_TOKEN || github.token }} - MOKO_CLONE_TOKEN: ${{ secrets.MOKOGITEA_TOKEN || secrets.MOKOGITEA_TOKEN || github.token }} - MOKO_CLONE_HOST: ${{ secrets.MOKOGITEA_TOKEN && 'git.mokoconsulting.tech/MokoConsulting' || 'github.com/mokoconsulting-tech' }} - COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.MOKOGITEA_TOKEN || github.token }}"}}' + GA_TOKEN: ${{ secrets.MOKOGIT_TOKEN || secrets.MOKOGIT_TOKEN || github.token }} + MOKO_CLONE_TOKEN: ${{ secrets.MOKOGIT_TOKEN || secrets.MOKOGIT_TOKEN || github.token }} + MOKO_CLONE_HOST: ${{ secrets.MOKOGIT_TOKEN && 'git.mokoconsulting.tech/MokoConsulting' || 'github.com/mokoconsulting-tech' }} + COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.MOKOGIT_TOKEN || github.token }}"}}' run: | git clone --depth 1 --branch main --quiet \ "https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/mokocli.git" \ diff --git a/mcp/servers/mokosuite_api/.mokogitea/workflows/enterprise-firewall-setup.yml b/mcp/servers/mokosuite_api/.mokogit/workflows/enterprise-firewall-setup.yml similarity index 100% rename from mcp/servers/mokosuite_api/.mokogitea/workflows/enterprise-firewall-setup.yml rename to mcp/servers/mokosuite_api/.mokogit/workflows/enterprise-firewall-setup.yml diff --git a/mcp/servers/mokossh/.mokogitea/workflows/gitleaks.yml b/mcp/servers/mokosuite_api/.mokogit/workflows/gitleaks.yml similarity index 97% rename from mcp/servers/mokossh/.mokogitea/workflows/gitleaks.yml rename to mcp/servers/mokosuite_api/.mokogit/workflows/gitleaks.yml index 9739b1f4..7ed6d0b6 100644 --- a/mcp/servers/mokossh/.mokogitea/workflows/gitleaks.yml +++ b/mcp/servers/mokosuite_api/.mokogit/workflows/gitleaks.yml @@ -3,7 +3,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later # # FILE INFORMATION -# DEFGROUP: Gitea.Workflow +# DEFGROUP: MokoGit.Workflow # INGROUP: mokocli.Security # REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/mokocli # PATH: /templates/workflows/gitleaks.yml.template @@ -38,7 +38,7 @@ permissions: env: NTFY_URL: ${{ vars.NTFY_URL || 'https://ntfy.mokoconsulting.tech' }} - NTFY_TOPIC: ${{ vars.NTFY_TOPIC || 'gitea-security' }} + NTFY_TOPIC: ${{ vars.NTFY_TOPIC || 'mokogit-security' }} jobs: gitleaks: diff --git a/mcp/servers/mokosuite_api/.mokogitea/workflows/mcp-auto-release.yml b/mcp/servers/mokosuite_api/.mokogit/workflows/mcp-auto-release.yml similarity index 100% rename from mcp/servers/mokosuite_api/.mokogitea/workflows/mcp-auto-release.yml rename to mcp/servers/mokosuite_api/.mokogit/workflows/mcp-auto-release.yml diff --git a/mcp/servers/mokosuite_api/.mokogitea/workflows/mcp-build-test.yml b/mcp/servers/mokosuite_api/.mokogit/workflows/mcp-build-test.yml similarity index 100% rename from mcp/servers/mokosuite_api/.mokogitea/workflows/mcp-build-test.yml rename to mcp/servers/mokosuite_api/.mokogit/workflows/mcp-build-test.yml diff --git a/mcp/servers/mokosuite_api/.mokogitea/workflows/mcp-sdk-check.yml b/mcp/servers/mokosuite_api/.mokogit/workflows/mcp-sdk-check.yml similarity index 100% rename from mcp/servers/mokosuite_api/.mokogitea/workflows/mcp-sdk-check.yml rename to mcp/servers/mokosuite_api/.mokogit/workflows/mcp-sdk-check.yml diff --git a/mcp/servers/mokosuite_api/.mokogitea/workflows/mcp-tool-inventory.yml b/mcp/servers/mokosuite_api/.mokogit/workflows/mcp-tool-inventory.yml similarity index 100% rename from mcp/servers/mokosuite_api/.mokogitea/workflows/mcp-tool-inventory.yml rename to mcp/servers/mokosuite_api/.mokogit/workflows/mcp-tool-inventory.yml diff --git a/mcp/servers/mokossh/.mokogitea/workflows/notify.yml b/mcp/servers/mokosuite_api/.mokogit/workflows/notify.yml similarity index 94% rename from mcp/servers/mokossh/.mokogitea/workflows/notify.yml rename to mcp/servers/mokosuite_api/.mokogit/workflows/notify.yml index 0e3ad8ec..d69d4021 100644 --- a/mcp/servers/mokossh/.mokogitea/workflows/notify.yml +++ b/mcp/servers/mokosuite_api/.mokogit/workflows/notify.yml @@ -3,10 +3,10 @@ # SPDX-License-Identifier: GPL-3.0-or-later # # FILE INFORMATION -# DEFGROUP: Gitea.Workflow +# DEFGROUP: MokoGit.Workflow # INGROUP: mokocli.Notifications # REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli -# PATH: /.gitea/workflows/notify.yml +# PATH: /.mokogit/workflows/notify.yml # VERSION: 01.00.00 # BRIEF: Push notifications via ntfy on release success or workflow failure @@ -26,7 +26,7 @@ permissions: env: NTFY_URL: ${{ vars.NTFY_URL || 'https://ntfy.mokoconsulting.tech' }} - NTFY_TOPIC: ${{ vars.NTFY_TOPIC || 'gitea-releases' }} + NTFY_TOPIC: ${{ vars.NTFY_TOPIC || 'mokogit-releases' }} jobs: notify: diff --git a/mcp/servers/mokosuite_api/.mokogitea/workflows/pr-check.yml b/mcp/servers/mokosuite_api/.mokogit/workflows/pr-check.yml similarity index 87% rename from mcp/servers/mokosuite_api/.mokogitea/workflows/pr-check.yml rename to mcp/servers/mokosuite_api/.mokogit/workflows/pr-check.yml index 1163ccda..0c13f70f 100644 --- a/mcp/servers/mokosuite_api/.mokogitea/workflows/pr-check.yml +++ b/mcp/servers/mokosuite_api/.mokogit/workflows/pr-check.yml @@ -3,7 +3,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later # # FILE INFORMATION -# DEFGROUP: Gitea.Workflow +# DEFGROUP: MokoGit.Workflow # INGROUP: mokocli.CI # REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/mokocli # PATH: /templates/workflows/universal/pr-check.yml.template @@ -109,8 +109,8 @@ jobs: id: platform run: | # Read platform from XML manifest ( tag) or plain text fallback - PLATFORM=$(sed -n 's/.*\([^<]*\)<\/platform>.*/\1/p' .mokogitea/manifest.xml 2>/dev/null | head -1) - [ -z "$PLATFORM" ] && PLATFORM=$(cat .mokogitea/manifest.xml 2>/dev/null | tr -d '[:space:]') + PLATFORM=$(sed -n 's/.*\([^<]*\)<\/platform>.*/\1/p' .mokogit/manifest.xml 2>/dev/null | head -1) + [ -z "$PLATFORM" ] && PLATFORM=$(cat .mokogit/manifest.xml 2>/dev/null | tr -d '[:space:]') [ -z "$PLATFORM" ] && PLATFORM="generic" echo "platform=$PLATFORM" >> "$GITHUB_OUTPUT" @@ -166,23 +166,6 @@ jobs: ;; esac - - name: Check update stream format - run: | - PLATFORM="${{ steps.platform.outputs.platform }}" - case "$PLATFORM" in - joomla) - if [ -f "updates.xml" ]; then - if command -v php &> /dev/null; then - php -r "libxml_use_internal_errors(true); \$x = simplexml_load_file('updates.xml'); if(!\$x){foreach(libxml_get_errors() as \$e) echo \$e->message; exit(1);}" || { echo "::error::updates.xml is malformed"; exit 1; } - fi - echo "updates.xml valid" - fi - ;; - dolibarr) - [ -f "update.txt" ] && echo "update.txt present" || echo "::warning::No update.txt" - ;; - esac - - name: Verify package source run: | SOURCE_DIR="src" diff --git a/mcp/servers/mokossh/.mokogitea/workflows/pre-release.yml b/mcp/servers/mokosuite_api/.mokogit/workflows/pre-release.yml similarity index 78% rename from mcp/servers/mokossh/.mokogitea/workflows/pre-release.yml rename to mcp/servers/mokosuite_api/.mokogit/workflows/pre-release.yml index 257763cb..a598ceb2 100644 --- a/mcp/servers/mokossh/.mokogitea/workflows/pre-release.yml +++ b/mcp/servers/mokosuite_api/.mokogit/workflows/pre-release.yml @@ -3,7 +3,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later # # FILE INFORMATION -# DEFGROUP: Gitea.Workflow +# DEFGROUP: MokoGit.Workflow # INGROUP: mokocli.Release # REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli # PATH: /templates/workflows/universal/pre-release.yml.template @@ -29,9 +29,9 @@ permissions: contents: write env: - GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }} - GITEA_ORG: ${{ vars.GITEA_ORG || github.repository_owner }} - GITEA_REPO: ${{ vars.GITEA_REPO || github.event.repository.name }} + MOKOGIT_URL: ${{ vars.MOKOGIT_URL || 'https://git.mokoconsulting.tech' }} + MOKOGIT_ORG: ${{ vars.MOKOGIT_ORG || github.repository_owner }} + MOKOGIT_REPO: ${{ vars.MOKOGIT_REPO || github.event.repository.name }} jobs: build: @@ -43,7 +43,7 @@ jobs: uses: actions/checkout@v4 with: fetch-depth: 0 - token: ${{ secrets.MOKOGITEA_TOKEN }} + token: ${{ secrets.MOKOGIT_TOKEN }} - name: Setup PHP run: | @@ -54,7 +54,7 @@ jobs: - name: Setup mokocli tools env: - MOKO_CLONE_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }} + MOKO_CLONE_TOKEN: ${{ secrets.MOKOGIT_TOKEN }} MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting run: | git clone --depth 1 --branch main --quiet "https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/mokocli.git" /tmp/mokocli-api @@ -87,9 +87,9 @@ jobs: php ${MOKO_API}/version_set_platform.php --path . --version "${VERSION}" # Commit version bump - git config --local user.email "gitea-actions[bot]@mokoconsulting.tech" - git config --local user.name "gitea-actions[bot]" - git remote set-url origin "https://jmiller:${{ secrets.MOKOGITEA_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git" + git config --local user.email "mokogit-actions[bot]@mokoconsulting.tech" + git config --local user.name "mokogit-actions[bot]" + git remote set-url origin "https://jmiller:${{ secrets.MOKOGIT_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git" git add -A git diff --cached --quiet || { git commit -m "chore(version): bump to ${VERSION} [skip ci]" @@ -107,7 +107,7 @@ jobs: [ -n "$ELEM" ] && EXT_ELEMENT="$ELEM" fi fi - [ -z "$EXT_ELEMENT" ] && EXT_ELEMENT=$(echo "${GITEA_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -') + [ -z "$EXT_ELEMENT" ] && EXT_ELEMENT=$(echo "${MOKOGIT_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -') ZIP_NAME="${EXT_ELEMENT}-${VERSION}${SUFFIX}.zip" @@ -144,7 +144,7 @@ jobs: echo "sha256=${SHA256}" >> "$GITHUB_OUTPUT" fi - - name: Create or replace Gitea release + - name: Create or replace MokoGit release id: release continue-on-error: true run: | @@ -154,8 +154,8 @@ jobs: SHA256="${{ steps.zip.outputs.sha256 }}" ZIP_NAME="${{ steps.zip.outputs.zip_name }}" EXT_ELEMENT="${{ steps.meta.outputs.ext_element }}" - TOKEN="${{ secrets.MOKOGITEA_TOKEN }}" - API="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" + TOKEN="${{ secrets.MOKOGIT_TOKEN }}" + API="${MOKOGIT_URL}/api/v1/repos/${MOKOGIT_ORG}/${MOKOGIT_REPO}" BRANCH=$(git branch --show-current) BODY="## ${VERSION} ($(date +%Y-%m-%d)) @@ -194,31 +194,11 @@ jobs: echo "Released: ${EXT_ELEMENT} ${VERSION} (${STABILITY})" - - name: "Update updates.xml" - if: steps.platform.outputs.platform == 'joomla' - run: | - VERSION="${{ steps.meta.outputs.version }}" - STABILITY="${{ steps.meta.outputs.stability }}" - SHA256="${{ steps.zip.outputs.sha256 }}" - php /tmp/mokocli-api/cli/updates_xml_build.php --path . --version "$VERSION" --stability "$STABILITY" --sha "$SHA256" --gitea-url "$GITEA_URL" --org "$GITEA_ORG" --repo "$GITEA_REPO" - 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 add updates.xml - git commit -m "chore: update $STABILITY channel $VERSION [skip ci]" - git push origin HEAD 2>&1 || echo "WARNING: push failed" - fi - - - name: "Sync updates.xml to all branches" - if: steps.platform.outputs.platform == 'joomla' - run: | - php /tmp/mokocli-api/cli/updates_xml_sync.php --path . --current "${{ github.ref_name }}" --branches main,dev --version "${{ steps.meta.outputs.version }}" --token "${{ secrets.MOKOGITEA_TOKEN }}" --org "${GITEA_ORG}" --repo "${GITEA_REPO}" --gitea-url "${GITEA_URL}" - - name: "Delete lesser pre-release channels (cascade)" continue-on-error: true run: | - API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" - TOKEN="${{ secrets.MOKOGITEA_TOKEN }}" + API_BASE="${MOKOGIT_URL}/api/v1/repos/${MOKOGIT_ORG}/${MOKOGIT_REPO}" + TOKEN="${{ secrets.MOKOGIT_TOKEN }}" STABILITY="${{ steps.meta.outputs.stability }}" # Cascade: rc → beta,alpha,dev | beta → alpha,dev | alpha → dev | dev → nothing diff --git a/mcp/servers/mokossh/.mokogitea/workflows/repo-health.yml b/mcp/servers/mokosuite_api/.mokogit/workflows/repo-health.yml similarity index 98% rename from mcp/servers/mokossh/.mokogitea/workflows/repo-health.yml rename to mcp/servers/mokosuite_api/.mokogit/workflows/repo-health.yml index 48f27ab2..08cd303c 100644 --- a/mcp/servers/mokossh/.mokogitea/workflows/repo-health.yml +++ b/mcp/servers/mokosuite_api/.mokogit/workflows/repo-health.yml @@ -6,7 +6,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later # # FILE INFORMATION -# DEFGROUP: Gitea.Workflow +# DEFGROUP: MokoGit.Workflow # INGROUP: mokocli.Validation # REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/mokocli # PATH: /templates/workflows/joomla/repo_health.yml.template @@ -49,7 +49,7 @@ env: SCRIPTS_ALLOWED_DIRS: scripts,scripts/fix,scripts/lib,scripts/release,scripts/run,scripts/validate # Repo health policy - REPO_REQUIRED_ARTIFACTS: README.md,LICENSE,CHANGELOG.md,CONTRIBUTING.md,CODE_OF_CONDUCT.md,.gitea/workflows/ + REPO_REQUIRED_ARTIFACTS: README.md,LICENSE,CHANGELOG.md,CONTRIBUTING.md,CODE_OF_CONDUCT.md,.mokogit/workflows/ REPO_OPTIONAL_FILES: SECURITY.md,GOVERNANCE.md,.editorconfig,.gitattributes,.gitignore,README.md,docs/ REPO_DISALLOWED_DIRS: REPO_DISALLOWED_FILES: TODO.md,todo.md @@ -60,7 +60,7 @@ env: # File / directory variables DOCS_INDEX: docs/docs-index.md SCRIPT_DIR: scripts - WORKFLOWS_DIR: .gitea/workflows + WORKFLOWS_DIR: .mokogit/workflows SHELLCHECK_PATTERN: '*.sh' SPDX_FILE_GLOBS: '*.sh,*.php,*.js,*.ts,*.css,*.xml,*.yml,*.yaml' FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true @@ -81,7 +81,7 @@ jobs: - name: Check actor permission (admin only) id: perm env: - TOKEN: ${{ secrets.MOKOGITEA_TOKEN || secrets.MOKOGITEA_TOKEN || github.token }} + TOKEN: ${{ secrets.MOKOGIT_TOKEN || secrets.MOKOGIT_TOKEN || github.token }} REPO: ${{ github.repository }} ACTOR: ${{ github.actor }} run: | @@ -92,14 +92,14 @@ jobs: # Hardcoded authorized users — always allowed case "$ACTOR" in - jmiller|gitea-actions[bot]) + jmiller|mokogit-actions[bot]) ALLOWED=true PERMISSION=admin METHOD="hardcoded allowlist" ;; *) # Detect platform and check permissions via API - API_BASE="${GITHUB_API_URL:-${GITEA_API_URL:-https://api.github.com}}" + API_BASE="${GITHUB_API_URL:-${MOKOGIT_API_URL:-https://api.github.com}}" RESP=$(curl -sf -H "Authorization: token ${TOKEN}" \ "${API_BASE}/repos/${REPO}/collaborators/${ACTOR}/permission" 2>/dev/null || echo '{}') PERMISSION=$(echo "$RESP" | grep -oP '"permission"\s*:\s*"\K[^"]+' || echo "unknown") @@ -551,10 +551,6 @@ jobs: joomla_findings+=("No .ini language files found") fi - if [ ! -f 'updates.xml' ]; then - joomla_findings+=("updates.xml missing in root (required for Joomla update server)") - fi - if [ -n "${SOURCE_DIR}" ]; then INDEX_DIRS=("${SOURCE_DIR}" "${SOURCE_DIR}/admin" "${SOURCE_DIR}/site") for dir in "${INDEX_DIRS[@]}"; do diff --git a/mcp/servers/mokossh/.mokogitea/workflows/repository-cleanup.yml b/mcp/servers/mokosuite_api/.mokogit/workflows/repository-cleanup.yml similarity index 99% rename from mcp/servers/mokossh/.mokogitea/workflows/repository-cleanup.yml rename to mcp/servers/mokosuite_api/.mokogit/workflows/repository-cleanup.yml index 0468b176..bce1b895 100644 --- a/mcp/servers/mokossh/.mokogitea/workflows/repository-cleanup.yml +++ b/mcp/servers/mokosuite_api/.mokogit/workflows/repository-cleanup.yml @@ -11,7 +11,7 @@ # PATH: /templates/workflows/shared/repository-cleanup.yml.template # VERSION: 04.06.00 # BRIEF: Recurring repository maintenance — labels, branches, workflows, logs, doc indexes -# NOTE: Synced via bulk-repo-sync to .mokogitea/workflows/repository-cleanup.yml in all governed repos. +# NOTE: Synced via bulk-repo-sync to .mokogit/workflows/repository-cleanup.yml in all governed repos. # Runs on the 1st and 15th of each month at 6:00 AM UTC, and on manual dispatch. name: "Universal: Repository Cleanup" diff --git a/mcp/servers/mokossh/.mokogitea/workflows/security-audit.yml b/mcp/servers/mokosuite_api/.mokogit/workflows/security-audit.yml similarity index 95% rename from mcp/servers/mokossh/.mokogitea/workflows/security-audit.yml rename to mcp/servers/mokosuite_api/.mokogit/workflows/security-audit.yml index 2406a072..30811344 100644 --- a/mcp/servers/mokossh/.mokogitea/workflows/security-audit.yml +++ b/mcp/servers/mokosuite_api/.mokogit/workflows/security-audit.yml @@ -3,10 +3,10 @@ # SPDX-License-Identifier: GPL-3.0-or-later # # FILE INFORMATION -# DEFGROUP: Gitea.Workflow +# DEFGROUP: MokoGit.Workflow # INGROUP: mokocli.Security # REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli -# PATH: /.gitea/workflows/security-audit.yml +# PATH: /.mokogit/workflows/security-audit.yml # VERSION: 01.00.00 # BRIEF: Dependency vulnerability scanning for composer and npm packages @@ -30,7 +30,7 @@ permissions: env: NTFY_URL: ${{ vars.NTFY_URL || 'https://ntfy.mokoconsulting.tech' }} - NTFY_TOPIC: ${{ vars.NTFY_TOPIC || 'gitea-security' }} + NTFY_TOPIC: ${{ vars.NTFY_TOPIC || 'mokogit-security' }} jobs: audit: diff --git a/mcp/servers/mokosuite_api/.mokogitea/workflows/standards-compliance.yml b/mcp/servers/mokosuite_api/.mokogit/workflows/standards-compliance.yml similarity index 99% rename from mcp/servers/mokosuite_api/.mokogitea/workflows/standards-compliance.yml rename to mcp/servers/mokosuite_api/.mokogit/workflows/standards-compliance.yml index 77741610..19197e37 100644 --- a/mcp/servers/mokosuite_api/.mokogitea/workflows/standards-compliance.yml +++ b/mcp/servers/mokosuite_api/.mokogit/workflows/standards-compliance.yml @@ -4,7 +4,7 @@ # DEFGROUP: GitHub.Workflow # INGROUP: MokoCli.Compliance # REPO: https://github.com/mokoconsulting-tech/MokoCli -# PATH: /.mokogitea/workflows/standards-compliance.yml +# PATH: /.mokogit/workflows/standards-compliance.yml # VERSION: 04.06.00 # BRIEF: MokoCli compliance validation workflow # NOTE: Validates repository structure, documentation, and coding standards diff --git a/mcp/servers/windows/.mokogitea/workflows/sync-version-on-merge.yml b/mcp/servers/mokosuite_api/.mokogit/workflows/sync-version-on-merge.yml similarity index 97% rename from mcp/servers/windows/.mokogitea/workflows/sync-version-on-merge.yml rename to mcp/servers/mokosuite_api/.mokogit/workflows/sync-version-on-merge.yml index a3238bdb..af1a686d 100644 --- a/mcp/servers/windows/.mokogitea/workflows/sync-version-on-merge.yml +++ b/mcp/servers/mokosuite_api/.mokogit/workflows/sync-version-on-merge.yml @@ -11,7 +11,7 @@ # PATH: /templates/workflows/shared/sync-version-on-merge.yml.template # VERSION: 04.06.00 # BRIEF: Auto-bump patch version on every push to main and propagate to all file headers -# NOTE: Synced via bulk-repo-sync to .mokogitea/workflows/sync-version-on-merge.yml in all governed repos. +# NOTE: Synced via bulk-repo-sync to .mokogit/workflows/sync-version-on-merge.yml in all governed repos. # README.md is the single source of truth for the repository version. name: "Universal: Sync Version on Merge" diff --git a/mcp/servers/mokosuite_api/CONTRIBUTING.md b/mcp/servers/mokosuite_api/CONTRIBUTING.md index db5f1ce9..46ee52e1 100644 --- a/mcp/servers/mokosuite_api/CONTRIBUTING.md +++ b/mcp/servers/mokosuite_api/CONTRIBUTING.md @@ -148,13 +148,13 @@ Every repo maintains 5 standard release channel tags: ### CI/CD -- Gitea Actions runs all CI workflows +- MokoGit Actions runs all CI workflows - GitHub Actions are disabled on mirrored repos -- Workflows live in both `.github/workflows/` and `.gitea/workflows/` +- Workflows live in both `.github/workflows/` and `.mokogit/workflows/` ### Update Servers (Joomla) -In manifest ``, Gitea must be priority 1, GitHub priority 2. +In manifest ``, MokoGit must be priority 1, GitHub priority 2. ### Secrets diff --git a/mcp/servers/mokosuite_api/README.md b/mcp/servers/mokosuite_api/README.md index 4e6041cb..e7a080c2 100644 --- a/mcp/servers/mokosuite_api/README.md +++ b/mcp/servers/mokosuite_api/README.md @@ -15,7 +15,7 @@ Model Context Protocol server for the Joomla Web Services API -- full CRUD for a | **Language** | Node.js | | **Tools** | 67 tools across 15 resource groups | | **License** | GPL-3.0-or-later | -| **Platform** | [Gitea](https://git.mokoconsulting.tech/MokoConsulting/joomla-api-mcp) (primary) | +| **Platform** | [MokoGit](https://git.mokoconsulting.tech/MokoConsulting/joomla-api-mcp) (primary) | --- diff --git a/mcp/servers/mokosuite_api/SECURITY.md b/mcp/servers/mokosuite_api/SECURITY.md index 714531c0..26d73c3c 100644 --- a/mcp/servers/mokosuite_api/SECURITY.md +++ b/mcp/servers/mokosuite_api/SECURITY.md @@ -46,7 +46,7 @@ Only the current major version receives security updates. Users should upgrade t ## Reporting a Vulnerability -Report security vulnerabilities via Gitea issue (preferred): +Report security vulnerabilities via MokoGit issue (preferred): https://git.mokoconsulting.tech/MokoConsulting/MokoCli-Template-Generic/issues/new?template=security.yaml Or email: hello@mokoconsulting.tech diff --git a/mcp/servers/windows/.mokogitea/CLAUDE.md b/mcp/servers/windows/.mokogit/CLAUDE.md similarity index 90% rename from mcp/servers/windows/.mokogitea/CLAUDE.md rename to mcp/servers/windows/.mokogit/CLAUDE.md index 8e557f06..88307ec2 100644 --- a/mcp/servers/windows/.mokogitea/CLAUDE.md +++ b/mcp/servers/windows/.mokogit/CLAUDE.md @@ -39,6 +39,6 @@ src/ - **Never commit** `.claude/`, `.mcp.json`, `TODO.md`, `*.min.css`/`*.min.js` - **Attribution**: `Authored-by: Moko Consulting` -- **Workflow directory**: `.mokogitea/` (not `.gitea/` or `.github/`) -- **Wiki**: documentation lives in the Gitea wiki, not `docs/` files +- **Workflow directory**: `.mokogit/` (not `.mokogit/` or `.github/`) +- **Wiki**: documentation lives in the MokoGit wiki, not `docs/` files - **Standards**: [MokoCli](https://git.mokoconsulting.tech/MokoConsulting/mokocli/wiki/Home) diff --git a/mcp/servers/windows/.mokogitea/ISSUE_TEMPLATE/adr.md b/mcp/servers/windows/.mokogit/ISSUE_TEMPLATE/adr.md similarity index 100% rename from mcp/servers/windows/.mokogitea/ISSUE_TEMPLATE/adr.md rename to mcp/servers/windows/.mokogit/ISSUE_TEMPLATE/adr.md diff --git a/mcp/servers/windows/.mokogitea/ISSUE_TEMPLATE/bug_report.md b/mcp/servers/windows/.mokogit/ISSUE_TEMPLATE/bug_report.md similarity index 100% rename from mcp/servers/windows/.mokogitea/ISSUE_TEMPLATE/bug_report.md rename to mcp/servers/windows/.mokogit/ISSUE_TEMPLATE/bug_report.md diff --git a/mcp/servers/windows/.mokogitea/ISSUE_TEMPLATE/config.yml b/mcp/servers/windows/.mokogit/ISSUE_TEMPLATE/config.yml similarity index 100% rename from mcp/servers/windows/.mokogitea/ISSUE_TEMPLATE/config.yml rename to mcp/servers/windows/.mokogit/ISSUE_TEMPLATE/config.yml diff --git a/mcp/servers/windows/.mokogitea/ISSUE_TEMPLATE/documentation.md b/mcp/servers/windows/.mokogit/ISSUE_TEMPLATE/documentation.md similarity index 100% rename from mcp/servers/windows/.mokogitea/ISSUE_TEMPLATE/documentation.md rename to mcp/servers/windows/.mokogit/ISSUE_TEMPLATE/documentation.md diff --git a/mcp/servers/windows/.mokogitea/ISSUE_TEMPLATE/feature_request.md b/mcp/servers/windows/.mokogit/ISSUE_TEMPLATE/feature_request.md similarity index 100% rename from mcp/servers/windows/.mokogitea/ISSUE_TEMPLATE/feature_request.md rename to mcp/servers/windows/.mokogit/ISSUE_TEMPLATE/feature_request.md diff --git a/mcp/servers/windows/.mokogitea/ISSUE_TEMPLATE/mcp_api_integration.md b/mcp/servers/windows/.mokogit/ISSUE_TEMPLATE/mcp_api_integration.md similarity index 100% rename from mcp/servers/windows/.mokogitea/ISSUE_TEMPLATE/mcp_api_integration.md rename to mcp/servers/windows/.mokogit/ISSUE_TEMPLATE/mcp_api_integration.md diff --git a/mcp/servers/windows/.mokogitea/ISSUE_TEMPLATE/mcp_connection_issue.md b/mcp/servers/windows/.mokogit/ISSUE_TEMPLATE/mcp_connection_issue.md similarity index 100% rename from mcp/servers/windows/.mokogitea/ISSUE_TEMPLATE/mcp_connection_issue.md rename to mcp/servers/windows/.mokogit/ISSUE_TEMPLATE/mcp_connection_issue.md diff --git a/mcp/servers/windows/.mokogitea/ISSUE_TEMPLATE/mcp_tool_request.md b/mcp/servers/windows/.mokogit/ISSUE_TEMPLATE/mcp_tool_request.md similarity index 100% rename from mcp/servers/windows/.mokogitea/ISSUE_TEMPLATE/mcp_tool_request.md rename to mcp/servers/windows/.mokogit/ISSUE_TEMPLATE/mcp_tool_request.md diff --git a/mcp/servers/windows/.mokogitea/ISSUE_TEMPLATE/question.md b/mcp/servers/windows/.mokogit/ISSUE_TEMPLATE/question.md similarity index 100% rename from mcp/servers/windows/.mokogitea/ISSUE_TEMPLATE/question.md rename to mcp/servers/windows/.mokogit/ISSUE_TEMPLATE/question.md diff --git a/mcp/servers/windows/.mokogitea/ISSUE_TEMPLATE/rfc.md b/mcp/servers/windows/.mokogit/ISSUE_TEMPLATE/rfc.md similarity index 100% rename from mcp/servers/windows/.mokogitea/ISSUE_TEMPLATE/rfc.md rename to mcp/servers/windows/.mokogit/ISSUE_TEMPLATE/rfc.md diff --git a/mcp/servers/windows/.mokogitea/ISSUE_TEMPLATE/security.md b/mcp/servers/windows/.mokogit/ISSUE_TEMPLATE/security.md similarity index 100% rename from mcp/servers/windows/.mokogitea/ISSUE_TEMPLATE/security.md rename to mcp/servers/windows/.mokogit/ISSUE_TEMPLATE/security.md diff --git a/mcp/servers/windows/.mokogitea/ISSUE_TEMPLATE/version.md b/mcp/servers/windows/.mokogit/ISSUE_TEMPLATE/version.md similarity index 100% rename from mcp/servers/windows/.mokogitea/ISSUE_TEMPLATE/version.md rename to mcp/servers/windows/.mokogit/ISSUE_TEMPLATE/version.md diff --git a/mcp/servers/windows/.mokogitea/manifest.xml b/mcp/servers/windows/.mokogit/manifest.xml similarity index 100% rename from mcp/servers/windows/.mokogitea/manifest.xml rename to mcp/servers/windows/.mokogit/manifest.xml diff --git a/mcp/servers/mokossh/.mokogitea/workflows/auto-assign.yml b/mcp/servers/windows/.mokogit/workflows/auto-assign.yml similarity index 98% rename from mcp/servers/mokossh/.mokogitea/workflows/auto-assign.yml rename to mcp/servers/windows/.mokogit/workflows/auto-assign.yml index ab7f5737..b9008a4b 100644 --- a/mcp/servers/mokossh/.mokogitea/workflows/auto-assign.yml +++ b/mcp/servers/windows/.mokogit/workflows/auto-assign.yml @@ -5,7 +5,7 @@ # DEFGROUP: GitHub.Workflow # INGROUP: MokoCli.Workflows.Shared # REPO: https://github.com/mokoconsulting-tech/MokoCli -# PATH: /.mokogitea/workflows/auto-assign.yml +# PATH: /.mokogit/workflows/auto-assign.yml # VERSION: 04.06.00 # BRIEF: Auto-assign jmiller to unassigned issues and PRs every 15 minutes diff --git a/mcp/servers/mokossh/.mokogitea/workflows/auto-dev-issue.yml b/mcp/servers/windows/.mokogit/workflows/auto-dev-issue.yml similarity index 98% rename from mcp/servers/mokossh/.mokogitea/workflows/auto-dev-issue.yml rename to mcp/servers/windows/.mokogit/workflows/auto-dev-issue.yml index a8774aba..f48dac0b 100644 --- a/mcp/servers/mokossh/.mokogitea/workflows/auto-dev-issue.yml +++ b/mcp/servers/windows/.mokogit/workflows/auto-dev-issue.yml @@ -11,7 +11,7 @@ # PATH: /templates/workflows/shared/auto-dev-issue.yml.template # VERSION: 04.06.00 # BRIEF: Auto-create tracking issue with sub-issues for dev/rc branch workflow -# NOTE: Synced via bulk-repo-sync to .mokogitea/workflows/auto-dev-issue.yml in all governed repos. +# NOTE: Synced via bulk-repo-sync to .mokogit/workflows/auto-dev-issue.yml in all governed repos. name: "Universal: Dev/RC Branch Issue" diff --git a/mcp/servers/windows/.mokogitea/workflows/auto-release.yml b/mcp/servers/windows/.mokogit/workflows/auto-release.yml similarity index 82% rename from mcp/servers/windows/.mokogitea/workflows/auto-release.yml rename to mcp/servers/windows/.mokogit/workflows/auto-release.yml index 47d5354a..bf65f62c 100644 --- a/mcp/servers/windows/.mokogitea/workflows/auto-release.yml +++ b/mcp/servers/windows/.mokogit/workflows/auto-release.yml @@ -3,7 +3,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later # # FILE INFORMATION -# DEFGROUP: Gitea.Workflow +# DEFGROUP: MokoGit.Workflow # INGROUP: mokocli.Release # REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/mokocli # PATH: /templates/workflows/universal/auto-release.yml.template @@ -17,7 +17,7 @@ # | Reads manifest.xml (joomla|dolibarr|generic) to branch logic. | # | | # | Platform-specific: | -# | joomla: XML manifest, updates.xml, type-prefixed packages | +# | joomla: XML manifest, type-prefixed packages | # | dolibarr: mod*.class.php, update.txt, dev version reset | # | generic: README-only, no update stream | # | | @@ -36,9 +36,9 @@ on: env: FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true - GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }} - GITEA_ORG: ${{ vars.GITEA_ORG || github.repository_owner }} - GITEA_REPO: ${{ vars.GITEA_REPO || github.event.repository.name }} + MOKOGIT_URL: ${{ vars.MOKOGIT_URL || 'https://git.mokoconsulting.tech' }} + MOKOGIT_ORG: ${{ vars.MOKOGIT_ORG || github.repository_owner }} + MOKOGIT_REPO: ${{ vars.MOKOGIT_REPO || github.event.repository.name }} permissions: contents: write @@ -53,12 +53,12 @@ jobs: - name: Checkout repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: - token: ${{ secrets.MOKOGITEA_TOKEN }} + token: ${{ secrets.MOKOGIT_TOKEN }} fetch-depth: 0 - name: Setup mokocli tools env: - MOKO_CLONE_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }} + MOKO_CLONE_TOKEN: ${{ secrets.MOKOGIT_TOKEN }} MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GH_PAT }}"}}' run: | @@ -262,17 +262,6 @@ jobs: VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" php /tmp/mokocli-api/cli/badge_update.php --path . --version "${VERSION}" 2>/dev/null || true - - name: "Step 5: Write update stream" - if: >- - steps.version.outputs.skip != 'true' && - steps.platform.outputs.platform == 'joomla' - run: | - VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" - php /tmp/mokocli-api/cli/updates_xml_build.php \ - --path . --version "${VERSION}" --stability stable \ - --gitea-url "${GITEA_URL}" --org "${GITEA_ORG}" --repo "${GITEA_REPO}" \ - --github-output - - name: Commit release changes if: >- steps.version.outputs.skip != 'true' && @@ -283,13 +272,13 @@ jobs: exit 0 fi VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" - git config --local user.email "gitea-actions[bot]@mokoconsulting.tech" - git config --local user.name "gitea-actions[bot]" + git config --local user.email "mokogit-actions[bot]@mokoconsulting.tech" + git config --local user.name "mokogit-actions[bot]" # Set push URL with token for branch-protected repos - git remote set-url origin "https://jmiller:${{ secrets.MOKOGITEA_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git" + git remote set-url origin "https://jmiller:${{ secrets.MOKOGIT_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git" git add -A git commit -m "chore(release): build ${VERSION} [skip ci]" \ - --author="gitea-actions[bot] " + --author="mokogit-actions[bot] " git push -u origin HEAD # -- STEP 6: Create tag --------------------------------------------------- @@ -310,8 +299,8 @@ jobs: fi echo "Tag: ${TAG}" >> $GITHUB_STEP_SUMMARY - # -- STEP 7: Create or update Gitea Release -------------------------------- - - name: "Step 7: Gitea Release" + # -- STEP 7: Create or update MokoGit Release -------------------------------- + - name: "Step 7: MokoGit Release" if: >- steps.version.outputs.skip != 'true' run: | @@ -319,7 +308,7 @@ jobs: RELEASE_TAG="${{ steps.version.outputs.release_tag }}" BRANCH="${{ steps.version.outputs.branch }}" MAJOR="${{ steps.version.outputs.major }}" - API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" + API_BASE="${MOKOGIT_URL}/api/v1/repos/${MOKOGIT_ORG}/${MOKOGIT_REPO}" # Reuse metadata from Step 5 (single source of truth) EXT_ELEMENT="${{ steps.updates.outputs.ext_element }}" @@ -329,9 +318,9 @@ jobs: # Fallbacks if Step 5 was skipped if [ -z "$EXT_ELEMENT" ]; then - EXT_ELEMENT=$(echo "${GITEA_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -') + EXT_ELEMENT=$(echo "${MOKOGIT_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -') fi - [ -z "$EXT_NAME" ] && EXT_NAME="${GITEA_REPO}" + [ -z "$EXT_NAME" ] && EXT_NAME="${MOKOGIT_REPO}" NOTES=$(php /tmp/mokocli-api/cli/release_notes.php --path . --version "$VERSION" 2>/dev/null) [ -z "$NOTES" ] && NOTES="Release ${VERSION}" @@ -349,20 +338,20 @@ jobs: RELEASE_NAME="${EXT_NAME} ${VERSION} (${TYPE_PREFIX}${EXT_ELEMENT}-${VERSION})" # Delete existing release if present (overwrite, not append) - EXISTING=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \ + EXISTING=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGIT_TOKEN }}" \ "${API_BASE}/releases/tags/${RELEASE_TAG}" 2>/dev/null || true) EXISTING_ID=$(echo "$EXISTING" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('id',''))" 2>/dev/null || true) if [ -n "$EXISTING_ID" ]; then - curl -sS -X DELETE -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \ + curl -sS -X DELETE -H "Authorization: token ${{ secrets.MOKOGIT_TOKEN }}" \ "${API_BASE}/releases/${EXISTING_ID}" 2>/dev/null || true - curl -sS -X DELETE -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \ + curl -sS -X DELETE -H "Authorization: token ${{ secrets.MOKOGIT_TOKEN }}" \ "${API_BASE}/tags/${RELEASE_TAG}" 2>/dev/null || true echo "Deleted previous stable release (id: ${EXISTING_ID})" fi # Create fresh release - curl -sf -X POST -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \ + curl -sf -X POST -H "Authorization: token ${{ secrets.MOKOGIT_TOKEN }}" \ -H "Content-Type: application/json" \ "${API_BASE}/releases" \ -d "$(python3 -c "import json; print(json.dumps({ @@ -381,10 +370,10 @@ jobs: VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" RELEASE_TAG="${{ steps.version.outputs.release_tag }}" REPO="${{ github.repository }}" - API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" + API_BASE="${MOKOGIT_URL}/api/v1/repos/${MOKOGIT_ORG}/${MOKOGIT_REPO}" # All ZIPs upload to the major release tag (vXX) - RELEASE_JSON=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \ + RELEASE_JSON=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGIT_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 @@ -402,7 +391,7 @@ jobs: EXT_ELEMENT=$(sed -n 's/.*\([^<]*\)<\/element>.*/\1/p' "$MANIFEST" 2>/dev/null | head -1) [ -z "$EXT_ELEMENT" ] && EXT_ELEMENT=$(sed -n 's/.*plugin="\([^"]*\)".*/\1/p' "$MANIFEST" 2>/dev/null | head -1) [ -z "$EXT_ELEMENT" ] && EXT_ELEMENT=$(basename "$MANIFEST" .xml | tr '[:upper:]' '[:lower:]') - [ -z "$EXT_ELEMENT" ] && EXT_ELEMENT=$(echo "${GITEA_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -') + [ -z "$EXT_ELEMENT" ] && EXT_ELEMENT=$(echo "${MOKOGIT_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -') fi # ZIP name: type_folder_element-VERSION (e.g. plg_system_mokojgdpc-01.01.00.zip) EXT_TYPE=$(sed -n 's/.*]*type="\([^"]*\)".*/\1/p' "$MANIFEST" | head -1) @@ -443,7 +432,7 @@ jobs: SHA256_TAR=$(sha256sum "/tmp/${TAR_NAME}" | cut -d' ' -f1) # -- Delete existing assets with same name before uploading ------ - ASSETS=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \ + ASSETS=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGIT_TOKEN }}" \ "${API_BASE}/releases/${RELEASE_ID}/assets" 2>/dev/null || echo "[]") for ASSET_NAME in "$ZIP_NAME" "$TAR_NAME"; do ASSET_ID=$(echo "$ASSETS" | python3 -c " @@ -454,99 +443,22 @@ jobs: print(a['id']); break " 2>/dev/null || true) if [ -n "$ASSET_ID" ]; then - curl -sf -X DELETE -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \ + curl -sf -X DELETE -H "Authorization: token ${{ secrets.MOKOGIT_TOKEN }}" \ "${API_BASE}/releases/${RELEASE_ID}/assets/${ASSET_ID}" 2>/dev/null || true fi done # -- Upload both to release tag ---------------------------------- - curl -sf -X POST -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \ + curl -sf -X POST -H "Authorization: token ${{ secrets.MOKOGIT_TOKEN }}" \ -H "Content-Type: application/octet-stream" \ --data-binary @"/tmp/${ZIP_NAME}" \ "${API_BASE}/releases/${RELEASE_ID}/assets?name=${ZIP_NAME}" > /dev/null 2>&1 || true - curl -sf -X POST -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \ + curl -sf -X POST -H "Authorization: token ${{ secrets.MOKOGIT_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 - # -- Update updates.xml with both download formats --------------- - if [ -f "updates.xml" ]; then - ZIP_URL="${GITEA_URL}/${GITEA_ORG}/${GITEA_REPO}/releases/download/${RELEASE_TAG}/${ZIP_NAME}" - TAR_URL="${GITEA_URL}/${GITEA_ORG}/${GITEA_REPO}/releases/download/${RELEASE_TAG}/${TAR_NAME}" - - # Use Python to update only the stable entry's downloads + sha256 - export PY_ZIP_URL="$ZIP_URL" PY_TAR_URL="$TAR_URL" PY_SHA="$SHA256_ZIP" - python3 << 'PYEOF' - import re, os - - with open("updates.xml") as f: - content = f.read() - - zip_url = os.environ["PY_ZIP_URL"] - tar_url = os.environ["PY_TAR_URL"] - sha = os.environ["PY_SHA"] - - # Find the stable update block and replace its downloads + sha256 - def replace_stable(m): - block = m.group(0) - # Replace downloads block - new_downloads = ( - " \n" - f" {zip_url}\n" - " " - ) - block = re.sub(r' .*?', new_downloads, block, flags=re.DOTALL) - # Add or replace sha256 - if '' in block: - block = re.sub(r' .*?', f' {sha}', block) - else: - block = block.replace('', f'\n {sha}') - return block - - content = re.sub( - r' .*?stable.*?', - replace_stable, - content, - flags=re.DOTALL - ) - - with open("updates.xml", "w") as f: - f.write(content) - PYEOF - - CURRENT_BRANCH="${{ github.ref_name }}" - git add updates.xml - git commit -m "chore(release): ZIP + tar.gz for ${VERSION} [skip ci]" \ - --author="gitea-actions[bot] " || true - git push || true - - # Sync updates.xml to main via direct API (always runs — may be on version/XX branch) - GA_TOKEN="${{ secrets.MOKOGITEA_TOKEN }}" - API="${GITEA_URL:-https://git.mokoconsulting.tech}/api/v1/repos/${{ github.repository }}" - - FILE_SHA=$(curl -sf -H "Authorization: token ${GA_TOKEN}" \ - "${API}/contents/updates.xml?ref=main" | jq -r '.sha // empty') - - if [ -n "$FILE_SHA" ]; then - CONTENT=$(base64 -w0 updates.xml) - curl -sf -X PUT -H "Authorization: token ${GA_TOKEN}" \ - -H "Content-Type: application/json" \ - "${API}/contents/updates.xml" \ - -d "$(jq -n \ - --arg content "$CONTENT" \ - --arg sha "$FILE_SHA" \ - --arg msg "chore: sync updates.xml ${VERSION} [skip ci]" \ - --arg branch "main" \ - '{content: $content, sha: $sha, message: $msg, branch: $branch}' - )" > /dev/null 2>&1 \ - && echo "updates.xml synced to main via API" \ - || echo "WARNING: failed to sync updates.xml to main" - else - echo "WARNING: could not get updates.xml SHA from main" - fi - fi - echo "### Packages" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "| Package | Size | SHA-256 |" >> $GITHUB_STEP_SUMMARY @@ -554,7 +466,7 @@ jobs: echo "| \`${ZIP_NAME}\` | ${ZIP_SIZE} | \`${SHA256_ZIP}\` |" >> $GITHUB_STEP_SUMMARY echo "| \`${TAR_NAME}\` | ${TAR_SIZE} | \`${SHA256_TAR}\` |" >> $GITHUB_STEP_SUMMARY echo "| Release | \`${RELEASE_TAG}\` | |" >> $GITHUB_STEP_SUMMARY - echo "| Download | [${ZIP_NAME}](${GITEA_URL}/${GITEA_ORG}/${GITEA_REPO}/releases/download/${RELEASE_TAG}/${ZIP_NAME}) |" >> $GITHUB_STEP_SUMMARY + echo "| Download | [${ZIP_NAME}](${MOKOGIT_URL}/${MOKOGIT_ORG}/${MOKOGIT_REPO}/releases/download/${RELEASE_TAG}/${ZIP_NAME}) |" >> $GITHUB_STEP_SUMMARY # -- STEP 8b: Update release description with changelog + SHA ---------------- - name: "Step 8b: Update release body with changelog and SHA" @@ -562,7 +474,7 @@ jobs: run: | VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" RELEASE_TAG="${{ steps.version.outputs.release_tag }}" - API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" + API_BASE="${MOKOGIT_URL}/api/v1/repos/${MOKOGIT_ORG}/${MOKOGIT_REPO}" EXT_ELEMENT="${{ steps.updates.outputs.ext_element }}" EXT_TYPE="${{ steps.updates.outputs.ext_type }}" EXT_FOLDER="${{ steps.updates.outputs.ext_folder }}" @@ -604,7 +516,7 @@ jobs: [ -n "$SHA256_TAR" ] && BODY="${BODY}| \`${TAR_NAME}\` | \`${SHA256_TAR}\` |\n" # Get release ID and update body - RELEASE_ID=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \ + RELEASE_ID=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGIT_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) @@ -616,7 +528,7 @@ jobs: req = urllib.request.Request( '${API_BASE}/releases/${RELEASE_ID}', data=data, - headers={'Authorization': 'token ${{ secrets.MOKOGITEA_TOKEN }}', 'Content-Type': 'application/json'}, + headers={'Authorization': 'token ${{ secrets.MOKOGIT_TOKEN }}', 'Content-Type': 'application/json'}, method='PATCH' ) urllib.request.urlopen(req) @@ -643,7 +555,7 @@ jobs: [ -z "$NOTES" ] && NOTES="Release ${VERSION}" echo "$NOTES" > /tmp/release_notes.md - EXISTING=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" "${GITEA_URL:-https://git.mokoconsulting.tech}/api/v1/repos/${{ github.repository }}/releases/tags/$RELEASE_TAG" 2>/dev/null | jq -r ".tag_name // empty" || true) + EXISTING=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGIT_TOKEN }}" "${MOKOGIT_URL:-https://git.mokoconsulting.tech}/api/v1/repos/${{ github.repository }}/releases/tags/$RELEASE_TAG" 2>/dev/null | jq -r ".tag_name // empty" || true) if [ -z "$EXISTING" ]; then gh release create "$RELEASE_TAG" \ @@ -660,8 +572,8 @@ jobs: # Upload assets to GitHub mirror for PKG in /tmp/${EXT_ELEMENT:-pkg}-${VERSION}.*; do if [ -f "$PKG" ]; then - _RELID=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" "${GITEA_URL:-https://git.mokoconsulting.tech}/api/v1/repos/${{ github.repository }}/releases/tags/$RELEASE_TAG" 2>/dev/null | jq -r ".id // empty") - [ -n "$_RELID" ] && curl -sf -X POST -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" -H "Content-Type: application/octet-stream" "${GITEA_URL:-https://git.mokoconsulting.tech}/api/v1/repos/${{ github.repository }}/releases/${_RELID}/assets?name=$(basename $PKG)" --data-binary "@$PKG" > /dev/null 2>&1 || true + _RELID=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGIT_TOKEN }}" "${MOKOGIT_URL:-https://git.mokoconsulting.tech}/api/v1/repos/${{ github.repository }}/releases/tags/$RELEASE_TAG" 2>/dev/null | jq -r ".id // empty") + [ -n "$_RELID" ] && curl -sf -X POST -H "Authorization: token ${{ secrets.MOKOGIT_TOKEN }}" -H "Content-Type: application/octet-stream" "${MOKOGIT_URL:-https://git.mokoconsulting.tech}/api/v1/repos/${{ github.repository }}/releases/${_RELID}/assets?name=$(basename $PKG)" --data-binary "@$PKG" > /dev/null 2>&1 || true fi done echo "GitHub mirror updated: ${GH_REPO} ${RELEASE_TAG}" >> $GITHUB_STEP_SUMMARY @@ -690,16 +602,16 @@ jobs: run: | php /tmp/mokocli-api/cli/release_cascade.php \ --stability stable \ - --token "${{ secrets.MOKOGITEA_TOKEN }}" \ - --org "${GITEA_ORG}" --repo "${GITEA_REPO}" \ - --gitea-url "${GITEA_URL}" 2>/dev/null || true + --token "${{ secrets.MOKOGIT_TOKEN }}" \ + --org "${MOKOGIT_ORG}" --repo "${MOKOGIT_REPO}" \ + --mokogit-url "${MOKOGIT_URL}" 2>/dev/null || true - name: "Step 11: Delete and recreate dev 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 }}" + API_BASE="${MOKOGIT_URL}/api/v1/repos/${MOKOGIT_ORG}/${MOKOGIT_REPO}" + TOKEN="${{ secrets.MOKOGIT_TOKEN }}" # Delete dev branch curl -sf -X DELETE -H "Authorization: token ${TOKEN}" \ @@ -722,8 +634,8 @@ jobs: steps.platform.outputs.mod_file != '' continue-on-error: true run: | - API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" - TOKEN="${{ secrets.MOKOGITEA_TOKEN }}" + API_BASE="${MOKOGIT_URL}/api/v1/repos/${MOKOGIT_ORG}/${MOKOGIT_REPO}" + TOKEN="${{ secrets.MOKOGIT_TOKEN }}" MOD_FILE="${{ steps.platform.outputs.mod_file }}" ENCODED_PATH=$(echo "$MOD_FILE" | sed 's|^\./||' | python3 -c "import sys,urllib.parse; print(urllib.parse.quote(sys.stdin.read().strip()))") FILE_RESP=$(curl -sf -H "Authorization: token ${TOKEN}" "${API_BASE}/contents/${ENCODED_PATH}?ref=dev" 2>/dev/null || true) @@ -757,5 +669,5 @@ jobs: echo "| Version | \`${VERSION}\` |" >> $GITHUB_STEP_SUMMARY echo "| Branch | \`${{ steps.version.outputs.branch }}\` |" >> $GITHUB_STEP_SUMMARY echo "| Tag | \`${{ steps.version.outputs.tag }}\` |" >> $GITHUB_STEP_SUMMARY - echo "| Release | [View](${GITEA_URL}/${GITEA_ORG}/${GITEA_REPO}/releases/tag/${{ steps.version.outputs.tag }}) |" >> $GITHUB_STEP_SUMMARY + echo "| Release | [View](${MOKOGIT_URL}/${MOKOGIT_ORG}/${MOKOGIT_REPO}/releases/tag/${{ steps.version.outputs.tag }}) |" >> $GITHUB_STEP_SUMMARY fi diff --git a/mcp/servers/windows/.mokogitea/workflows/cascade-dev.yml b/mcp/servers/windows/.mokogit/workflows/cascade-dev.yml similarity index 92% rename from mcp/servers/windows/.mokogitea/workflows/cascade-dev.yml rename to mcp/servers/windows/.mokogit/workflows/cascade-dev.yml index f595c921..2b5340d8 100644 --- a/mcp/servers/windows/.mokogitea/workflows/cascade-dev.yml +++ b/mcp/servers/windows/.mokogit/workflows/cascade-dev.yml @@ -3,7 +3,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later # # FILE INFORMATION -# DEFGROUP: Gitea.Workflow +# DEFGROUP: MokoGit.Workflow # INGROUP: MokoCli.Maintenance # REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/MokoCli-API # PATH: /templates/workflows/cascade-dev.yml.template @@ -32,9 +32,9 @@ on: env: FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true - GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }} - GITEA_ORG: ${{ vars.GITEA_ORG || github.repository_owner }} - GITEA_REPO: ${{ vars.GITEA_REPO || github.event.repository.name }} + MOKOGIT_URL: ${{ vars.MOKOGIT_URL || 'https://git.mokoconsulting.tech' }} + MOKOGIT_ORG: ${{ vars.MOKOGIT_ORG || github.repository_owner }} + MOKOGIT_REPO: ${{ vars.MOKOGIT_REPO || github.event.repository.name }} permissions: contents: write @@ -52,9 +52,9 @@ jobs: - name: Discover target branches id: branches env: - GA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }} + GA_TOKEN: ${{ secrets.MOKOGIT_TOKEN }} run: | - API="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" + API="${MOKOGIT_URL}/api/v1/repos/${MOKOGIT_ORG}/${MOKOGIT_REPO}" # Fetch all branches (paginated) PAGE=1 @@ -93,9 +93,9 @@ jobs: - name: Cascade to all target branches if: steps.branches.outputs.targets != '' env: - GA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }} + GA_TOKEN: ${{ secrets.MOKOGIT_TOKEN }} run: | - API="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" + API="${MOKOGIT_URL}/api/v1/repos/${MOKOGIT_ORG}/${MOKOGIT_REPO}" SHORT_SHA="${GITHUB_SHA:0:7}" TARGETS="${{ steps.branches.outputs.targets }}" @@ -127,7 +127,7 @@ jobs: # Check for existing cascade PR EXISTING=$(curl -sS \ -H "Authorization: token ${GA_TOKEN}" \ - "${API}/pulls?state=open&head=${GITEA_ORG}:main&base=${ENCODED_BRANCH}&limit=1") + "${API}/pulls?state=open&head=${MOKOGIT_ORG}:main&base=${ENCODED_BRANCH}&limit=1") EXISTING_COUNT=$(echo "$EXISTING" | jq 'length') PR_NUMBER="" diff --git a/mcp/servers/windows/.mokogitea/workflows/changelog-validation.yml b/mcp/servers/windows/.mokogit/workflows/changelog-validation.yml similarity index 97% rename from mcp/servers/windows/.mokogitea/workflows/changelog-validation.yml rename to mcp/servers/windows/.mokogit/workflows/changelog-validation.yml index f104937c..3bf54b28 100644 --- a/mcp/servers/windows/.mokogitea/workflows/changelog-validation.yml +++ b/mcp/servers/windows/.mokogit/workflows/changelog-validation.yml @@ -11,7 +11,7 @@ # PATH: /templates/workflows/shared/changelog-validation.yml.template # VERSION: 04.06.00 # BRIEF: Validates CHANGELOG.md format and version consistency -# NOTE: Deployed to .mokogitea/workflows/changelog-validation.yml in governed repos. +# NOTE: Deployed to .mokogit/workflows/changelog-validation.yml in governed repos. name: "Universal: Changelog Validation" diff --git a/mcp/servers/windows/.mokogitea/workflows/cleanup.yml b/mcp/servers/windows/.mokogit/workflows/cleanup.yml similarity index 84% rename from mcp/servers/windows/.mokogitea/workflows/cleanup.yml rename to mcp/servers/windows/.mokogit/workflows/cleanup.yml index b06157c7..fc5a7f4e 100644 --- a/mcp/servers/windows/.mokogitea/workflows/cleanup.yml +++ b/mcp/servers/windows/.mokogit/workflows/cleanup.yml @@ -3,10 +3,10 @@ # SPDX-License-Identifier: GPL-3.0-or-later # # FILE INFORMATION -# DEFGROUP: Gitea.Workflow +# DEFGROUP: MokoGit.Workflow # INGROUP: MokoCli.Maintenance # REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoCli -# PATH: /.gitea/workflows/cleanup.yml +# PATH: /.mokogit/workflows/cleanup.yml # VERSION: 01.00.00 # BRIEF: Scheduled cleanup — delete merged branches and old workflow runs @@ -21,7 +21,7 @@ permissions: contents: write env: - GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }} + MOKOGIT_URL: ${{ vars.MOKOGIT_URL || 'https://git.mokoconsulting.tech' }} jobs: cleanup: @@ -33,14 +33,14 @@ jobs: uses: actions/checkout@v4 with: fetch-depth: 0 - token: ${{ secrets.MOKOGITEA_TOKEN }} + token: ${{ secrets.MOKOGIT_TOKEN }} - name: Delete merged branches env: - GA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }} + GA_TOKEN: ${{ secrets.MOKOGIT_TOKEN }} run: | echo "=== Merged Branch Cleanup ===" - API="${GITEA_URL}/api/v1/repos/${{ github.repository }}" + API="${MOKOGIT_URL}/api/v1/repos/${{ github.repository }}" # List branches via API BRANCHES=$(curl -sS -H "Authorization: token ${GA_TOKEN}" \ @@ -66,10 +66,10 @@ jobs: - name: Clean old workflow runs env: - GA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }} + GA_TOKEN: ${{ secrets.MOKOGIT_TOKEN }} run: | echo "=== Workflow Run Cleanup ===" - API="${GITEA_URL}/api/v1/repos/${{ github.repository }}" + API="${MOKOGIT_URL}/api/v1/repos/${{ github.repository }}" CUTOFF=$(date -d "30 days ago" +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -v-30d +%Y-%m-%dT%H:%M:%SZ) # Get old completed runs diff --git a/mcp/servers/windows/.mokogitea/workflows/codeql-analysis.yml b/mcp/servers/windows/.mokogit/workflows/codeql-analysis.yml similarity index 97% rename from mcp/servers/windows/.mokogitea/workflows/codeql-analysis.yml rename to mcp/servers/windows/.mokogit/workflows/codeql-analysis.yml index 0e4c7353..ed9de887 100644 --- a/mcp/servers/windows/.mokogitea/workflows/codeql-analysis.yml +++ b/mcp/servers/windows/.mokogit/workflows/codeql-analysis.yml @@ -11,7 +11,7 @@ # PATH: /templates/workflows/generic/codeql-analysis.yml.template # VERSION: 04.05.00 # BRIEF: CodeQL security scanning workflow (generic — all repo types) -# NOTE: Deployed to .mokogitea/workflows/codeql-analysis.yml in governed repos. +# NOTE: Deployed to .mokogit/workflows/codeql-analysis.yml in governed repos. # CodeQL does not support PHP directly; JavaScript scans JSON/YAML/shell. # For PHP-specific security scanning see standards-compliance.yml. diff --git a/mcp/servers/windows/.mokogitea/workflows/copilot-agent.yml b/mcp/servers/windows/.mokogit/workflows/copilot-agent.yml similarity index 100% rename from mcp/servers/windows/.mokogitea/workflows/copilot-agent.yml rename to mcp/servers/windows/.mokogit/workflows/copilot-agent.yml diff --git a/mcp/servers/windows/.mokogitea/workflows/deploy-manual.yml b/mcp/servers/windows/.mokogit/workflows/deploy-manual.yml similarity index 91% rename from mcp/servers/windows/.mokogitea/workflows/deploy-manual.yml rename to mcp/servers/windows/.mokogit/workflows/deploy-manual.yml index 62052b66..73d7c0d3 100644 --- a/mcp/servers/windows/.mokogitea/workflows/deploy-manual.yml +++ b/mcp/servers/windows/.mokogit/workflows/deploy-manual.yml @@ -3,7 +3,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later # # FILE INFORMATION -# DEFGROUP: Gitea.Workflow +# DEFGROUP: MokoGit.Workflow # INGROUP: MokoCli.Deploy # REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoCli-API # PATH: /templates/workflows/joomla/deploy-manual.yml.template @@ -42,10 +42,10 @@ jobs: - name: Setup MokoCli tools env: - GA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN || secrets.MOKOGITEA_TOKEN || github.token }} - MOKO_CLONE_TOKEN: ${{ secrets.MOKOGITEA_TOKEN || secrets.MOKOGITEA_TOKEN || github.token }} - MOKO_CLONE_HOST: ${{ secrets.MOKOGITEA_TOKEN && 'git.mokoconsulting.tech/MokoConsulting' || 'github.com/mokoconsulting-tech' }} - COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.MOKOGITEA_TOKEN || github.token }}"}}' + GA_TOKEN: ${{ secrets.MOKOGIT_TOKEN || secrets.MOKOGIT_TOKEN || github.token }} + MOKO_CLONE_TOKEN: ${{ secrets.MOKOGIT_TOKEN || secrets.MOKOGIT_TOKEN || github.token }} + MOKO_CLONE_HOST: ${{ secrets.MOKOGIT_TOKEN && 'git.mokoconsulting.tech/MokoConsulting' || 'github.com/mokoconsulting-tech' }} + COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.MOKOGIT_TOKEN || github.token }}"}}' run: | git clone --depth 1 --branch main --quiet \ "https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/MokoCli-API.git" \ diff --git a/mcp/servers/windows/.mokogitea/workflows/enterprise-firewall-setup.yml b/mcp/servers/windows/.mokogit/workflows/enterprise-firewall-setup.yml similarity index 100% rename from mcp/servers/windows/.mokogitea/workflows/enterprise-firewall-setup.yml rename to mcp/servers/windows/.mokogit/workflows/enterprise-firewall-setup.yml diff --git a/mcp/servers/windows/.mokogitea/workflows/gitleaks.yml b/mcp/servers/windows/.mokogit/workflows/gitleaks.yml similarity index 97% rename from mcp/servers/windows/.mokogitea/workflows/gitleaks.yml rename to mcp/servers/windows/.mokogit/workflows/gitleaks.yml index f6daf0c8..b4ad9be7 100644 --- a/mcp/servers/windows/.mokogitea/workflows/gitleaks.yml +++ b/mcp/servers/windows/.mokogit/workflows/gitleaks.yml @@ -3,7 +3,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later # # FILE INFORMATION -# DEFGROUP: Gitea.Workflow +# DEFGROUP: MokoGit.Workflow # INGROUP: MokoCli.Security # REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/MokoCli-API # PATH: /templates/workflows/gitleaks.yml.template @@ -38,7 +38,7 @@ permissions: env: NTFY_URL: ${{ vars.NTFY_URL || 'https://ntfy.mokoconsulting.tech' }} - NTFY_TOPIC: ${{ vars.NTFY_TOPIC || 'gitea-security' }} + NTFY_TOPIC: ${{ vars.NTFY_TOPIC || 'mokogit-security' }} jobs: gitleaks: diff --git a/mcp/servers/windows/.mokogitea/workflows/mcp-auto-release.yml b/mcp/servers/windows/.mokogit/workflows/mcp-auto-release.yml similarity index 100% rename from mcp/servers/windows/.mokogitea/workflows/mcp-auto-release.yml rename to mcp/servers/windows/.mokogit/workflows/mcp-auto-release.yml diff --git a/mcp/servers/windows/.mokogitea/workflows/mcp-build-test.yml b/mcp/servers/windows/.mokogit/workflows/mcp-build-test.yml similarity index 100% rename from mcp/servers/windows/.mokogitea/workflows/mcp-build-test.yml rename to mcp/servers/windows/.mokogit/workflows/mcp-build-test.yml diff --git a/mcp/servers/windows/.mokogitea/workflows/mcp-sdk-check.yml b/mcp/servers/windows/.mokogit/workflows/mcp-sdk-check.yml similarity index 100% rename from mcp/servers/windows/.mokogitea/workflows/mcp-sdk-check.yml rename to mcp/servers/windows/.mokogit/workflows/mcp-sdk-check.yml diff --git a/mcp/servers/windows/.mokogitea/workflows/mcp-tool-inventory.yml b/mcp/servers/windows/.mokogit/workflows/mcp-tool-inventory.yml similarity index 100% rename from mcp/servers/windows/.mokogitea/workflows/mcp-tool-inventory.yml rename to mcp/servers/windows/.mokogit/workflows/mcp-tool-inventory.yml diff --git a/mcp/servers/windows/.mokogitea/workflows/notify.yml b/mcp/servers/windows/.mokogit/workflows/notify.yml similarity index 94% rename from mcp/servers/windows/.mokogitea/workflows/notify.yml rename to mcp/servers/windows/.mokogit/workflows/notify.yml index 3153b258..ea818575 100644 --- a/mcp/servers/windows/.mokogitea/workflows/notify.yml +++ b/mcp/servers/windows/.mokogit/workflows/notify.yml @@ -3,10 +3,10 @@ # SPDX-License-Identifier: GPL-3.0-or-later # # FILE INFORMATION -# DEFGROUP: Gitea.Workflow +# DEFGROUP: MokoGit.Workflow # INGROUP: MokoCli.Notifications # REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoCli -# PATH: /.mokogitea/workflows/notify.yml +# PATH: /.mokogit/workflows/notify.yml # VERSION: 01.00.00 # BRIEF: Push notifications via ntfy on release success or workflow failure @@ -27,7 +27,7 @@ permissions: env: NTFY_URL: ${{ vars.NTFY_URL || 'https://ntfy.mokoconsulting.tech' }} - NTFY_TOPIC: ${{ vars.NTFY_TOPIC || 'gitea-releases' }} + NTFY_TOPIC: ${{ vars.NTFY_TOPIC || 'mokogit-releases' }} jobs: notify: diff --git a/mcp/servers/windows/.mokogitea/workflows/pr-check.yml b/mcp/servers/windows/.mokogit/workflows/pr-check.yml similarity index 91% rename from mcp/servers/windows/.mokogitea/workflows/pr-check.yml rename to mcp/servers/windows/.mokogit/workflows/pr-check.yml index f232f897..f839da7f 100644 --- a/mcp/servers/windows/.mokogitea/workflows/pr-check.yml +++ b/mcp/servers/windows/.mokogit/workflows/pr-check.yml @@ -3,7 +3,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later # # FILE INFORMATION -# DEFGROUP: Gitea.Workflow +# DEFGROUP: MokoGit.Workflow # INGROUP: MokoCli.CI # REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/MokoCli-API # PATH: /templates/workflows/universal/pr-check.yml.template @@ -165,23 +165,6 @@ jobs: ;; esac - - name: Check update stream format - run: | - PLATFORM="${{ steps.platform.outputs.platform }}" - case "$PLATFORM" in - joomla) - if [ -f "updates.xml" ]; then - if command -v php &> /dev/null; then - php -r "libxml_use_internal_errors(true); \$x = simplexml_load_file('updates.xml'); if(!\$x){foreach(libxml_get_errors() as \$e) echo \$e->message; exit(1);}" || { echo "::error::updates.xml is malformed"; exit 1; } - fi - echo "updates.xml valid" - fi - ;; - dolibarr) - [ -f "update.txt" ] && echo "update.txt present" || echo "::warning::No update.txt" - ;; - esac - - name: Verify package source run: | SOURCE_DIR="src" diff --git a/mcp/servers/windows/.mokogitea/workflows/pre-release.yml b/mcp/servers/windows/.mokogit/workflows/pre-release.yml similarity index 68% rename from mcp/servers/windows/.mokogitea/workflows/pre-release.yml rename to mcp/servers/windows/.mokogit/workflows/pre-release.yml index 26944c1f..c9c88229 100644 --- a/mcp/servers/windows/.mokogitea/workflows/pre-release.yml +++ b/mcp/servers/windows/.mokogit/workflows/pre-release.yml @@ -3,7 +3,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later # # FILE INFORMATION -# DEFGROUP: Gitea.Workflow +# DEFGROUP: MokoGit.Workflow # INGROUP: mokocli.Release # REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli # PATH: /templates/workflows/universal/pre-release.yml.template @@ -29,9 +29,9 @@ permissions: contents: write env: - GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }} - GITEA_ORG: ${{ vars.GITEA_ORG || github.repository_owner }} - GITEA_REPO: ${{ vars.GITEA_REPO || github.event.repository.name }} + MOKOGIT_URL: ${{ vars.MOKOGIT_URL || 'https://git.mokoconsulting.tech' }} + MOKOGIT_ORG: ${{ vars.MOKOGIT_ORG || github.repository_owner }} + MOKOGIT_REPO: ${{ vars.MOKOGIT_REPO || github.event.repository.name }} jobs: build: @@ -43,7 +43,7 @@ jobs: uses: actions/checkout@v4 with: fetch-depth: 0 - token: ${{ secrets.MOKOGITEA_TOKEN }} + token: ${{ secrets.MOKOGIT_TOKEN }} - name: Setup tools run: | @@ -58,7 +58,7 @@ jobs: sudo apt-get install -y -qq php-cli php-mbstring php-xml php-zip php-curl >/dev/null 2>&1 fi git clone --depth 1 --branch main --quiet \ - "https://x-access-token:${{ secrets.MOKOGITEA_TOKEN }}@git.mokoconsulting.tech/MokoConsulting/mokocli.git" \ + "https://x-access-token:${{ secrets.MOKOGIT_TOKEN }}@git.mokoconsulting.tech/MokoConsulting/mokocli.git" \ /tmp/mokocli-api fi # Set MOKO_CLI to whichever path exists @@ -71,7 +71,7 @@ jobs: - name: Detect platform id: platform run: | - PLATFORM=$(sed -n 's/.*\([^<]*\)<\/platform>.*/\1/p' .mokogitea/manifest.xml 2>/dev/null | head -1 | tr -d '[:space:]') + PLATFORM=$(sed -n 's/.*\([^<]*\)<\/platform>.*/\1/p' .mokogit/manifest.xml 2>/dev/null | head -1 | tr -d '[:space:]') [ -z "$PLATFORM" ] && PLATFORM="generic" echo "platform=$PLATFORM" >> "$GITHUB_OUTPUT" MANIFEST=$(find ./src -maxdepth 1 -name "pkg_*.xml" -exec grep -l '/dev/null | head -1) @@ -108,9 +108,9 @@ jobs: --path . --version "$VERSION" --branch "${{ github.ref_name }}" 2>/dev/null || true # Commit version bump - git config --local user.email "gitea-actions[bot]@mokoconsulting.tech" - git config --local user.name "gitea-actions[bot]" - git remote set-url origin "https://jmiller:${{ secrets.MOKOGITEA_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git" + git config --local user.email "mokogit-actions[bot]@mokoconsulting.tech" + git config --local user.name "mokogit-actions[bot]" + git remote set-url origin "https://jmiller:${{ secrets.MOKOGIT_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git" git add -A git diff --cached --quiet || { git commit -m "chore(version): pre-release bump to ${VERSION} [skip ci]" @@ -126,11 +126,11 @@ jobs: if [ -z "$EXT_ELEMENT" ]; then EXT_ELEMENT=$(basename "$MANIFEST" .xml | tr '[:upper:]' '[:lower:]') case "$EXT_ELEMENT" in - templatedetails|manifest) EXT_ELEMENT=$(echo "${GITEA_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -') ;; + templatedetails|manifest) EXT_ELEMENT=$(echo "${MOKOGIT_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -') ;; esac fi else - EXT_ELEMENT=$(echo "${GITEA_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -') + EXT_ELEMENT=$(echo "${MOKOGIT_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -') fi ;; dolibarr) @@ -138,11 +138,11 @@ jobs: MOD_BASENAME=$(basename "$MOD_FILE" .class.php) EXT_ELEMENT=$(echo "$MOD_BASENAME" | sed 's/^mod//' | tr '[:upper:]' '[:lower:]') else - EXT_ELEMENT=$(echo "${GITEA_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -') + EXT_ELEMENT=$(echo "${MOKOGIT_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -') fi ;; *) - EXT_ELEMENT=$(echo "${GITEA_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -') + EXT_ELEMENT=$(echo "${MOKOGIT_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -') ;; esac @@ -216,7 +216,7 @@ jobs: echo "sha256=${SHA256}" >> "$GITHUB_OUTPUT" echo "ZIP: ${ZIP_NAME} (SHA: ${SHA256:0:16}...)" - - name: Create or replace Gitea release + - name: Create or replace MokoGit release id: release run: | TAG="${{ steps.meta.outputs.tag }}" @@ -225,8 +225,8 @@ jobs: SHA256="${{ steps.zip.outputs.sha256 }}" ZIP_NAME="${{ steps.meta.outputs.zip_name }}" EXT_ELEMENT="${{ steps.meta.outputs.ext_element }}" - TOKEN="${{ secrets.MOKOGITEA_TOKEN }}" - API="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" + TOKEN="${{ secrets.MOKOGIT_TOKEN }}" + API="${MOKOGIT_URL}/api/v1/repos/${MOKOGIT_ORG}/${MOKOGIT_REPO}" BRANCH=$(git branch --show-current) BODY="## ${VERSION} ($(date +%Y-%m-%d)) @@ -265,93 +265,11 @@ jobs: echo "Released: ${EXT_ELEMENT} ${VERSION} (${STABILITY})" - - name: Update updates.xml - if: steps.platform.outputs.platform == 'joomla' - run: | - STABILITY="${{ steps.meta.outputs.stability }}" - VERSION="${{ steps.meta.outputs.version }}" - SHA256="${{ steps.zip.outputs.sha256 }}" - ZIP_NAME="${{ steps.meta.outputs.zip_name }}" - TAG="${{ steps.meta.outputs.tag }}" - - if [ ! -f "updates.xml" ]; then - echo "No updates.xml -- skipping" - exit 0 - fi - - # Map stability to XML tag name - case "$STABILITY" in - development) XML_TAG="development" ;; - alpha) XML_TAG="alpha" ;; - beta) XML_TAG="beta" ;; - release-candidate) XML_TAG="rc" ;; - *) XML_TAG="$STABILITY" ;; - esac - - DOWNLOAD_URL="${GITEA_URL}/${GITEA_ORG}/${GITEA_REPO}/releases/download/${TAG}/${ZIP_NAME}" - - # Use PHP to update the channel in updates.xml - php -r ' - $xml_tag = $argv[1]; - $version = $argv[2]; - $sha256 = $argv[3]; - $url = $argv[4]; - $date = date("Y-m-d"); - - $content = file_get_contents("updates.xml"); - $pattern = "/((?:(?!<\/update>).)*?" . preg_quote($xml_tag) . "<\/tag>.*?<\/update>)/s"; - - $content = preg_replace_callback($pattern, function($m) use ($version, $sha256, $url, $date) { - $block = $m[0]; - $block = preg_replace("/[^<]*<\/version>/", "{$version}", $block); - if (strpos($block, "") !== false) { - $block = preg_replace("/[^<]*<\/sha256>/", "{$sha256}", $block); - } else { - $block = str_replace("", "\n {$sha256}", $block); - } - $block = preg_replace("/(]*>)[^<]*(<\/downloadurl>)/", "\${1}{$url}\${2}", $block); - return $block; - }, $content); - - file_put_contents("updates.xml", $content); - echo "Updated {$xml_tag} channel: version={$version}\n"; - ' "$XML_TAG" "$VERSION" "$SHA256" "$DOWNLOAD_URL" - - # Commit and push - 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 add updates.xml - git commit -m "chore: update ${STABILITY} channel ${VERSION} [skip ci]" - git push origin HEAD 2>&1 || echo "WARNING: push failed" - fi - - - name: "Sync updates.xml to all branches" - if: steps.platform.outputs.platform == 'joomla' - run: | - CURRENT_BRANCH="${{ github.ref_name }}" - git config --local user.email "gitea-actions[bot]@mokoconsulting.tech" - git config --local user.name "gitea-actions[bot]" - - for BRANCH in main dev; do - [ "$BRANCH" = "$CURRENT_BRANCH" ] && continue - echo "Syncing updates.xml -> ${BRANCH}" - git fetch origin "${BRANCH}" 2>/dev/null || continue - git checkout "origin/${BRANCH}" -- . 2>/dev/null || continue - git checkout "${CURRENT_BRANCH}" -- updates.xml - if ! git diff --quiet updates.xml 2>/dev/null; then - git add updates.xml - git commit -m "chore: sync updates.xml from ${CURRENT_BRANCH} [skip ci]" - git push origin HEAD:refs/heads/${BRANCH} 2>&1 || echo "WARNING: push to ${BRANCH} failed" - fi - git checkout "${CURRENT_BRANCH}" 2>/dev/null - done - - name: "Delete lesser pre-release channels (cascade)" continue-on-error: true run: | - API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" - TOKEN="${{ secrets.MOKOGITEA_TOKEN }}" + API_BASE="${MOKOGIT_URL}/api/v1/repos/${MOKOGIT_ORG}/${MOKOGIT_REPO}" + TOKEN="${{ secrets.MOKOGIT_TOKEN }}" php ${MOKO_CLI}/release_cascade.php \ --stability "${{ steps.meta.outputs.stability }}" \ diff --git a/mcp/servers/windows/.mokogitea/workflows/repo-health.yml b/mcp/servers/windows/.mokogit/workflows/repo-health.yml similarity index 98% rename from mcp/servers/windows/.mokogitea/workflows/repo-health.yml rename to mcp/servers/windows/.mokogit/workflows/repo-health.yml index d57b58f3..181f5420 100644 --- a/mcp/servers/windows/.mokogitea/workflows/repo-health.yml +++ b/mcp/servers/windows/.mokogit/workflows/repo-health.yml @@ -6,7 +6,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later # # FILE INFORMATION -# DEFGROUP: Gitea.Workflow +# DEFGROUP: MokoGit.Workflow # INGROUP: MokoCli.Validation # REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/MokoCli-API # PATH: /templates/workflows/joomla/repo_health.yml.template @@ -53,7 +53,7 @@ env: SCRIPTS_ALLOWED_DIRS: scripts,scripts/fix,scripts/lib,scripts/release,scripts/run,scripts/validate # Repo health policy - REPO_REQUIRED_ARTIFACTS: README.md,LICENSE,CHANGELOG.md,CONTRIBUTING.md,CODE_OF_CONDUCT.md,.gitea/workflows/ + REPO_REQUIRED_ARTIFACTS: README.md,LICENSE,CHANGELOG.md,CONTRIBUTING.md,CODE_OF_CONDUCT.md,.mokogit/workflows/ REPO_OPTIONAL_FILES: SECURITY.md,GOVERNANCE.md,.editorconfig,.gitattributes,.gitignore,README.md,docs/ REPO_DISALLOWED_DIRS: REPO_DISALLOWED_FILES: TODO.md,todo.md @@ -64,7 +64,7 @@ env: # File / directory variables DOCS_INDEX: docs/docs-index.md SCRIPT_DIR: scripts - WORKFLOWS_DIR: .gitea/workflows + WORKFLOWS_DIR: .mokogit/workflows SHELLCHECK_PATTERN: '*.sh' SPDX_FILE_GLOBS: '*.sh,*.php,*.js,*.ts,*.css,*.xml,*.yml,*.yaml' FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true @@ -85,7 +85,7 @@ jobs: - name: Check actor permission (admin only) id: perm env: - TOKEN: ${{ secrets.MOKOGITEA_TOKEN || secrets.MOKOGITEA_TOKEN || github.token }} + TOKEN: ${{ secrets.MOKOGIT_TOKEN || secrets.MOKOGIT_TOKEN || github.token }} REPO: ${{ github.repository }} ACTOR: ${{ github.actor }} run: | @@ -96,14 +96,14 @@ jobs: # Hardcoded authorized users — always allowed case "$ACTOR" in - jmiller|gitea-actions[bot]) + jmiller|mokogit-actions[bot]) ALLOWED=true PERMISSION=admin METHOD="hardcoded allowlist" ;; *) # Detect platform and check permissions via API - API_BASE="${GITHUB_API_URL:-${GITEA_API_URL:-https://api.github.com}}" + API_BASE="${GITHUB_API_URL:-${MOKOGIT_API_URL:-https://api.github.com}}" RESP=$(curl -sf -H "Authorization: token ${TOKEN}" \ "${API_BASE}/repos/${REPO}/collaborators/${ACTOR}/permission" 2>/dev/null || echo '{}') PERMISSION=$(echo "$RESP" | grep -oP '"permission"\s*:\s*"\K[^"]+' || echo "unknown") @@ -574,10 +574,6 @@ jobs: joomla_findings+=("No .ini language files found") fi - if [ ! -f 'updates.xml' ]; then - joomla_findings+=("updates.xml missing in root (required for Joomla update server)") - fi - INDEX_DIRS=("${SOURCE_DIR}" "${SOURCE_DIR}/admin" "${SOURCE_DIR}/site") for dir in "${INDEX_DIRS[@]}"; do if [ -d "${dir}" ] && [ ! -f "${dir}/index.html" ]; then diff --git a/mcp/servers/mokosuite_api/.mokogitea/workflows/repository-cleanup.yml b/mcp/servers/windows/.mokogit/workflows/repository-cleanup.yml similarity index 99% rename from mcp/servers/mokosuite_api/.mokogitea/workflows/repository-cleanup.yml rename to mcp/servers/windows/.mokogit/workflows/repository-cleanup.yml index 0468b176..bce1b895 100644 --- a/mcp/servers/mokosuite_api/.mokogitea/workflows/repository-cleanup.yml +++ b/mcp/servers/windows/.mokogit/workflows/repository-cleanup.yml @@ -11,7 +11,7 @@ # PATH: /templates/workflows/shared/repository-cleanup.yml.template # VERSION: 04.06.00 # BRIEF: Recurring repository maintenance — labels, branches, workflows, logs, doc indexes -# NOTE: Synced via bulk-repo-sync to .mokogitea/workflows/repository-cleanup.yml in all governed repos. +# NOTE: Synced via bulk-repo-sync to .mokogit/workflows/repository-cleanup.yml in all governed repos. # Runs on the 1st and 15th of each month at 6:00 AM UTC, and on manual dispatch. name: "Universal: Repository Cleanup" diff --git a/mcp/servers/windows/.mokogitea/workflows/security-audit.yml b/mcp/servers/windows/.mokogit/workflows/security-audit.yml similarity index 94% rename from mcp/servers/windows/.mokogitea/workflows/security-audit.yml rename to mcp/servers/windows/.mokogit/workflows/security-audit.yml index 71fd244a..02104efe 100644 --- a/mcp/servers/windows/.mokogitea/workflows/security-audit.yml +++ b/mcp/servers/windows/.mokogit/workflows/security-audit.yml @@ -3,10 +3,10 @@ # SPDX-License-Identifier: GPL-3.0-or-later # # FILE INFORMATION -# DEFGROUP: Gitea.Workflow +# DEFGROUP: MokoGit.Workflow # INGROUP: MokoCli.Security # REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoCli -# PATH: /.mokogitea/workflows/security-audit.yml +# PATH: /.mokogit/workflows/security-audit.yml # VERSION: 01.00.00 # BRIEF: Dependency vulnerability scanning for composer and npm packages @@ -30,7 +30,7 @@ permissions: env: NTFY_URL: ${{ vars.NTFY_URL || 'https://ntfy.mokoconsulting.tech' }} - NTFY_TOPIC: ${{ vars.NTFY_TOPIC || 'gitea-security' }} + NTFY_TOPIC: ${{ vars.NTFY_TOPIC || 'mokogit-security' }} jobs: audit: diff --git a/mcp/servers/windows/.mokogitea/workflows/standards-compliance.yml b/mcp/servers/windows/.mokogit/workflows/standards-compliance.yml similarity index 99% rename from mcp/servers/windows/.mokogitea/workflows/standards-compliance.yml rename to mcp/servers/windows/.mokogit/workflows/standards-compliance.yml index 77741610..19197e37 100644 --- a/mcp/servers/windows/.mokogitea/workflows/standards-compliance.yml +++ b/mcp/servers/windows/.mokogit/workflows/standards-compliance.yml @@ -4,7 +4,7 @@ # DEFGROUP: GitHub.Workflow # INGROUP: MokoCli.Compliance # REPO: https://github.com/mokoconsulting-tech/MokoCli -# PATH: /.mokogitea/workflows/standards-compliance.yml +# PATH: /.mokogit/workflows/standards-compliance.yml # VERSION: 04.06.00 # BRIEF: MokoCli compliance validation workflow # NOTE: Validates repository structure, documentation, and coding standards diff --git a/mcp/servers/mokosuite_api/.mokogitea/workflows/sync-version-on-merge.yml b/mcp/servers/windows/.mokogit/workflows/sync-version-on-merge.yml similarity index 97% rename from mcp/servers/mokosuite_api/.mokogitea/workflows/sync-version-on-merge.yml rename to mcp/servers/windows/.mokogit/workflows/sync-version-on-merge.yml index a3238bdb..af1a686d 100644 --- a/mcp/servers/mokosuite_api/.mokogitea/workflows/sync-version-on-merge.yml +++ b/mcp/servers/windows/.mokogit/workflows/sync-version-on-merge.yml @@ -11,7 +11,7 @@ # PATH: /templates/workflows/shared/sync-version-on-merge.yml.template # VERSION: 04.06.00 # BRIEF: Auto-bump patch version on every push to main and propagate to all file headers -# NOTE: Synced via bulk-repo-sync to .mokogitea/workflows/sync-version-on-merge.yml in all governed repos. +# NOTE: Synced via bulk-repo-sync to .mokogit/workflows/sync-version-on-merge.yml in all governed repos. # README.md is the single source of truth for the repository version. name: "Universal: Sync Version on Merge" diff --git a/mcp/src/config.ts b/mcp/src/config.ts index 430030a0..1abfc8df 100644 --- a/mcp/src/config.ts +++ b/mcp/src/config.ts @@ -36,8 +36,8 @@ export async function loadConfig(): Promise { return { apiPath: resolve(parsed.apiPath), standardsPath: parsed.standardsPath ? resolve(parsed.standardsPath) : undefined, - giteaUrl: parsed.giteaUrl, - giteaToken: parsed.giteaToken, + mokogitUrl: parsed.mokogitUrl, + mokogitToken: parsed.mokogitToken, }; } catch (err) { // Auto-detect: if running from within MokoCli-API/mcp/dist/, resolve parent diff --git a/mcp/src/index.ts b/mcp/src/index.ts index 80f53ecf..247716ed 100644 --- a/mcp/src/index.ts +++ b/mcp/src/index.ts @@ -414,7 +414,7 @@ server.tool( server.tool( 'standards_sync_wikis', - 'Sync Gitea wiki repos to their GitHub mirrors. Optionally filter by repo name.', + 'Sync MokoGit wiki repos to their GitHub mirrors. Optionally filter by repo name.', { repo: z.string().optional().describe('Filter to a specific repo name (e.g. "MokoOnyx"). Omit to sync all.'), }, diff --git a/mcp/src/types.ts b/mcp/src/types.ts index 78a445bb..5a3f5aff 100644 --- a/mcp/src/types.ts +++ b/mcp/src/types.ts @@ -17,10 +17,10 @@ export interface StandardsConfig { apiPath: string; /** Path to MokoCli root (contains docs/) */ standardsPath?: string; - /** Gitea API base URL */ - giteaUrl?: string; - /** Gitea API token (for repo queries) */ - giteaToken?: string; + /** MokoGit API base URL */ + mokogitUrl?: string; + /** MokoGit API token (for repo queries) */ + mokogitToken?: string; } export interface ExecResult { diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 9bf9bce9..690a4fe7 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -271,7 +271,7 @@ parameters: path: cli/client_inventory.php - - message: '#^Method ClientProvision\:\:giteaApi\(\) return type has no value type specified in iterable type array\.$#' + message: '#^Method ClientProvision\:\:mokogitApi\(\) return type has no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 path: cli/client_provision.php @@ -367,7 +367,7 @@ parameters: path: cli/release_manage.php - - message: '#^Function releaseGiteaApi\(\) return type has no value type specified in iterable type array\.$#' + message: '#^Function releaseMokoGitApi\(\) return type has no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 path: cli/release_manage.php @@ -415,25 +415,7 @@ parameters: path: cli/theme_lint.php - - message: '#^Offset ''alpha''\|''beta''\|''development''\|''rc''\|''stable'' on array\{stable\: ''stable'', rc\: ''rc'', beta\: ''beta'', alpha\: ''alpha'', development\: ''dev''\} on left side of \?\? always exists and is not nullable\.$#' - identifier: nullCoalesce.offset - count: 2 - path: cli/updates_xml_build.php - - - - message: '#^Function apiCall\(\) has parameter \$data with no value type specified in iterable type array\.$#' - identifier: missingType.iterableValue - count: 1 - path: cli/updates_xml_sync.php - - - - message: '#^Function apiCall\(\) return type has no value type specified in iterable type array\.$#' - identifier: missingType.iterableValue - count: 1 - path: cli/updates_xml_sync.php - - - - message: '#^Function giteaApi\(\) return type has no value type specified in iterable type array\.$#' + message: '#^Function mokogitApi\(\) return type has no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 path: cli/version_bump_remote.php @@ -772,7 +754,7 @@ parameters: message: '#^Call to function is_int\(\) with string will always evaluate to false\.$#' identifier: function.impossibleType count: 1 - path: lib/Enterprise/MokoGiteaAdapter.php + path: lib/Enterprise/MokoGitAdapter.php - message: '#^Method MokoCli\\MokoCliParser\:\:generate\(\) has parameter \$params with no value type specified in iterable type array\.$#' diff --git a/scripts/cleanup-claude-dirs.sh b/scripts/cleanup-claude-dirs.sh index 52905d2d..fb52f924 100644 --- a/scripts/cleanup-claude-dirs.sh +++ b/scripts/cleanup-claude-dirs.sh @@ -3,7 +3,7 @@ # # .claude/ is local workspace config (MCP settings, worktrees) and should # never be committed. This script: -# 1. Checks if .claude/ exists in the repo via Gitea API +# 1. Checks if .claude/ exists in the repo via MokoGit API # 2. Deletes all files in .claude/ via API # 3. Ensures .claude/ is in .gitignore # @@ -13,11 +13,11 @@ # set -euo pipefail -GITEA_URL="${GITEA_URL:-https://git.mokoconsulting.tech}" -GITEA_TOKEN="${GITEA_TOKEN:-$(cat ~/.gitea-token 2>/dev/null || echo "")}" +MOKOGIT_URL="${MOKOGIT_URL:-https://git.mokoconsulting.tech}" +MOKOGIT_TOKEN="${MOKOGIT_TOKEN:-$(cat ~/.mokogit-token 2>/dev/null || echo "")}" -if [[ -z "$GITEA_TOKEN" ]]; then - echo "ERROR: GITEA_TOKEN not set" +if [[ -z "$MOKOGIT_TOKEN" ]]; then + echo "ERROR: MOKOGIT_TOKEN not set" exit 1 fi @@ -32,8 +32,8 @@ get_repos() { for ORG in MokoConsulting ClarksvilleFurs; do PAGE=1 while true; do - REPOS=$(curl -sf -H "Authorization: token ${GITEA_TOKEN}" \ - "${GITEA_URL}/api/v1/orgs/${ORG}/repos?page=${PAGE}&limit=50" 2>/dev/null) + REPOS=$(curl -sf -H "Authorization: token ${MOKOGIT_TOKEN}" \ + "${MOKOGIT_URL}/api/v1/orgs/${ORG}/repos?page=${PAGE}&limit=50" 2>/dev/null) [[ -z "$REPOS" || "$REPOS" == "[]" ]] && break echo "$REPOS" | python3 -c " @@ -60,8 +60,8 @@ while IFS='|' read -r FULL_NAME BRANCH; do fi # Check if .claude/ exists in the repo - CLAUDE_DIR=$(curl -sf -H "Authorization: token ${GITEA_TOKEN}" \ - "${GITEA_URL}/api/v1/repos/${FULL_NAME}/contents/.claude?ref=${BRANCH}" 2>/dev/null) + CLAUDE_DIR=$(curl -sf -H "Authorization: token ${MOKOGIT_TOKEN}" \ + "${MOKOGIT_URL}/api/v1/repos/${FULL_NAME}/contents/.claude?ref=${BRANCH}" 2>/dev/null) if [[ -z "$CLAUDE_DIR" || "$CLAUDE_DIR" == "null" ]]; then SKIPPED=$((SKIPPED + 1)) @@ -88,9 +88,9 @@ elif isinstance(data, dict) and data.get('type') == 'file': ENCODED_PATH=$(python3 -c "import urllib.parse; print(urllib.parse.quote('${FILE_PATH}', safe='/'))" 2>/dev/null) RESULT=$(curl -sf -X DELETE \ - -H "Authorization: token ${GITEA_TOKEN}" \ + -H "Authorization: token ${MOKOGIT_TOKEN}" \ -H "Content-Type: application/json" \ - "${GITEA_URL}/api/v1/repos/${FULL_NAME}/contents/${ENCODED_PATH}" \ + "${MOKOGIT_URL}/api/v1/repos/${FULL_NAME}/contents/${ENCODED_PATH}" \ -d "{\"sha\": \"${FILE_SHA}\", \"message\": \"chore: remove .claude/ from version control [skip ci]\", \"branch\": \"${BRANCH}\"}" \ -w "%{http_code}" -o /dev/null 2>&1) @@ -102,16 +102,16 @@ elif isinstance(data, dict) and data.get('type') == 'file': done <<< "$FILES" # Also check for .mcp.json - MCP_JSON=$(curl -sf -H "Authorization: token ${GITEA_TOKEN}" \ - "${GITEA_URL}/api/v1/repos/${FULL_NAME}/contents/.mcp.json?ref=${BRANCH}" 2>/dev/null) + MCP_JSON=$(curl -sf -H "Authorization: token ${MOKOGIT_TOKEN}" \ + "${MOKOGIT_URL}/api/v1/repos/${FULL_NAME}/contents/.mcp.json?ref=${BRANCH}" 2>/dev/null) if [[ -n "$MCP_JSON" && "$MCP_JSON" != "null" ]]; then MCP_SHA=$(echo "$MCP_JSON" | python3 -c "import sys,json; print(json.load(sys.stdin).get('sha',''))" 2>/dev/null) if [[ -n "$MCP_SHA" ]]; then RESULT=$(curl -sf -X DELETE \ - -H "Authorization: token ${GITEA_TOKEN}" \ + -H "Authorization: token ${MOKOGIT_TOKEN}" \ -H "Content-Type: application/json" \ - "${GITEA_URL}/api/v1/repos/${FULL_NAME}/contents/.mcp.json" \ + "${MOKOGIT_URL}/api/v1/repos/${FULL_NAME}/contents/.mcp.json" \ -d "{\"sha\": \"${MCP_SHA}\", \"message\": \"chore: remove .mcp.json from version control [skip ci]\", \"branch\": \"${BRANCH}\"}" \ -w "%{http_code}" -o /dev/null 2>&1) [[ "$RESULT" == "200" ]] && log " Deleted: .mcp.json" diff --git a/scripts/sync-wikis-to-github.sh b/scripts/sync-wikis-to-github.sh index e1f7f8f9..9f9e539b 100644 --- a/scripts/sync-wikis-to-github.sh +++ b/scripts/sync-wikis-to-github.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash -# sync-wikis-to-github.sh — Export all Gitea wikis to a consolidated GitHub repo +# sync-wikis-to-github.sh — Export all MokoGit wikis to a consolidated GitHub repo # -# Clones each Gitea wiki, copies pages into project-named subdirectories, +# Clones each MokoGit wiki, copies pages into project-named subdirectories, # and pushes to mokoconsulting-tech/wiki on GitHub. # # Structure: @@ -21,7 +21,7 @@ # set -euo pipefail -GITEA_URL="${GITEA_URL:-https://git.mokoconsulting.tech}" +MOKOGIT_URL="${MOKOGIT_URL:-https://git.mokoconsulting.tech}" GITHUB_ORG="${GITHUB_ORG:-mokoconsulting-tech}" GITHUB_WIKI_REPO="${GITHUB_WIKI_REPO:-wiki}" GH_TOKEN="${GH_TOKEN:-$(cat ~/.github-token 2>/dev/null || echo "")}" @@ -35,17 +35,17 @@ if [[ -z "$GH_TOKEN" ]]; then exit 1 fi -# Auto-discover repos with wikis from Gitea API -GITEA_TOKEN="${GITEA_TOKEN:-$(cat ~/.gitea-token 2>/dev/null || echo "")}" +# Auto-discover repos with wikis from MokoGit API +MOKOGIT_TOKEN="${MOKOGIT_TOKEN:-$(cat ~/.mokogit-token 2>/dev/null || echo "")}" declare -A REPOS=() -if [[ -n "$GITEA_TOKEN" ]]; then +if [[ -n "$MOKOGIT_TOKEN" ]]; then log "Auto-discovering repos with wikis..." for ORG in MokoConsulting ClarksvilleFurs; do PAGE=1 while true; do - RESPONSE=$(curl -sf -H "Authorization: token ${GITEA_TOKEN}" \ - "${GITEA_URL}/api/v1/orgs/${ORG}/repos?page=${PAGE}&limit=50" 2>/dev/null) + RESPONSE=$(curl -sf -H "Authorization: token ${MOKOGIT_TOKEN}" \ + "${MOKOGIT_URL}/api/v1/orgs/${ORG}/repos?page=${PAGE}&limit=50" 2>/dev/null) [[ -z "$RESPONSE" || "$RESPONSE" == "[]" ]] && break REPO_LIST=$(echo "$RESPONSE" | python3 -c " @@ -96,23 +96,23 @@ git clone --quiet "https://${GH_TOKEN}@github.com/${GITHUB_ORG}/${GITHUB_WIKI_RE } cd "$WIKI_DIR" -git config user.email "gitea-actions[bot]@mokoconsulting.tech" -git config user.name "gitea-actions[bot]" +git config user.email "mokogit-actions[bot]@mokoconsulting.tech" +git config user.name "mokogit-actions[bot]" SYNCED=0 -for GITEA_REPO in "${!REPOS[@]}"; do - PROJECT="${REPOS[$GITEA_REPO]}" +for MOKOGIT_REPO in "${!REPOS[@]}"; do + PROJECT="${REPOS[$MOKOGIT_REPO]}" - if [[ -n "$FILTER" && "$PROJECT" != "$FILTER" && "$GITEA_REPO" != *"$FILTER"* ]]; then + if [[ -n "$FILTER" && "$PROJECT" != "$FILTER" && "$MOKOGIT_REPO" != *"$FILTER"* ]]; then continue fi - log "Exporting wiki: ${GITEA_REPO} → ${PROJECT}/" + log "Exporting wiki: ${MOKOGIT_REPO} → ${PROJECT}/" - # Clone Gitea wiki + # Clone MokoGit wiki WIKI_CLONE="${TMPDIR}/${PROJECT}.wiki" - if ! git clone --quiet "${GITEA_URL}/${GITEA_REPO}.wiki.git" "$WIKI_CLONE" 2>/dev/null; then + if ! git clone --quiet "${MOKOGIT_URL}/${MOKOGIT_REPO}.wiki.git" "$WIKI_CLONE" 2>/dev/null; then log " SKIP: no wiki" continue fi @@ -137,9 +137,9 @@ done cat > "${WIKI_DIR}/README.md" << 'HEADER' # Moko Consulting — Wiki Archive -Consolidated backup of all project wikis from [Gitea](https://git.mokoconsulting.tech). +Consolidated backup of all project wikis from [MokoGit](https://git.mokoconsulting.tech). -> **Source of truth:** Gitea wikis. This repo is a read-only mirror. +> **Source of truth:** MokoGit wikis. This repo is a read-only mirror. ## Projects @@ -157,7 +157,7 @@ echo "*Last synced: $(date -u '+%Y-%m-%d %H:%M UTC')*" >> "${WIKI_DIR}/README.md # Commit and push git add -A if ! git diff --cached --quiet 2>/dev/null; then - git commit --quiet -m "docs: sync wikis from Gitea ($(date -u '+%Y-%m-%d %H:%M UTC'))" + git commit --quiet -m "docs: sync wikis from MokoGit ($(date -u '+%Y-%m-%d %H:%M UTC'))" git push --force origin HEAD:main 2>&1 | tail -3 log "Pushed to ${GITHUB_ORG}/${GITHUB_WIKI_REPO}" else diff --git a/templates/client-provision-example.json b/templates/client-provision-example.json index 39bbfa96..bb4efb85 100644 --- a/templates/client-provision-example.json +++ b/templates/client-provision-example.json @@ -1,7 +1,7 @@ { "name": "exampleclient", "org": "ExampleClient", - "gitea_url": "https://git.mokoconsulting.tech", + "mokogit_url": "https://git.mokoconsulting.tech", "variables": { "DEV_SYNC_HOST": "dev.exampleclient.com", diff --git a/templates/configs/manifest.xml.template b/templates/configs/manifest.xml.template index 58326ca4..8aefd116 100644 --- a/templates/configs/manifest.xml.template +++ b/templates/configs/manifest.xml.template @@ -7,7 +7,7 @@ INGROUP: MokoPlatform.Templates REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli PATH: /templates/configs/manifest.xml.template - BRIEF: XML manifest template — synced to .mokogitea/manifest.xml in every governed repository + BRIEF: XML manifest template — synced to .mokogit/manifest.xml in every governed repository NOTE: This template is a reference only. The bulk sync generates XML via MokoCliParser::generate(). mokocli Repository Manifest diff --git a/templates/configs/manifest.yml.template b/templates/configs/manifest.yml.template index e712a252..714493ae 100644 --- a/templates/configs/manifest.yml.template +++ b/templates/configs/manifest.yml.template @@ -5,7 +5,7 @@ # INGROUP: MokoPlatform.Templates # REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli # PATH: /templates/configs/manifest.yml.template -# BRIEF: Governance attachment template — synced to .mokogitea/manifest.xml in every governed repository +# BRIEF: Governance attachment template — synced to .mokogit/manifest.xml in every governed repository # NOTE: Tokens replaced at sync time: {{org}}, {{repo_name}}, {{platform}}, {{standards_version}} # # This file is managed automatically by mokocli bulk sync. diff --git a/templates/configs/mokostandards.xml.template b/templates/configs/mokostandards.xml.template index ed72e27e..8c459988 100644 --- a/templates/configs/mokostandards.xml.template +++ b/templates/configs/mokostandards.xml.template @@ -7,7 +7,7 @@ INGROUP: MokoPlatform.Templates REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli PATH: /templates/configs/manifest.xml.template - BRIEF: XML manifest template — synced to .mokogitea/manifest.xml in every governed repository + BRIEF: XML manifest template — synced to .mokogit/manifest.xml in every governed repository NOTE: This template is a reference only. The bulk sync generates XML via MokoCliParser::generate(). mokocli Repository Manifest diff --git a/templates/docs/required/CODEOWNERS b/templates/docs/required/CODEOWNERS index 630df710..58884b8e 100644 --- a/templates/docs/required/CODEOWNERS +++ b/templates/docs/required/CODEOWNERS @@ -19,10 +19,10 @@ /api/ @mokoconsulting-tech # CI/CD WORKFLOWS -/.mokogitea/workflows/ @mokoconsulting-tech +/.mokogit/workflows/ @mokoconsulting-tech # ISSUE TEMPLATES -/.mokogitea/ISSUE_TEMPLATE/ @mokoconsulting-tech +/.mokogit/ISSUE_TEMPLATE/ @mokoconsulting-tech # GOVERNANCE + OPERATIONAL FILES /CONTRIBUTING.md @mokoconsulting-tech diff --git a/templates/docs/required/template-CONTRIBUTING.md b/templates/docs/required/template-CONTRIBUTING.md index b1dc0a8d..b1755649 100644 --- a/templates/docs/required/template-CONTRIBUTING.md +++ b/templates/docs/required/template-CONTRIBUTING.md @@ -109,10 +109,10 @@ All contributions must follow [mokocli](https://git.mokoconsulting.tech/MokoCons ## Custom Workflows -Place repo-specific workflows in `.mokogitea/workflows/custom/` — they are **never overwritten or deleted** by mokocli sync: +Place repo-specific workflows in `.mokogit/workflows/custom/` — they are **never overwritten or deleted** by mokocli sync: ``` -.mokogitea/workflows/ +.mokogit/workflows/ ├── deploy-dev.yml ← Synced from mokocli ├── auto-release.yml ← Synced from mokocli └── custom/ ← Your custom workflows (safe) diff --git a/templates/governance.yml b/templates/governance.yml index 5a9925e9..5286faeb 100644 --- a/templates/governance.yml +++ b/templates/governance.yml @@ -56,7 +56,7 @@ labels: secrets: - name: GA_TOKEN - description: "Gitea API token for automation" + description: "MokoGit API token for automation" required: true scope: org - name: GH_TOKEN @@ -65,12 +65,12 @@ secrets: scope: org variables: - - name: GITEA_URL - description: "Gitea instance URL" + - name: MOKOGIT_URL + description: "MokoGit instance URL" default: "https://git.mokoconsulting.tech" scope: org - - name: GITEA_ORG - description: "Gitea organization name" + - name: MOKOGIT_ORG + description: "MokoGit organization name" default: "MokoConsulting" scope: org diff --git a/templates/mokogitea/CLAUDE.dolibarr.md.template b/templates/mokogit/CLAUDE.dolibarr.md.template similarity index 98% rename from templates/mokogitea/CLAUDE.dolibarr.md.template rename to templates/mokogit/CLAUDE.dolibarr.md.template index 708901df..5e29f8fa 100644 --- a/templates/mokogitea/CLAUDE.dolibarr.md.template +++ b/templates/mokogit/CLAUDE.dolibarr.md.template @@ -9,10 +9,10 @@ SPDX-License-Identifier: GPL-3.0-or-later DEFGROUP: MokoPlatform.Templates.GitHub INGROUP: MokoPlatform.Templates REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli -PATH: /templates/mokogitea/CLAUDE.dolibarr.md.template +PATH: /templates/mokogit/CLAUDE.dolibarr.md.template VERSION: XX.YY.ZZ BRIEF: Claude AI assistant context template for Dolibarr/MokoCRM module repositories -NOTE: Synced to .gitea/CLAUDE.md in all Dolibarr/CRM repos via bulk sync. +NOTE: Synced to .mokogit/CLAUDE.md in all Dolibarr/CRM repos via bulk sync. Tokens replaced at sync time: {{REPO_NAME}}, {{REPO_URL}}, {{MODULE_NAME}}, {{MODULE_CLASS}}, {{MODULE_ID}}, {{REPO_DESCRIPTION}} --> @@ -28,7 +28,7 @@ NOTE: Synced to .gitea/CLAUDE.md in all Dolibarr/CRM repos via bulk sync. > > 1. Check whether any `{{TOKEN}}` placeholders remain in this file. > 2. If they do, locate the values as described in the table below and replace every occurrence -> in **both** `.gitea/copilot-instructions.md` and `.gitea/CLAUDE.md`. +> in **both** `.mokogit/copilot-instructions.md` and `.mokogit/CLAUDE.md`. > 3. After replacing all tokens, **delete this entire notice block** (from `> [!IMPORTANT]` > through the closing `> ---` line) in both files. > 4. Tell the developer: *"I've self-updated the AI context files with this repository's @@ -88,7 +88,7 @@ This repository is governed by [mokocli](https://git.mokoconsulting.tech/MokoCon ├── tests/ # Test suite │ ├── unit/ │ └── integration/ -├── .gitea/ +├── .mokogit/ │ ├── workflows/ # CI/CD workflows (synced from mokocli) │ ├── copilot-instructions.md │ └── CLAUDE.md # This file diff --git a/templates/mokogitea/CLAUDE.joomla.md.template b/templates/mokogit/CLAUDE.joomla.md.template similarity index 76% rename from templates/mokogitea/CLAUDE.joomla.md.template rename to templates/mokogit/CLAUDE.joomla.md.template index ac67dac8..653ea587 100644 --- a/templates/mokogitea/CLAUDE.joomla.md.template +++ b/templates/mokogit/CLAUDE.joomla.md.template @@ -9,10 +9,10 @@ SPDX-License-Identifier: GPL-3.0-or-later DEFGROUP: MokoPlatform.Templates.GitHub INGROUP: MokoPlatform.Templates REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli -PATH: /templates/mokogitea/CLAUDE.joomla.md.template +PATH: /templates/mokogit/CLAUDE.joomla.md.template VERSION: XX.YY.ZZ BRIEF: Claude AI assistant context template for Joomla/MokoWaaS governed repositories -NOTE: Synced to .gitea/CLAUDE.md in all Joomla/WaaS repos via bulk sync. +NOTE: Synced to .mokogit/CLAUDE.md in all Joomla/WaaS repos via bulk sync. Tokens replaced at sync time: {{REPO_NAME}}, {{REPO_URL}}, {{EXTENSION_NAME}}, {{EXTENSION_TYPE}}, {{EXTENSION_ELEMENT}}, {{REPO_DESCRIPTION}} --> @@ -28,7 +28,7 @@ NOTE: Synced to .gitea/CLAUDE.md in all Joomla/WaaS repos via bulk sync. > > 1. Check whether any `{{TOKEN}}` placeholders remain in this file. > 2. If they do, locate the values as described in the table below and replace every occurrence -> in **both** `.gitea/copilot-instructions.md` and `.gitea/CLAUDE.md`. +> in **both** `.mokogit/copilot-instructions.md` and `.mokogit/CLAUDE.md`. > 3. After replacing all tokens, **delete this entire notice block** (from `> [!IMPORTANT]` > through the closing `> ---` line) in both files. > 4. Tell the developer: *"I've self-updated the AI context files with this repository's @@ -64,7 +64,6 @@ This repository is governed by [mokocli](https://git.mokoconsulting.tech/MokoCon ``` {{REPO_NAME}}/ ├── manifest.xml # Joomla installer manifest (root — required) -├── updates.xml # Update server manifest (root — required) ├── site/ # Frontend (site) code │ ├── controller.php │ ├── controllers/ @@ -80,7 +79,7 @@ This repository is governed by [mokocli](https://git.mokoconsulting.tech/MokoCon ├── media/ # CSS, JS, images ├── docs/ # Technical documentation ├── tests/ # Test suite -├── .gitea/ +├── .mokogit/ │ ├── workflows/ # CI/CD workflows (synced from mokocli) │ ├── copilot-instructions.md │ └── CLAUDE.md # This file @@ -114,56 +113,12 @@ Three files must **always have the same version**: |------|------------------------| | `README.md` | `FILE INFORMATION` block + badge | | `manifest.xml` | `` tag | -| `updates.xml` | `` in the most recent `` block | -The `make release` command / release workflow syncs all three automatically. +The `make release` command / release workflow syncs both automatically. ---- +### Update Server -# updates.xml — Required in Repo Root - -`updates.xml` is the Joomla update server manifest. It allows Joomla installations to check for new versions of this extension via: - -```xml - - - - https://git.mokoconsulting.tech/mokoconsulting-tech/{{REPO_NAME}}/raw/branch/main/updates.xml - - - https://raw.githubusercontent.com/mokoconsulting-tech/{{REPO_NAME}}/main/updates.xml - - -``` - -**Rules:** -- Every release prepends a new `` block at the top — older entries are preserved. -- `` in `updates.xml` must exactly match `` in `manifest.xml` and `README.md`. -- `` must include two `` entries: Gitea release asset (primary) and GitHub release asset (mirror). -- `` — backslash is literal (Joomla regex syntax). - -Example `updates.xml` entry for a new release: -```xml - - - {{EXTENSION_NAME}} - {{REPO_NAME}} - {{EXTENSION_ELEMENT}} - {{EXTENSION_TYPE}} - 01.02.04 - {{REPO_URL}}/releases/tag/01.02.04 - - - {{REPO_URL}}/releases/download/01.02.04/{{EXTENSION_ELEMENT}}-01.02.04.zip - - - - 8.2 - Moko Consulting - https://mokoconsulting.tech - - -``` +MokoGit generates update feeds dynamically from releases — no static `updates.xml` needed in the repo. The update server URL in `manifest.xml` should point to `https://git.mokoconsulting.tech/{{ORG}}/{{REPO_NAME}}/updates.xml`. --- @@ -251,8 +206,8 @@ token: ${{ secrets.GITHUB_TOKEN }} | Change type | Documentation to update | |-------------|------------------------| | New or renamed PHP class/method | PHPDoc block; `docs/api/` entry | -| New or changed `manifest.xml` | Sync version to `updates.xml` and `README.md` | -| New release | Prepend `` to `updates.xml`; update `CHANGELOG.md`; bump `README.md` | +| New or changed `manifest.xml` | Sync version to `README.md` | +| New release | Update `CHANGELOG.md`; bump `README.md` | | New or changed workflow | `docs/workflows/.md` | | Any modified file | Update the `VERSION` field in that file's `FILE INFORMATION` block | | **Every PR** | **Bump the patch version** — increment `XX.YY.ZZ` in `README.md`; `sync-version-on-merge` propagates it | @@ -263,7 +218,7 @@ token: ${{ secrets.GITHUB_TOKEN }} - **Never commit directly to `main`** — all changes go through a PR. - **Never hardcode version numbers** in body text — update `README.md` and let automation propagate. -- **Never let `manifest.xml`, `updates.xml`, and `README.md` versions diverge.** +- **Never let `manifest.xml` and `README.md` versions diverge.** - **Never skip the FILE INFORMATION block** on a new source file. - **Never use bare `catch (\Throwable $e) {}`** — always log or re-throw. - **Never mix tabs and spaces** within a file — follow `.editorconfig`. @@ -277,7 +232,7 @@ token: ${{ secrets.GITHUB_TOKEN }} Before opening a PR, verify: - [ ] Patch version bumped in `README.md` (e.g. `01.02.03` → `01.02.04`) -- [ ] If this is a release: `manifest.xml` version updated; `updates.xml` updated with new entry +- [ ] If this is a release: `manifest.xml` version updated - [ ] FILE INFORMATION headers updated in modified files - [ ] CHANGELOG.md updated - [ ] Tests pass @@ -297,5 +252,5 @@ Before opening a PR, verify: ### Update Server Priority -In the manifest XML `` block, Gitea MUST be priority 1 and GitHub priority 2. -Never set GitHub as the primary update server — Gitea is the source of truth. +In the manifest XML `` block, MokoGit MUST be priority 1 and GitHub priority 2. +Never set GitHub as the primary update server — MokoGit is the source of truth. diff --git a/templates/mokogitea/CLAUDE.md.template b/templates/mokogit/CLAUDE.md.template similarity index 86% rename from templates/mokogitea/CLAUDE.md.template rename to templates/mokogit/CLAUDE.md.template index 94187dfa..063a0e42 100644 --- a/templates/mokogitea/CLAUDE.md.template +++ b/templates/mokogit/CLAUDE.md.template @@ -29,6 +29,6 @@ make clean # Clean build artifacts - **Never commit** `.claude/`, `.mcp.json`, `TODO.md`, `*.min.css`/`*.min.js` - **Attribution**: `Authored-by: Moko Consulting` -- **Workflow directory**: `.mokogitea/` (not `.gitea/` or `.github/`) -- **Wiki**: documentation lives in the Gitea wiki, not `docs/` files +- **Workflow directory**: `.mokogit/` (not `.mokogit/` or `.github/`) +- **Wiki**: documentation lives in the MokoGit wiki, not `docs/` files - **Standards**: [mokocli](https://git.mokoconsulting.tech/MokoConsulting/mokocli/wiki/Home) diff --git a/templates/mokogitea/CODEOWNERS b/templates/mokogit/CODEOWNERS similarity index 51% rename from templates/mokogitea/CODEOWNERS rename to templates/mokogit/CODEOWNERS index 2a52a7e4..9c3cb5f0 100644 --- a/templates/mokogitea/CODEOWNERS +++ b/templates/mokogit/CODEOWNERS @@ -9,31 +9,31 @@ # unauthorized modifications to workflows, configs, and governance files. # ── Synced workflows (managed by MokoCLI — do not edit manually) ──── -/.mokogitea/workflows/auto-bump.yml @jmiller -/.mokogitea/workflows/auto-release.yml @jmiller -/.mokogitea/workflows/pre-release.yml @jmiller -/.mokogitea/workflows/cascade-dev.yml @jmiller -/.mokogitea/workflows/rc-revert.yml @jmiller -/.mokogitea/workflows/branch-cleanup.yml @jmiller -/.mokogitea/workflows/cleanup.yml @jmiller -/.mokogitea/workflows/ci-generic.yml @jmiller -/.mokogitea/workflows/pr-check.yml @jmiller -/.mokogitea/workflows/notify.yml @jmiller -/.mokogitea/workflows/repo-health.yml @jmiller -/.mokogitea/workflows/gitleaks.yml @jmiller -/.mokogitea/workflows/issue-branch.yml @jmiller -/.mokogitea/workflows/ci-issue-reporter.yml @jmiller -/.mokogitea/workflows/sync-on-merge.yml @jmiller -/.mokogitea/workflows/version-set.yml @jmiller -# Custom workflows in .mokogitea/workflows/ not listed above are repo-owned. +/.mokogit/workflows/auto-bump.yml @jmiller +/.mokogit/workflows/auto-release.yml @jmiller +/.mokogit/workflows/pre-release.yml @jmiller +/.mokogit/workflows/cascade-dev.yml @jmiller +/.mokogit/workflows/rc-revert.yml @jmiller +/.mokogit/workflows/branch-cleanup.yml @jmiller +/.mokogit/workflows/cleanup.yml @jmiller +/.mokogit/workflows/ci-generic.yml @jmiller +/.mokogit/workflows/pr-check.yml @jmiller +/.mokogit/workflows/notify.yml @jmiller +/.mokogit/workflows/repo-health.yml @jmiller +/.mokogit/workflows/gitleaks.yml @jmiller +/.mokogit/workflows/issue-branch.yml @jmiller +/.mokogit/workflows/ci-issue-reporter.yml @jmiller +/.mokogit/workflows/sync-on-merge.yml @jmiller +/.mokogit/workflows/version-set.yml @jmiller +# Custom workflows in .mokogit/workflows/ not listed above are repo-owned. -# ── MokoGitea configuration ────────────────────────────────────────────── -/.mokogitea/ISSUE_TEMPLATE/ @jmiller -/.mokogitea/CODEOWNERS @jmiller -/.mokogitea/copilot.yml @jmiller -/.mokogitea/copilot-instructions.md @jmiller -/.mokogitea/CLAUDE.md @jmiller -/.mokogitea/.mokostandards @jmiller +# ── MokoGit configuration ────────────────────────────────────────────── +/.mokogit/ISSUE_TEMPLATE/ @jmiller +/.mokogit/CODEOWNERS @jmiller +/.mokogit/copilot.yml @jmiller +/.mokogit/copilot-instructions.md @jmiller +/.mokogit/CLAUDE.md @jmiller +/.mokogit/.mokostandards @jmiller # ── Build and config files ─────────────────────────────────────────────── /composer.json @jmiller diff --git a/templates/mokogitea/CODEOWNERS.template b/templates/mokogit/CODEOWNERS.template similarity index 85% rename from templates/mokogitea/CODEOWNERS.template rename to templates/mokogit/CODEOWNERS.template index 50d270ae..2996fe6c 100644 --- a/templates/mokogitea/CODEOWNERS.template +++ b/templates/mokogit/CODEOWNERS.template @@ -1,7 +1,7 @@ # CODEOWNERS Template # # This file defines code ownership for automatic review assignment. -# Copy to .gitea/CODEOWNERS (remove .template suffix) and customize. +# Copy to .mokogit/CODEOWNERS (remove .template suffix) and customize. # # Syntax: # pattern owner(s) @@ -27,13 +27,13 @@ /CONTRIBUTING.md @mokoconsulting-tech/docs-team # GitHub configuration -/.gitea/ @mokoconsulting-tech/devops-team -/.gitea/workflows/ @mokoconsulting-tech/devops-team +/.mokogit/ @mokoconsulting-tech/devops-team +/.mokogit/workflows/ @mokoconsulting-tech/devops-team # Security-related files /SECURITY.md @mokoconsulting-tech/security-team /docs/policy/security-*.md @mokoconsulting-tech/security-team -/.gitea/workflows/security-*.yml @mokoconsulting-tech/security-team +/.mokogit/workflows/security-*.yml @mokoconsulting-tech/security-team # API and automation /api/ @mokoconsulting-tech/automation-team diff --git a/templates/mokogitea/ISSUE_TEMPLATE/adr.md b/templates/mokogit/ISSUE_TEMPLATE/adr.md similarity index 100% rename from templates/mokogitea/ISSUE_TEMPLATE/adr.md rename to templates/mokogit/ISSUE_TEMPLATE/adr.md diff --git a/templates/mokogitea/ISSUE_TEMPLATE/bug_report.md b/templates/mokogit/ISSUE_TEMPLATE/bug_report.md similarity index 100% rename from templates/mokogitea/ISSUE_TEMPLATE/bug_report.md rename to templates/mokogit/ISSUE_TEMPLATE/bug_report.md diff --git a/templates/mokogitea/ISSUE_TEMPLATE/config.yml b/templates/mokogit/ISSUE_TEMPLATE/config.yml similarity index 100% rename from templates/mokogitea/ISSUE_TEMPLATE/config.yml rename to templates/mokogit/ISSUE_TEMPLATE/config.yml diff --git a/templates/mokogitea/ISSUE_TEMPLATE/documentation.md b/templates/mokogit/ISSUE_TEMPLATE/documentation.md similarity index 100% rename from templates/mokogitea/ISSUE_TEMPLATE/documentation.md rename to templates/mokogit/ISSUE_TEMPLATE/documentation.md diff --git a/templates/mokogitea/ISSUE_TEMPLATE/dolibarr_issue.md b/templates/mokogit/ISSUE_TEMPLATE/dolibarr_issue.md similarity index 100% rename from templates/mokogitea/ISSUE_TEMPLATE/dolibarr_issue.md rename to templates/mokogit/ISSUE_TEMPLATE/dolibarr_issue.md diff --git a/templates/mokogitea/ISSUE_TEMPLATE/dolibarr_module_id_request.md b/templates/mokogit/ISSUE_TEMPLATE/dolibarr_module_id_request.md similarity index 100% rename from templates/mokogitea/ISSUE_TEMPLATE/dolibarr_module_id_request.md rename to templates/mokogit/ISSUE_TEMPLATE/dolibarr_module_id_request.md diff --git a/templates/mokogitea/ISSUE_TEMPLATE/enterprise_support.md b/templates/mokogit/ISSUE_TEMPLATE/enterprise_support.md similarity index 100% rename from templates/mokogitea/ISSUE_TEMPLATE/enterprise_support.md rename to templates/mokogit/ISSUE_TEMPLATE/enterprise_support.md diff --git a/templates/mokogitea/ISSUE_TEMPLATE/feature_request.md b/templates/mokogit/ISSUE_TEMPLATE/feature_request.md similarity index 100% rename from templates/mokogitea/ISSUE_TEMPLATE/feature_request.md rename to templates/mokogit/ISSUE_TEMPLATE/feature_request.md diff --git a/templates/mokogitea/ISSUE_TEMPLATE/firewall-request.md b/templates/mokogit/ISSUE_TEMPLATE/firewall-request.md similarity index 100% rename from templates/mokogitea/ISSUE_TEMPLATE/firewall-request.md rename to templates/mokogit/ISSUE_TEMPLATE/firewall-request.md diff --git a/templates/mokogitea/ISSUE_TEMPLATE/joomla_issue.md b/templates/mokogit/ISSUE_TEMPLATE/joomla_issue.md similarity index 100% rename from templates/mokogitea/ISSUE_TEMPLATE/joomla_issue.md rename to templates/mokogit/ISSUE_TEMPLATE/joomla_issue.md diff --git a/templates/mokogitea/ISSUE_TEMPLATE/question.md b/templates/mokogit/ISSUE_TEMPLATE/question.md similarity index 100% rename from templates/mokogitea/ISSUE_TEMPLATE/question.md rename to templates/mokogit/ISSUE_TEMPLATE/question.md diff --git a/templates/mokogitea/ISSUE_TEMPLATE/request-license.md b/templates/mokogit/ISSUE_TEMPLATE/request-license.md similarity index 100% rename from templates/mokogitea/ISSUE_TEMPLATE/request-license.md rename to templates/mokogit/ISSUE_TEMPLATE/request-license.md diff --git a/templates/mokogitea/ISSUE_TEMPLATE/rfc.md b/templates/mokogit/ISSUE_TEMPLATE/rfc.md similarity index 100% rename from templates/mokogitea/ISSUE_TEMPLATE/rfc.md rename to templates/mokogit/ISSUE_TEMPLATE/rfc.md diff --git a/templates/mokogitea/ISSUE_TEMPLATE/security.md b/templates/mokogit/ISSUE_TEMPLATE/security.md similarity index 100% rename from templates/mokogitea/ISSUE_TEMPLATE/security.md rename to templates/mokogit/ISSUE_TEMPLATE/security.md diff --git a/templates/mokogitea/ISSUE_TEMPLATE/version.md b/templates/mokogit/ISSUE_TEMPLATE/version.md similarity index 100% rename from templates/mokogitea/ISSUE_TEMPLATE/version.md rename to templates/mokogit/ISSUE_TEMPLATE/version.md diff --git a/templates/mokogitea/PULL_REQUEST_TEMPLATE.md b/templates/mokogit/PULL_REQUEST_TEMPLATE.md similarity index 100% rename from templates/mokogitea/PULL_REQUEST_TEMPLATE.md rename to templates/mokogit/PULL_REQUEST_TEMPLATE.md diff --git a/templates/mokogitea/PULL_REQUEST_TEMPLATE.md.backup b/templates/mokogit/PULL_REQUEST_TEMPLATE.md.backup similarity index 100% rename from templates/mokogitea/PULL_REQUEST_TEMPLATE.md.backup rename to templates/mokogit/PULL_REQUEST_TEMPLATE.md.backup diff --git a/templates/mokogitea/README.md b/templates/mokogit/README.md similarity index 96% rename from templates/mokogitea/README.md rename to templates/mokogit/README.md index 2566e097..77ced29a 100644 --- a/templates/mokogitea/README.md +++ b/templates/mokogit/README.md @@ -22,7 +22,7 @@ along with this program. If not, see . DEFGROUP: MokoPlatform.Templates INGROUP: MokoPlatform.GitHub REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli -PATH: /templates/mokogitea/README.md +PATH: /templates/mokogit/README.md BRIEF: GitHub-specific templates including issues, PRs, and CODEOWNERS --> @@ -53,7 +53,7 @@ Located in `ISSUE_TEMPLATE/` directory: - **Custom Templates**: Project-specific issue types - **Configuration** (`config.yml`): Issue template configuration -**Usage**: Copy entire `ISSUE_TEMPLATE/` directory to your repository's `.mokogitea/` directory. +**Usage**: Copy entire `ISSUE_TEMPLATE/` directory to your repository's `.mokogit/` directory. ### Pull Request Template @@ -61,7 +61,7 @@ Located in `ISSUE_TEMPLATE/` directory: **Purpose**: Standardize pull request descriptions and ensure all necessary information is provided before review. -**Usage**: Copy to `.mokogitea/PULL_REQUEST_TEMPLATE.md` in your repository. +**Usage**: Copy to `.mokogit/PULL_REQUEST_TEMPLATE.md` in your repository. ### CODEOWNERS Template @@ -70,7 +70,7 @@ Located in `ISSUE_TEMPLATE/` directory: **Purpose**: Define code ownership for automatic review assignment. **Usage**: -1. Copy to `.mokogitea/CODEOWNERS` (remove `.template` suffix) +1. Copy to `.mokogit/CODEOWNERS` (remove `.template` suffix) 2. Customize with your team and file patterns 3. Commit to repository @@ -79,7 +79,7 @@ Located in `ISSUE_TEMPLATE/` directory: ### Setup Process 1. **Choose Templates**: Identify which templates your repository needs -2. **Copy to Repository**: Copy templates to your repository's `.mokogitea/` directory +2. **Copy to Repository**: Copy templates to your repository's `.mokogit/` directory 3. **Customize**: Adapt templates to your project's needs 4. **Test**: Create test issues/PRs to validate templates 5. **Document**: Update README with any project-specific requirements @@ -88,7 +88,7 @@ Located in `ISSUE_TEMPLATE/` directory: ``` your-repository/ -└── .mokogitea/ +└── .mokogit/ ├── ISSUE_TEMPLATE/ │ ├── bug_report.md │ ├── feature_request.md @@ -205,7 +205,7 @@ The CODEOWNERS file: * @org/default-team /docs/ @org/docs-team /src/ @org/dev-team -/.mokogitea/workflows/ @org/devops-team +/.mokogit/workflows/ @org/devops-team /scripts/ @org/automation-team /docs/policy/security-*.md @org/security-team ``` @@ -274,7 +274,7 @@ Before publishing templates: For small projects: ``` -.mokogitea/ +.mokogit/ ├── ISSUE_TEMPLATE/ │ └── bug_report.md └── PULL_REQUEST_TEMPLATE.md @@ -284,7 +284,7 @@ For small projects: For large projects: ``` -.mokogitea/ +.mokogit/ ├── ISSUE_TEMPLATE/ │ ├── bug_report.md │ ├── feature_request.md @@ -299,7 +299,7 @@ For large projects: For repositories with multiple components: ``` -.mokogitea/ +.mokogit/ ├── ISSUE_TEMPLATE/ │ ├── bug_report.md │ ├── feature_request.md @@ -371,7 +371,7 @@ Require status checks that verify: ## Metadata -* **Document**: templates/mokogitea/README.md +* **Document**: templates/mokogit/README.md * **Repository**: [mokocli](https://git.mokoconsulting.tech/MokoConsulting/mokocli) * **Owner**: Moko Consulting Engineering Team * **Scope**: GitHub templates and configuration diff --git a/templates/mokogitea/copilot-instructions.dolibarr.md.template b/templates/mokogit/copilot-instructions.dolibarr.md.template similarity index 98% rename from templates/mokogitea/copilot-instructions.dolibarr.md.template rename to templates/mokogit/copilot-instructions.dolibarr.md.template index 75611e79..2db7b7b6 100644 --- a/templates/mokogitea/copilot-instructions.dolibarr.md.template +++ b/templates/mokogit/copilot-instructions.dolibarr.md.template @@ -9,10 +9,10 @@ SPDX-License-Identifier: GPL-3.0-or-later DEFGROUP: MokoPlatform.Templates.GitHub INGROUP: MokoPlatform.Templates REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli -PATH: /templates/mokogitea/copilot-instructions.dolibarr.md.template +PATH: /templates/mokogit/copilot-instructions.dolibarr.md.template VERSION: XX.YY.ZZ BRIEF: GitHub Copilot custom instructions template for Dolibarr/MokoCRM module repositories -NOTE: Synced to .gitea/copilot-instructions.md in all Dolibarr/CRM module repos via bulk sync. +NOTE: Synced to .mokogit/copilot-instructions.md in all Dolibarr/CRM module repos via bulk sync. Tokens replaced at sync time: {{REPO_NAME}}, {{REPO_URL}}, {{MODULE_NAME}}, {{MODULE_CLASS}}, {{MODULE_ID}}, {{PRIMARY_LANGUAGE}} --> @@ -28,7 +28,7 @@ NOTE: Synced to .gitea/copilot-instructions.md in all Dolibarr/CRM module repos > > 1. Check whether any `{{TOKEN}}` placeholders remain in this file. > 2. If they do, locate the values as described in the table below and replace every occurrence -> in **both** `.gitea/copilot-instructions.md` and `.gitea/CLAUDE.md`. +> in **both** `.mokogit/copilot-instructions.md` and `.mokogit/CLAUDE.md`. > 3. After replacing all tokens, **delete this entire notice block** (from `> [!IMPORTANT]` > through the closing `> ---` line) in both files. > 4. Tell the developer: *"I've self-updated the AI context files with this repository's @@ -159,7 +159,7 @@ public $version = '01.02.04'; // Must match README.md version ├── docs/ # Technical documentation ├── scripts/ # Build and maintenance scripts ├── tests/ # Test suite -├── .gitea/ +├── .mokogit/ │ ├── workflows/ │ ├── copilot-instructions.md # This file │ └── CLAUDE.md diff --git a/templates/mokogitea/copilot-instructions.joomla.md.template b/templates/mokogit/copilot-instructions.joomla.md.template similarity index 74% rename from templates/mokogitea/copilot-instructions.joomla.md.template rename to templates/mokogit/copilot-instructions.joomla.md.template index a9f213e6..effb9ff1 100644 --- a/templates/mokogitea/copilot-instructions.joomla.md.template +++ b/templates/mokogit/copilot-instructions.joomla.md.template @@ -9,10 +9,10 @@ SPDX-License-Identifier: GPL-3.0-or-later DEFGROUP: MokoPlatform.Templates.GitHub INGROUP: MokoPlatform.Templates REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli -PATH: /templates/mokogitea/copilot-instructions.joomla.md.template +PATH: /templates/mokogit/copilot-instructions.joomla.md.template VERSION: XX.YY.ZZ BRIEF: GitHub Copilot custom instructions template for Joomla/MokoWaaS governed repositories -NOTE: Synced to .gitea/copilot-instructions.md in all Joomla/WaaS repos via bulk sync. +NOTE: Synced to .mokogit/copilot-instructions.md in all Joomla/WaaS repos via bulk sync. Tokens replaced at sync time: {{REPO_NAME}}, {{REPO_URL}}, {{EXTENSION_NAME}}, {{EXTENSION_TYPE}}, {{EXTENSION_ELEMENT}} --> @@ -28,7 +28,7 @@ NOTE: Synced to .gitea/copilot-instructions.md in all Joomla/WaaS repos via bulk > > 1. Check whether any `{{TOKEN}}` placeholders remain in this file. > 2. If they do, locate the values as described in the table below and replace every occurrence -> in **both** `.gitea/copilot-instructions.md` and `.gitea/CLAUDE.md`. +> in **both** `.mokogit/copilot-instructions.md` and `.mokogit/CLAUDE.md`. > 3. After replacing all tokens, **delete this entire notice block** (from `> [!IMPORTANT]` > through the closing `> ---` line) in both files. > 4. Tell the developer: *"I've self-updated the AI context files with this repository's @@ -122,30 +122,7 @@ BRIEF: One-line description ### Joomla Version Alignment -The version in `README.md` **must always match** the `` tag in `manifest.xml` and the latest entry in `updates.xml`. The `make release` command / release workflow updates all three automatically. - -```xml - -01.02.04 - - - - - {{EXTENSION_NAME}} - 01.02.04 - - - {{REPO_URL}}/releases/download/01.02.04/{{EXTENSION_ELEMENT}}-01.02.04.zip - - - - - - -``` +The version in `README.md` **must always match** the `` tag in `manifest.xml`. The release workflow updates both automatically. --- @@ -154,7 +131,6 @@ The version in `README.md` **must always match** the `` tag in `manifes ``` {{REPO_NAME}}/ ├── manifest.xml # Joomla installer manifest (root — required) -├── updates.xml # Update server manifest (root — required, see below) ├── site/ # Frontend (site) code │ ├── controller.php │ ├── controllers/ @@ -170,7 +146,7 @@ The version in `README.md` **must always match** the `` tag in `manifes ├── media/ # CSS, JS, images (deployed to /media/{{EXTENSION_ELEMENT}}/) ├── docs/ # Technical documentation ├── tests/ # Test suite -├── .gitea/ +├── .mokogit/ │ ├── workflows/ │ ├── copilot-instructions.md # This file │ └── CLAUDE.md @@ -183,35 +159,17 @@ The version in `README.md` **must always match** the `` tag in `manifes --- -## updates.xml — Required in Repo Root +## Update Server -`updates.xml` **must exist at the repository root**. It is the Joomla update server manifest that allows Joomla installations to check for new versions of this extension. - -The `manifest.xml` must reference BOTH update servers: -```xml - - - https://git.mokoconsulting.tech/mokoconsulting-tech/{{REPO_NAME}}/raw/branch/main/updates.xml - - - https://raw.githubusercontent.com/mokoconsulting-tech/{{REPO_NAME}}/main/updates.xml - - -``` - -**Rules:** -- Every release must prepend a new `` block at the top of `updates.xml` — old entries must be preserved below. -- The `` in `updates.xml` must exactly match `` in `manifest.xml` and the version in `README.md`. -- `` must include two `` entries: Gitea release asset (primary) and GitHub release asset (mirror). -- `` — the backslash is a **literal backslash character** in the XML attribute value; Joomla's update-server parser treats the value as a regular expression, so `\.` matches a literal dot and `[0-9]+` matches one or more digits. Do not double-escape it. +MokoGit generates update feeds dynamically from releases — no static `updates.xml` needed in the repo. The update server URL in `manifest.xml` should point to `https://git.mokoconsulting.tech/{{ORG}}/{{REPO_NAME}}/updates.xml`. --- ## manifest.xml Rules - Lives at the repo root as `manifest.xml` (not inside `site/` or `admin/`). -- `` tag must be kept in sync with `README.md` version and `updates.xml`. -- Must include `` block pointing to this repo's `updates.xml`. +- `` tag must be kept in sync with `README.md` version. +- Must include `` block with the MokoGit dynamic update server URL. - Must include `` and `` sections. - Joomla 4.x requires `Moko\{{EXTENSION_NAME}}` for namespaced extensions. @@ -289,8 +247,8 @@ Approved prefixes: `dev/` · `rc/` · `version/` · `patch/` · `copilot/` · `d | Change type | Documentation to update | |-------------|------------------------| | New or renamed PHP class/method | PHPDoc block; `docs/api/` entry | -| New or changed manifest.xml | Update `updates.xml` version; bump README.md version | -| New release | Prepend `` block to `updates.xml`; update CHANGELOG.md; bump README.md version | +| New or changed manifest.xml | Bump README.md version | +| New release | Update CHANGELOG.md; bump README.md version | | New or changed workflow | `docs/workflows/.md` | | Any modified file | Update the `VERSION` field in that file's `FILE INFORMATION` block | | **Every PR** | **Bump the patch version** — increment `XX.YY.ZZ` in `README.md`; `sync-version-on-merge` propagates it | @@ -304,7 +262,4 @@ Approved prefixes: `dev/` · `rc/` · `version/` · `patch/` · `copilot/` · `d - Never add `defined('_JEXEC') or die;` to CLI scripts or model tests — only to web-accessible PHP files - Never hardcode version numbers in body text — update `README.md` and let automation propagate - Never use `github.token` or `secrets.GITHUB_TOKEN` in workflows — always use `secrets.GH_TOKEN` -- Never let `manifest.xml` version, `updates.xml` version, and `README.md` version go out of sync - -## Update Server Priority -In , Gitea must be priority 1 and GitHub priority 2. Never reverse this. +- Never let `manifest.xml` version and `README.md` version go out of sync diff --git a/templates/mokogitea/copilot-instructions.md.template b/templates/mokogit/copilot-instructions.md.template similarity index 98% rename from templates/mokogitea/copilot-instructions.md.template rename to templates/mokogit/copilot-instructions.md.template index eaa2eac0..cddf905e 100644 --- a/templates/mokogitea/copilot-instructions.md.template +++ b/templates/mokogit/copilot-instructions.md.template @@ -9,10 +9,10 @@ SPDX-License-Identifier: GPL-3.0-or-later DEFGROUP: MokoPlatform.Templates.GitHub INGROUP: MokoPlatform.Templates REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli -PATH: /templates/mokogitea/copilot-instructions.md.template +PATH: /templates/mokogit/copilot-instructions.md.template VERSION: XX.YY.ZZ BRIEF: Standard GitHub Copilot custom instructions template for Moko Consulting governed repositories -NOTE: Synced to .gitea/copilot-instructions.md in all governed repositories via bulk sync. +NOTE: Synced to .mokogit/copilot-instructions.md in all governed repositories via bulk sync. Tokens replaced at sync time: {{REPO_NAME}}, {{REPO_URL}}, {{PRIMARY_LANGUAGE}}, {{PLATFORM_TYPE}} --> @@ -27,7 +27,7 @@ NOTE: Synced to .gitea/copilot-instructions.md in all governed repositories via > > 1. Check whether any `{{TOKEN}}` placeholders remain in this file. > 2. If they do, locate the values as described in the table below and replace every occurrence -> in **both** `.gitea/copilot-instructions.md` and `.gitea/CLAUDE.md`. +> in **both** `.mokogit/copilot-instructions.md` and `.mokogit/CLAUDE.md`. > 3. After replacing all tokens, **delete this entire notice block** (from `> [!IMPORTANT]` > through the closing `> ---` line) in both files. > 4. Tell the developer: *"I've self-updated the AI context files with this repository's diff --git a/templates/mokogitea/dependabot.yml.template b/templates/mokogit/dependabot.yml.template similarity index 96% rename from templates/mokogitea/dependabot.yml.template rename to templates/mokogit/dependabot.yml.template index 6b7e0b29..76254ddc 100644 --- a/templates/mokogitea/dependabot.yml.template +++ b/templates/mokogit/dependabot.yml.template @@ -8,10 +8,10 @@ # DEFGROUP: GitHub.Dependabot # INGROUP: MokoPlatform.Security # REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli -# PATH: /templates/mokogitea/dependabot.yml.template +# PATH: /templates/mokogit/dependabot.yml.template # VERSION: XX.YY.ZZ # BRIEF: Template Dependabot configuration for governed repositories -# NOTE: Copy to .gitea/dependabot.yml and remove ecosystems that don't apply. +# NOTE: Copy to .mokogit/dependabot.yml and remove ecosystems that don't apply. # Keep the github-actions entry — it is required for all governed repos. # The templates/workflows entry only applies if your repo ships template # workflow files (.yml) under templates/workflows/. @@ -22,7 +22,7 @@ updates: # ------------------------------------------------------------------------- # GitHub Actions — REQUIRED for all governed repositories - # Monitors uses: pins in .gitea/workflows/*.yml + # Monitors uses: pins in .mokogit/workflows/*.yml # ------------------------------------------------------------------------- - package-ecosystem: "github-actions" directory: "/" diff --git a/templates/mokogitea/override.tf.template b/templates/mokogit/override.tf.template similarity index 94% rename from templates/mokogitea/override.tf.template rename to templates/mokogit/override.tf.template index 3f50b2b5..1fa4b35e 100644 --- a/templates/mokogitea/override.tf.template +++ b/templates/mokogit/override.tf.template @@ -1,5 +1,5 @@ # Repository Health Check Override Configuration -# Location: .gitea/override.tf +# Location: .mokogit/override.tf # # This file allows repository-specific customization of health checks. # It overrides the default configuration from mokocli. @@ -72,14 +72,14 @@ locals { # File sync exclusions # Files to exclude from automatic sync sync_exclusions = [ - # Example: ".gitea/workflows/custom-workflow.yml", - # Example: ".gitea/ISSUE_TEMPLATE/custom-template.md", + # Example: ".mokogit/workflows/custom-workflow.yml", + # Example: ".mokogit/ISSUE_TEMPLATE/custom-template.md", ] # Protected files # Files that should never be overwritten by sync protected_files = [ - # Example: ".gitea/workflows/deployment.yml", + # Example: ".mokogit/workflows/deployment.yml", # Example: "scripts/release/custom-release.sh", ] } diff --git a/templates/mokogitea/renovate.json b/templates/mokogit/renovate.json similarity index 100% rename from templates/mokogitea/renovate.json rename to templates/mokogit/renovate.json diff --git a/templates/schemas/manifest-schema.xsd b/templates/schemas/manifest-schema.xsd index dfe0ea17..b1e2a507 100644 --- a/templates/schemas/manifest-schema.xsd +++ b/templates/schemas/manifest-schema.xsd @@ -4,9 +4,9 @@ SPDX-License-Identifier: GPL-3.0-or-later mokocli Manifest Schema v09.01.00 - Defines the structure of .mokogitea/manifest.xml + Defines the structure of .mokogit/manifest.xml - Validate: xmllint - -schema definitions/manifest-schema.xsd .mokogitea/manifest.xml + Validate: xmllint - -schema definitions/manifest-schema.xsd .mokogit/manifest.xml --> Root element of the manifest.xml repository manifest. - Every governed repository MUST contain this file at .mokogitea/manifest.xml + Every governed repository MUST contain this file at .mokogit/manifest.xml diff --git a/templates/schemas/mokostandards-schema.xsd b/templates/schemas/mokostandards-schema.xsd index b479ffeb..1218248c 100644 --- a/templates/schemas/mokostandards-schema.xsd +++ b/templates/schemas/mokostandards-schema.xsd @@ -22,7 +22,7 @@ Root element of the .mokostandards repository manifest. - Every governed repository MUST contain this file at .gitea/.mokostandards + Every governed repository MUST contain this file at .mokogit/.mokostandards diff --git a/templates/scripts/validate/validate_structure.php b/templates/scripts/validate/validate_structure.php index 7c978a7c..a1d67a0e 100644 --- a/templates/scripts/validate/validate_structure.php +++ b/templates/scripts/validate/validate_structure.php @@ -31,7 +31,7 @@ use MokoCli\CliFramework; * - Required root files present (README.md, CHANGELOG.md, LICENSE, CONTRIBUTING.md, * SECURITY.md, .gitignore, .editorconfig, composer.json) * - Required directories present (src/, docs/, tests/) - * - .mokogitea/manifest.xml XML governance manifest present + * - .mokogit/manifest.xml XML governance manifest present * - SPDX-License-Identifier header present in all PHP source files * - No tab characters in YAML/JSON config files * - No Windows path separators in PHP source @@ -73,16 +73,16 @@ class ValidateStructure extends CliFramework // ── Governance attachment ───────────────────────────────────────── $this->section('mokocli governance'); - $mokoFile = file_exists("{$path}/.mokogitea/manifest.xml") + $mokoFile = file_exists("{$path}/.mokogit/manifest.xml") || file_exists("{$path}/.github/.mokostandards") || file_exists("{$path}/.mokostandards"); - $this->status($mokoFile, '.mokogitea/manifest.xml (XML manifest)'); + $this->status($mokoFile, '.mokogit/manifest.xml (XML manifest)'); $mokoFile ? $passed++ : $failed++; // Validate XML format if file exists if ($mokoFile) { - $manifestPath = file_exists("{$path}/.mokogitea/manifest.xml") - ? "{$path}/.mokogitea/manifest.xml" + $manifestPath = file_exists("{$path}/.mokogit/manifest.xml") + ? "{$path}/.mokogit/manifest.xml" : (file_exists("{$path}/.github/.mokostandards") ? "{$path}/.github/.mokostandards" : "{$path}/.mokostandards"); diff --git a/tests/Enterprise/GitPlatformAdapterTest.php b/tests/Enterprise/GitPlatformAdapterTest.php index 4fa11c82..ed292177 100644 --- a/tests/Enterprise/GitPlatformAdapterTest.php +++ b/tests/Enterprise/GitPlatformAdapterTest.php @@ -19,7 +19,7 @@ use MokoCli\ApiClient; use MokoCli\Config; use MokoCli\GitPlatformAdapter; use MokoCli\GitHubAdapter; -use MokoCli\MokoGiteaAdapter; +use MokoCli\MokoGitAdapter; use MokoCli\PlatformAdapterFactory; echo "Testing GitPlatformAdapter Interface Compliance\n"; @@ -58,22 +58,22 @@ assert_true($ghAdapter->getWorkflowDir() === '.github/workflows', 'getWorkflowDi assert_true($ghAdapter->getApiClient() === $ghClient, 'getApiClient() returns injected client'); echo "\n"; -// ── Test 2: MokoGiteaAdapter implements GitPlatformAdapter ────────────────── -echo "2. Testing MokoGiteaAdapter interface compliance...\n"; +// ── Test 2: MokoGitAdapter implements GitPlatformAdapter ────────────────── +echo "2. Testing MokoGitAdapter interface compliance...\n"; -$giteaClient = new ApiClient( +$mokogitClient = new ApiClient( baseUrl: 'https://git.mokoconsulting.tech/api/v1', authToken: 'test-token', enableCaching: false, authScheme: 'token' ); -$giteaAdapter = new MokoGiteaAdapter($giteaClient); +$mokogitAdapter = new MokoGitAdapter($mokogitClient); -assert_true($giteaAdapter instanceof GitPlatformAdapter, 'MokoGiteaAdapter implements GitPlatformAdapter'); -assert_true($giteaAdapter->getPlatformName() === 'gitea', 'getPlatformName() returns "gitea"'); -assert_true($giteaAdapter->getBaseUrl() === 'https://git.mokoconsulting.tech/api/v1', 'getBaseUrl() returns Gitea API URL'); -assert_true($giteaAdapter->getWorkflowDir() === '.mokogitea/workflows', 'getWorkflowDir() returns .gitea/workflows'); -assert_true($giteaAdapter->getApiClient() === $giteaClient, 'getApiClient() returns injected client'); +assert_true($mokogitAdapter instanceof GitPlatformAdapter, 'MokoGitAdapter implements GitPlatformAdapter'); +assert_true($mokogitAdapter->getPlatformName() === 'mokogit', 'getPlatformName() returns "mokogit"'); +assert_true($mokogitAdapter->getBaseUrl() === 'https://git.mokoconsulting.tech/api/v1', 'getBaseUrl() returns MokoGit API URL'); +assert_true($mokogitAdapter->getWorkflowDir() === '.mokogit/workflows', 'getWorkflowDir() returns .mokogit/workflows'); +assert_true($mokogitAdapter->getApiClient() === $mokogitClient, 'getApiClient() returns injected client'); echo "\n"; // ── Test 3: All interface methods exist on both adapters ──────────────── @@ -94,12 +94,12 @@ $requiredMethods = [ foreach ($requiredMethods as $method) { $ghHas = method_exists($ghAdapter, $method); - $giteaHas = method_exists($giteaAdapter, $method); + $mokogitHas = method_exists($mokogitAdapter, $method); - if ($ghHas && $giteaHas) { + if ($ghHas && $mokogitHas) { $passed++; } else { - echo " ✗ FAILED: {$method} — GitHub=" . ($ghHas ? 'yes' : 'NO') . " Gitea=" . ($giteaHas ? 'yes' : 'NO') . "\n"; + echo " ✗ FAILED: {$method} — GitHub=" . ($ghHas ? 'yes' : 'NO') . " MokoGit=" . ($mokogitHas ? 'yes' : 'NO') . "\n"; $failed++; } } @@ -121,14 +121,14 @@ try { assert_true(false, 'Factory creates GitHubAdapter: ' . $e->getMessage()); } -// Test Gitea creation -$config->set('gitea.token', 'test-gitea-token'); +// Test MokoGit creation +$config->set('mokogit.token', 'test-mokogit-token'); try { - $adapter = PlatformAdapterFactory::create($config, 'gitea'); - assert_true($adapter instanceof MokoGiteaAdapter, 'Factory creates MokoGiteaAdapter for platform=gitea'); - assert_true($adapter->getPlatformName() === 'gitea', 'Created adapter identifies as gitea'); + $adapter = PlatformAdapterFactory::create($config, 'mokogit'); + assert_true($adapter instanceof MokoGitAdapter, 'Factory creates MokoGitAdapter for platform=mokogit'); + assert_true($adapter->getPlatformName() === 'mokogit', 'Created adapter identifies as mokogit'); } catch (\Exception $e) { - assert_true(false, 'Factory creates MokoGiteaAdapter: ' . $e->getMessage()); + assert_true(false, 'Factory creates MokoGitAdapter: ' . $e->getMessage()); } // Test invalid platform @@ -146,13 +146,13 @@ echo "5. Testing Config platform configuration...\n"; $config = new Config([ 'platform' => 'github', 'github' => ['organization' => 'mokoconsulting-tech', 'rate_limit' => 5000], - 'gitea' => ['url' => 'https://git.mokoconsulting.tech', 'organization' => 'mokoconsulting-tech', 'rate_limit' => 5000], + 'mokogit' => ['url' => 'https://git.mokoconsulting.tech', 'organization' => 'mokoconsulting-tech', 'rate_limit' => 5000], ]); assert_true($config->getString('platform') === 'github', 'Default platform is github'); -assert_true($config->getString('gitea.url') === 'https://git.mokoconsulting.tech', 'Gitea URL configured'); -assert_true($config->getString('gitea.organization') === 'mokoconsulting-tech', 'Gitea org configured'); -assert_true($config->getInt('gitea.rate_limit') === 5000, 'Gitea rate limit configured'); +assert_true($config->getString('mokogit.url') === 'https://git.mokoconsulting.tech', 'MokoGit URL configured'); +assert_true($config->getString('mokogit.organization') === 'mokoconsulting-tech', 'MokoGit org configured'); +assert_true($config->getInt('mokogit.rate_limit') === 5000, 'MokoGit rate limit configured'); echo "\n"; // ── Test 6: ApiClient auth scheme ─────────────────────────────────────── @@ -185,9 +185,9 @@ try { assert_true(true, 'GitHubAdapter.migrateRepository() throws RuntimeException'); } -// MokoGiteaAdapter.migrateRepository() should NOT throw (it calls the API) +// MokoGitAdapter.migrateRepository() should NOT throw (it calls the API) // We can't test it without a real server, but verify the method exists -assert_true(method_exists($giteaAdapter, 'migrateRepository'), 'MokoGiteaAdapter.migrateRepository() exists'); +assert_true(method_exists($mokogitAdapter, 'migrateRepository'), 'MokoGitAdapter.migrateRepository() exists'); echo "\n"; // ── Summary ───────────────────────────────────────────────────────────── diff --git a/tests/Unit/VersionBumpTest.php b/tests/Unit/VersionBumpTest.php index 26ff0ecb..a9c40fad 100644 --- a/tests/Unit/VersionBumpTest.php +++ b/tests/Unit/VersionBumpTest.php @@ -88,9 +88,9 @@ class VersionBumpTest extends TestCase public function testPreservesSuffixOnBump(): void { - mkdir("{$this->tmpDir}/.mokogitea", 0755, true); + mkdir("{$this->tmpDir}/.mokogit", 0755, true); file_put_contents( - "{$this->tmpDir}/.mokogitea/manifest.xml", + "{$this->tmpDir}/.mokogit/manifest.xml", '01.02.03-dev' ); $this->writeReadme('01.02.03'); @@ -98,7 +98,7 @@ class VersionBumpTest extends TestCase $output = $this->execute(); $this->assertStringContainsString('01.02.04-dev', $output); - $manifest = file_get_contents("{$this->tmpDir}/.mokogitea/manifest.xml"); + $manifest = file_get_contents("{$this->tmpDir}/.mokogit/manifest.xml"); $this->assertStringContainsString('01.02.04-dev', $manifest); } diff --git a/validate/auto_detect_platform.php b/validate/auto_detect_platform.php index eacc8ecb..a5f3fe16 100755 --- a/validate/auto_detect_platform.php +++ b/validate/auto_detect_platform.php @@ -200,7 +200,6 @@ class AutoDetectPlatform extends CliFramework 'src/media/templates/site/mokoonyx/css/theme/light.custom.css' => 15, 'src/media/templates/site/mokoonyx/css/theme/dark.custom.css' => 15, 'src/script.php' => 10, - 'updates.xml' => 10, ]; foreach ($themeMarkers as $path => $weight) { $full = $repoPath . '/' . $path; @@ -754,7 +753,7 @@ class AutoDetectPlatform extends CliFramework } // Check for .mokocli platform declaration - $mokoFiles = ["{$repoPath}/.gitea/.mokocli", "{$repoPath}/.github/.mokocli"]; + $mokoFiles = ["{$repoPath}/.mokogit/.mokocli", "{$repoPath}/.github/.mokocli"]; foreach ($mokoFiles as $mokoFile) { if (file_exists($mokoFile)) { $content = @file_get_contents($mokoFile); diff --git a/validate/check_client_theme.php b/validate/check_client_theme.php index 4c1628ed..14b49544 100644 --- a/validate/check_client_theme.php +++ b/validate/check_client_theme.php @@ -33,7 +33,6 @@ use MokoCli\{CliFramework, SourceResolver}; * - Required theme files (light.custom.css, dark.custom.css) * - PHP syntax of script.php * - CSS brace balance - * - updates.xml at repo root * - Image size warnings */ class CheckClientTheme extends CliFramework @@ -55,7 +54,6 @@ class CheckClientTheme extends CliFramework '~media/templates/site/mokoonyx/css/user.css', '~media/templates/site/mokoonyx/js/user.js', '~script.php', - 'updates.xml', ]; /** Maximum image size before warning (1 MB). */ @@ -225,19 +223,6 @@ class CheckClientTheme extends CliFramework $manifestVer = $m[1]; } - $updatesFile = $path . '/updates.xml'; - if (is_file($updatesFile)) { - $updatesContent = (string) file_get_contents($updatesFile); - if (preg_match('/([^<]+)<\/version>/', $updatesContent, $m)) { - if ($m[1] !== $manifestVer) { - $this->warning("Version drift: manifest={$manifestVer}, updates.xml={$m[1]}"); - $warns++; - } else { - $this->status(true, "Versions match: {$manifestVer}"); - } - } - } - if (is_file($path . '/CHANGELOG.md')) { $cl = (string) file_get_contents($path . '/CHANGELOG.md'); if (!str_contains($cl, "[{$manifestVer}]")) { diff --git a/validate/check_composer_deps.php b/validate/check_composer_deps.php index 17518104..94e025bd 100644 --- a/validate/check_composer_deps.php +++ b/validate/check_composer_deps.php @@ -50,8 +50,8 @@ try { fwrite(STDERR, "Platform init failed: " . $e->getMessage() . "\n"); exit(1); } -$token = $config->getString('platform', 'gitea') === 'gitea' - ? $config->getString('gitea.token', '') +$token = $config->getString('platform', 'mokogit') === 'mokogit' + ? $config->getString('mokogit.token', '') : $config->getString('github.token', ''); $EXPECTED_VERSION = '04.02.30'; diff --git a/validate/check_repo_health.php b/validate/check_repo_health.php index 523629f6..81cb2c75 100755 --- a/validate/check_repo_health.php +++ b/validate/check_repo_health.php @@ -23,7 +23,7 @@ * Rulesets (15) — main protected, dev branch, rulesets * Deployment (10) — deploy workflow, build system * - * Note: This file uses curl_init for HTTP requests to the Gitea API. + * Note: This file uses curl_init for HTTP requests to the MokoGit API. * No shell commands or child processes are invoked. */ @@ -58,7 +58,7 @@ class RepoHealthChecker extends CliFramework $this->addArgument('--path', 'Repository path', '.'); $this->addArgument('--threshold', 'Minimum health %', '70'); $this->addArgument('--json', 'JSON output', false); - $this->addArgument('--create-issue', 'Create Gitea issue', false); + $this->addArgument('--create-issue', 'Create MokoGit issue', false); $this->addArgument('--repo', 'owner/repo', ''); } @@ -68,7 +68,7 @@ class RepoHealthChecker extends CliFramework $this->logger = new AuditLogger('repo_health_checker'); $this->metrics = new MetricsCollector(); $config = \MokoCli\Config::load(); - $this->apiBaseUrl = rtrim($config->getString('gitea.url', 'https://git.mokoconsulting.tech'), '/') . '/api/v1'; + $this->apiBaseUrl = rtrim($config->getString('mokogit.url', 'https://git.mokoconsulting.tech'), '/') . '/api/v1'; } protected function run(): int @@ -152,14 +152,14 @@ class RepoHealthChecker extends CliFramework $this->addCheck( $cat, - '.mokogitea/.mokocli manifest', - file_exists("{$p}/.gitea/.mokocli"), + '.mokogit/.mokocli manifest', + file_exists("{$p}/.mokogit/.mokocli"), 5 ); $this->addCheck( $cat, 'Workflows directory', - is_dir("{$p}/.gitea/workflows") || is_dir("{$p}/.github/workflows"), + is_dir("{$p}/.mokogit/workflows") || is_dir("{$p}/.github/workflows"), 5 ); $this->addCheck( @@ -387,7 +387,7 @@ class RepoHealthChecker extends CliFramework $cat = 'workflows'; $this->initCategory($cat, 'Workflows', 15); - $wf = is_dir("{$p}/.gitea/workflows") ? "{$p}/.gitea/workflows" : "{$p}/.github/workflows"; + $wf = is_dir("{$p}/.mokogit/workflows") ? "{$p}/.mokogit/workflows" : "{$p}/.github/workflows"; $exists = is_dir($wf); $this->addCheck($cat, 'Workflows directory', $exists, 5); @@ -420,7 +420,7 @@ class RepoHealthChecker extends CliFramework $this->addCheck($cat, 'SECURITY.md', file_exists("{$p}/SECURITY.md"), 5); - $wf = is_dir("{$p}/.gitea/workflows") ? "{$p}/.gitea/workflows" : "{$p}/.github/workflows"; + $wf = is_dir("{$p}/.mokogit/workflows") ? "{$p}/.mokogit/workflows" : "{$p}/.github/workflows"; $hasScan = is_dir($wf) && (!empty(glob("{$wf}/*gitleaks*.yml")) || !empty(glob("{$wf}/*trivy*.yml")) || !empty(glob("{$wf}/*security*.yml"))); $this->addCheck($cat, 'Security scanning workflow', $hasScan, 5); @@ -456,7 +456,7 @@ class RepoHealthChecker extends CliFramework return; } - $token = getenv('GH_TOKEN') ?: getenv('GITEA_TOKEN') ?: ''; + $token = getenv('GH_TOKEN') ?: getenv('MOKOGIT_TOKEN') ?: ''; if (!$token) { $this->addCheck($cat, 'Main branch protected', false, 5); $this->addCheck($cat, 'Dev branch exists', false, 5); @@ -464,7 +464,7 @@ class RepoHealthChecker extends CliFramework return; } - // Gitea uses /branch_protections endpoint (not /branches/main/protection) + // MokoGit uses /branch_protections endpoint (not /branches/main/protection) $protections = $this->apiFetch("repos/{$repo}/branch_protections", $token); $mainProtected = false; foreach ($protections as $bp) { @@ -492,7 +492,7 @@ class RepoHealthChecker extends CliFramework $cat = 'deployment'; $this->initCategory($cat, 'Deployment', 10); - $wf = is_dir("{$p}/.gitea/workflows") ? "{$p}/.gitea/workflows" : "{$p}/.github/workflows"; + $wf = is_dir("{$p}/.mokogit/workflows") ? "{$p}/.mokogit/workflows" : "{$p}/.github/workflows"; $this->addCheck( $cat, 'Deploy workflow', @@ -605,7 +605,7 @@ class RepoHealthChecker extends CliFramework $body .= "- {$c['name']} ({$c['points']}pts)\n"; } } - $token = getenv('GH_TOKEN') ?: getenv('GITEA_TOKEN') ?: ''; + $token = getenv('GH_TOKEN') ?: getenv('MOKOGIT_TOKEN') ?: ''; if (!$token) { return; } diff --git a/validate/check_structure.php b/validate/check_structure.php index 740c1a0d..d3644083 100644 --- a/validate/check_structure.php +++ b/validate/check_structure.php @@ -32,7 +32,7 @@ class CheckStructure extends CliFramework private const REQUIRED_DIRS = ['docs', 'scripts']; /** @var list At least one of these workflow directories must exist. */ - private const WORKFLOW_DIRS = ['.github/workflows', '.mokogitea/workflows']; + private const WORKFLOW_DIRS = ['.github/workflows', '.mokogit/workflows']; /** @var list Required file paths (relative to repo root). */ private const REQUIRED_FILES = ['README.md', 'LICENSE', 'CONTRIBUTING.md', 'SECURITY.md']; diff --git a/validate/check_version_consistency.php b/validate/check_version_consistency.php index d9416ad8..24def866 100755 --- a/validate/check_version_consistency.php +++ b/validate/check_version_consistency.php @@ -116,9 +116,9 @@ class CheckVersionConsistency extends CliFramework // ── Check workflow files ────────────────────────────────────────────── $this->section('Checking workflow files'); - // Check both .github/workflows and .gitea/workflows + // Check both .github/workflows and .mokogit/workflows $workflowFiles = []; - foreach (['.github/workflows', '.mokogitea/workflows'] as $wfDir) { + foreach (['.github/workflows', '.mokogit/workflows'] as $wfDir) { $dir = $path . '/' . $wfDir; if (is_dir($dir)) { $workflowFiles = array_merge($workflowFiles, glob($dir . '/*.yml') ?: []); diff --git a/validate/check_wiki_health.php b/validate/check_wiki_health.php index 8afd9867..381e9f29 100644 --- a/validate/check_wiki_health.php +++ b/validate/check_wiki_health.php @@ -22,7 +22,7 @@ use MokoCli\CliFramework; /** * Wiki Health Checker * - * Validates Gitea wiki structure and content for a repository, + * Validates MokoGit wiki structure and content for a repository, * checking for required pages, broken links, and formatting issues. * * @since 04.00.00 @@ -33,16 +33,16 @@ class CheckWikiHealth extends CliFramework { $this->setDescription('Validate wiki health for a repository'); $this->addArgument('--path', 'Repository path (default: current directory)', '.'); - $this->addArgument('--gitea-url', 'Gitea base URL', 'https://git.mokoconsulting.tech'); - $this->addArgument('--token', 'Gitea API token (or set GITEA_TOKEN env var)', ''); + $this->addArgument('--mokogit-url', 'MokoGit base URL', 'https://git.mokoconsulting.tech'); + $this->addArgument('--token', 'MokoGit API token (or set MOKOGIT_TOKEN env var)', ''); $this->addArgument('--json', 'Output as JSON', false); } protected function run(): int { $repoPath = realpath($this->getArgument('--path', '.')) ?: '.'; - $giteaUrl = $this->getArgument('--gitea-url', 'https://git.mokoconsulting.tech'); - $token = $this->getArgument('--token', getenv('GITEA_TOKEN') ?: ''); + $mokogitUrl = $this->getArgument('--mokogit-url', 'https://git.mokoconsulting.tech'); + $token = $this->getArgument('--token', getenv('MOKOGIT_TOKEN') ?: ''); // Detect repo owner/name from git config $configFile = $repoPath . '/.git/config'; @@ -72,7 +72,7 @@ class CheckWikiHealth extends CliFramework $issues = 0; // Check wiki pages via API - $apiUrl = "{$giteaUrl}/api/v1/repos/{$owner}/{$repo}/wiki/pages"; + $apiUrl = "{$mokogitUrl}/api/v1/repos/{$owner}/{$repo}/wiki/pages"; $headers = $token ? ["Authorization: token {$token}"] : []; $pages = $this->apiGet($apiUrl, $headers); @@ -108,7 +108,7 @@ class CheckWikiHealth extends CliFramework // Check Home has mokocli link if ($hasHome) { - $homeUrl = "{$giteaUrl}/api/v1/repos/{$owner}/{$repo}/wiki/page/Home"; + $homeUrl = "{$mokogitUrl}/api/v1/repos/{$owner}/{$repo}/wiki/page/Home"; $home = $this->apiGet($homeUrl, $headers); if ($home) { $content = base64_decode($home['content_base64'] ?? ''); diff --git a/validate/scan_drift.php b/validate/scan_drift.php index 6286e3d9..55377b24 100755 --- a/validate/scan_drift.php +++ b/validate/scan_drift.php @@ -269,9 +269,9 @@ class DriftScanner extends CliFramework $protectedFiles = $overrideConfig['protected_files'] ?? []; $syncExclusions = $overrideConfig['sync_exclusions'] ?? []; - // Check workflows — scan both .github/workflows and .gitea/workflows + // Check workflows — scan both .github/workflows and .mokogit/workflows $drift = $this->checkFileCategory($org, $repo, 'workflows', '.github/workflows', $drift, $protectedFiles, $syncExclusions); - $drift = $this->checkFileCategory($org, $repo, 'workflows_gitea', '.mokogitea/workflows', $drift, $protectedFiles, $syncExclusions); + $drift = $this->checkFileCategory($org, $repo, 'workflows_mokogit', '.mokogit/workflows', $drift, $protectedFiles, $syncExclusions); // Check GitHub configs $drift = $this->checkFileCategory($org, $repo, 'github', '.github', $drift, $protectedFiles, $syncExclusions);