Skip to content

Add integrated Git server (Gitea) management UI and API#1

Merged
jhd3197 merged 3 commits intomainfrom
dev
Jan 22, 2026
Merged

Add integrated Git server (Gitea) management UI and API#1
jhd3197 merged 3 commits intomainfrom
dev

Conversation

@jhd3197
Copy link
Copy Markdown
Owner

@jhd3197 jhd3197 commented Jan 22, 2026

This PR introduces first-class Git server management in ServerKit by integrating Gitea across the UI, API, and CLI layers.

What’s included

  • Integrated Gitea management UI for repositories, branches, and workflows
  • Backend API support to interact with Gitea services from ServerKit
  • CLI enhancement with branch switching support for Git-based projects
  • Initial Gitea integration plan and architecture documentation

Why this matters

  • Enables self-hosted Git management without relying on external platforms
  • Aligns ServerKit with a fully open-source, infrastructure-owned workflow
  • Improves developer productivity by unifying server, app, and Git operations in one place

Notes

  • This lays the foundation for future features like repo provisioning, deploy hooks, and CI integrations
  • Documentation added to guide future expansion and contributor alignment

jhd3197 and others added 3 commits January 21, 2026 18:25
Introduces backend API endpoints and service logic for installing, managing, and uninstalling a Gitea-based Git server. Adds a new frontend page for Git server management, updates the sidebar and routing, and includes supporting API methods and styles for the new feature.
- Add 'serverkit update --branch <name>' to switch branches
- Add 'serverkit branch' command to show current branch
- Skip version check for non-main branches (dev mode)
- Show commit hash and branch in update output
- Warn users when running on non-main branch

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Introduces GITEA_INTEGRATION_PLAN.md outlining the architecture, UI/UX, backend API, database changes, and implementation phases for integrating Gitea-based Git functionality into ServerKit, including resource warnings and webhook support.
Copilot AI review requested due to automatic review settings January 22, 2026 00:37
@jhd3197 jhd3197 merged commit 425df2b into main Jan 22, 2026
5 checks passed
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces integrated Git server management by adding Gitea as a first-class feature in ServerKit. The implementation spans CLI, backend API, and frontend UI layers to enable self-hosted Git repository management.

Changes:

  • Enhanced CLI with branch switching capabilities for Git-based project management
  • Added comprehensive Gitea management UI with installation, configuration, and access control
  • Implemented backend services and API endpoints for Gitea lifecycle management (install, start, stop, uninstall)

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
serverkit Enhanced update command with branch switching support and new branch command
frontend/src/pages/Git.jsx New Git management page with installation wizard and server controls
frontend/src/styles/pages/_git.less Complete styling for Git page including tabs, status cards, and modals
frontend/src/styles/main.less Import for new Git page styles
frontend/src/services/api.js API client methods for Git server endpoints
frontend/src/components/Sidebar.jsx Added Git navigation item to sidebar
frontend/src/App.jsx Routing for new Git page
backend/app/services/git_service.py Service layer for Gitea installation and management
backend/app/api/git.py REST API endpoints for Git server operations
backend/app/init.py Blueprint registration for Git API
GITEA_INTEGRATION_PLAN.md Architecture and implementation planning documentation

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +724 to +728
# Only include password in response if it was generated
if generated_password:
response['admin_password'] = admin_password
response['warning'] = 'Save these credentials - password shown only once!'

Copy link

Copilot AI Jan 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The generated admin_password is returned in the API response (lines 726-727) and could be logged or exposed in API responses. This sensitive credential should be handled more securely and only displayed once to the user through a secure channel.

Suggested change
# Only include password in response if it was generated
if generated_password:
response['admin_password'] = admin_password
response['warning'] = 'Save these credentials - password shown only once!'

Copilot uses AI. Check for mistakes.
# ========================================

GITEA_APP_NAME = 'serverkit-gitea'
GITEA_CONFIG_FILE = os.path.join(CONFIG_DIR, 'gitea.json')
Copy link

Copilot AI Jan 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CONFIG_DIR variable is referenced without the cls prefix (line 584). It should be cls.CONFIG_DIR to properly reference the class variable.

Copilot uses AI. Check for mistakes.
Comment thread serverkit
Comment on lines +434 to +435
git checkout "$target_branch" 2>/dev/null || git checkout -b "$target_branch" "origin/$target_branch"
git reset --hard "origin/$target_branch"
Copy link

Copilot AI Jan 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The git checkout command may fail silently if the remote branch doesn't exist. The fallback creates a new local branch tracking the remote, but there's no error handling if the remote branch doesn't exist. This could leave the system in an inconsistent state. Add validation to check if the remote branch exists before attempting checkout.

Suggested change
git checkout "$target_branch" 2>/dev/null || git checkout -b "$target_branch" "origin/$target_branch"
git reset --hard "origin/$target_branch"
if git show-ref --verify --quiet "refs/remotes/origin/$target_branch"; then
git checkout "$target_branch" 2>/dev/null || git checkout -b "$target_branch" "origin/$target_branch"
git reset --hard "origin/$target_branch"
else
if type print_error >/dev/null 2>&1; then
print_error "Remote branch 'origin/$target_branch' does not exist. Aborting update."
else
echo -e "${RED}Remote branch 'origin/$target_branch' does not exist. Aborting update.${NC}"
fi
exit 1
fi

Copilot uses AI. Check for mistakes.
Comment on lines +338 to +362
onClick={() => {
navigator.clipboard.writeText(`git clone ssh://git@${window.location.hostname}:${status?.ssh_port}/user/repo.git`);
toast.success('SSH URL copied to clipboard');
}}
>
Copy SSH URL
</button>
</div>
</div>
</div>
)}

{activeTab === 'access' && (
<div className="access-tab">
<div className="info-card">
<h3>HTTP Access</h3>
<p className="text-muted">Access Gitea through your web browser</p>
<div className="access-url">
<code>http://{window.location.hostname}:{status?.http_port}</code>
<button
className="btn btn-sm btn-secondary"
onClick={() => {
navigator.clipboard.writeText(`http://${window.location.hostname}:${status?.http_port}`);
toast.success('URL copied');
}}
Copy link

Copilot AI Jan 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The clipboard write operations (lines 339 and 360) do not handle potential errors. The navigator.clipboard API can fail for various reasons (permissions, insecure context, etc.). Add error handling with try-catch blocks to gracefully handle failures and inform the user.

Copilot uses AI. Check for mistakes.
Comment on lines +704 to +714
# Save config with admin credentials and ports
config = {
'admin_user': admin_user,
'admin_email': admin_email,
'http_port': http_port,
'ssh_port': ssh_port,
'db_password': variables.get('DB_PASSWORD'),
'installed_at': datetime.now().isoformat(),
'version': '1.21'
}
cls._save_gitea_config(config)
Copy link

Copilot AI Jan 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Storing the admin_password in plaintext in the configuration file (line 710) poses a security risk. Even though a comment mentions it should be encrypted, the password is saved directly without encryption. Consider removing it from config storage or implementing proper encryption.

Copilot uses AI. Check for mistakes.
Comment thread serverkit
force_update=true
shift
;;
--branch|-b)
Copy link

Copilot AI Jan 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The argument parsing does not validate the branch parameter value. If --branch is provided without a value (e.g., at the end of arguments), $2 will be empty or the next argument, potentially causing unexpected behavior. Add validation to ensure target_branch is not empty after parsing.

Suggested change
--branch|-b)
--branch|-b)
if [[ -z "$2" || "$2" == -* ]]; then
echo -e "${RED}Error:${NC} --branch requires a branch name argument" >&2
exit 1
fi

Copilot uses AI. Check for mistakes.
Comment thread backend/app/api/git.py
Comment on lines +26 to +36
@git_bp.route('/install', methods=['POST'])
@jwt_required()
def install():
"""Install Gitea with PostgreSQL."""
data = request.get_json() or {}

result = GitService.install_gitea(
admin_user=data.get('adminUser', 'admin'),
admin_email=data.get('adminEmail'),
admin_password=data.get('adminPassword')
)
Copy link

Copilot AI Jan 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The install endpoint does not validate the admin_email parameter on the API layer. While frontend validation exists, backend validation is essential for API security. Add validation to ensure admin_email is provided and properly formatted before proceeding with installation.

Copilot uses AI. Check for mistakes.
Comment thread GITEA_INTEGRATION_PLAN.md
Comment on lines +248 to +252
# Save config with admin credentials
config = {
'admin_user': admin_user,
'admin_email': admin_email,
'admin_password': admin_password, # Should be encrypted
Copy link

Copilot AI Jan 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation shows storing admin_password in plaintext with a comment 'Should be encrypted' (line 252). This same security issue exists in the actual implementation. The documentation should be updated to reflect proper security practices or the note should emphasize this is a known security concern that must be addressed.

Suggested change
# Save config with admin credentials
config = {
'admin_user': admin_user,
'admin_email': admin_email,
'admin_password': admin_password, # Should be encrypted
# Save config (do NOT store admin password in plaintext)
config = {
'admin_user': admin_user,
'admin_email': admin_email,

Copilot uses AI. Check for mistakes.
Comment on lines +754 to +760
# Remove from database
db.session.delete(app)
db.session.commit()

# Remove config
if os.path.exists(cls.GITEA_CONFIG_FILE):
os.remove(cls.GITEA_CONFIG_FILE)
Copy link

Copilot AI Jan 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The uninstall_gitea method has a potential database rollback issue. If os.remove(cls.GITEA_CONFIG_FILE) fails after the database commit (line 756), the Application will be deleted from the database but the config file will remain, causing an inconsistent state. Consider wrapping all operations in a try-catch or moving the file deletion before the database commit.

Copilot uses AI. Check for mistakes.
Comment on lines +670 to +672
def install_gitea(cls, admin_user: str = 'admin',
admin_email: str = None,
admin_password: str = None) -> Dict:
Copy link

Copilot AI Jan 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing validation for required admin_email parameter. The email is required for Gitea installation but the function accepts None without validation, which could lead to installation failures.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants