Files
recipe-maintainer/recipe-info/gitea/tests/git_push.py
autonomic-bot f283a371bb recipe-maintainer: public snapshot (secrets + deployment plans removed, single commit)
Sanitized single-commit public mirror of recipe-maintainer.
- Removed test-ssh/.testenv (live creds); added test-ssh/.testenv.example placeholders.
- Removed plans/ and planned-updates/ (deployment-planning docs) so no client/
  deployment domains appear in the public repo.
- All other secret stores were already gitignored.
- docs.coopcloud.tech retained as a submodule (public upstream).
2026-06-16 20:18:24 +00:00

162 lines
5.9 KiB
Python

#!/usr/bin/env python3
"""Test creating a repo and pushing a commit via HTTPS on Gitea."""
import argparse
import base64
import json
import os
import shutil
import subprocess
import sys
import tempfile
import time
import urllib.error
import urllib.request
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..', '..'))
from utils.tests.helpers import resolve_domain
WORKSPACE = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '..'))
def load_testsecrets(domain):
path = os.path.join(WORKSPACE, 'recipe-info', 'testsecrets', domain)
if not os.path.exists(path):
return {}
secrets = {}
with open(path) as f:
for line in f:
line = line.strip()
if '=' in line:
k, v = line.split('=', 1)
secrets[k.strip()] = v.strip()
return secrets
def api(method, url, data=None, token=None, username=None, password=None):
body = json.dumps(data).encode() if data is not None else None
req = urllib.request.Request(url, data=body, method=method)
req.add_header('Content-Type', 'application/json')
if token:
req.add_header('Authorization', f'token {token}')
elif username and password:
creds = base64.b64encode(f'{username}:{password}'.encode()).decode()
req.add_header('Authorization', f'Basic {creds}')
try:
with urllib.request.urlopen(req, timeout=15) as resp:
raw = resp.read()
return resp.getcode(), json.loads(raw) if raw else {}
except urllib.error.HTTPError as e:
raw = e.read().decode(errors='replace')
try:
return e.code, json.loads(raw)
except Exception:
return e.code, {}
def run_git(args, cwd, env=None):
result = subprocess.run(
['git'] + args, cwd=cwd, capture_output=True, text=True,
env={**os.environ, **(env or {})},
timeout=30,
)
if result.returncode != 0:
raise RuntimeError(f"git {' '.join(args)} failed:\n{result.stderr}")
return result.stdout.strip()
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--domain', default=os.environ.get('TEST_DOMAIN'))
parser.add_argument('--username', default=os.environ.get('GITEA_ADMIN_USER'))
parser.add_argument('--password', default=os.environ.get('GITEA_ADMIN_PASS'))
args = parser.parse_args()
domain = args.domain or resolve_domain('gitea')
base_url = f'https://{domain}'
# Load credentials from testsecrets if not provided via args/env
username = args.username
password = args.password
if not username or not password:
secrets = load_testsecrets(domain)
username = username or secrets.get('admin_username')
password = password or secrets.get('admin_password')
if not username or not password:
print(f'FAIL: No credentials found. Pass --username/--password or add '
f'admin_username/admin_password to recipe-info/testsecrets/{domain}')
sys.exit(1)
repo_name = f'test-push-{int(time.time())}'
print(f'Testing git push on {base_url} as {username} ...')
# 1. Create a test repo via API
print(f' Creating repo {repo_name} ...')
status, body = api('POST', f'{base_url}/api/v1/user/repos',
data={'name': repo_name, 'private': False,
'auto_init': False},
username=username, password=password)
if status != 201:
print(f'FAIL: Could not create repo (HTTP {status}): {body}')
sys.exit(1)
clone_url = body.get('clone_url') or f'{base_url}/{username}/{repo_name}.git'
print(f' Repo created: {clone_url}')
tmpdir = tempfile.mkdtemp(prefix='gitea-test-')
try:
# 2. Clone (empty) and make a commit
git_env = {
'GIT_AUTHOR_NAME': 'Test Bot',
'GIT_AUTHOR_EMAIL': 'test@example.com',
'GIT_COMMITTER_NAME': 'Test Bot',
'GIT_COMMITTER_EMAIL': 'test@example.com',
# Embed credentials in the URL via a helper config
'GIT_CONFIG_COUNT': '1',
'GIT_CONFIG_KEY_0': f'url.https://{username}:{password}@{domain}/.insteadOf',
'GIT_CONFIG_VALUE_0': f'https://{domain}/',
}
print(' Cloning repo ...')
run_git(['clone', clone_url, tmpdir], cwd='/tmp', env=git_env)
# Write a test file
test_file = os.path.join(tmpdir, 'README.md')
with open(test_file, 'w') as f:
f.write(f'# {repo_name}\n\nAutomated test commit.\n')
run_git(['add', 'README.md'], cwd=tmpdir, env=git_env)
run_git(['commit', '-m', 'test: automated push test'], cwd=tmpdir, env=git_env)
# 3. Push
print(' Pushing commit ...')
run_git(['push', 'origin', 'HEAD:main'], cwd=tmpdir, env=git_env)
print(' Push succeeded.')
# 4. Verify via API — check the commit landed
print(' Verifying commit via API ...')
status, commits = api('GET',
f'{base_url}/api/v1/repos/{username}/{repo_name}/commits?limit=1',
username=username, password=password)
if status != 200 or not commits:
print(f'FAIL: Could not verify commit via API (HTTP {status}): {commits}')
sys.exit(1)
commit_msg = commits[0].get('commit', {}).get('message', '').strip()
if 'automated push test' not in commit_msg:
print(f'FAIL: Unexpected commit message: {commit_msg!r}')
sys.exit(1)
print(f' Commit verified: {commit_msg!r}')
finally:
shutil.rmtree(tmpdir, ignore_errors=True)
# 5. Delete the test repo
print(f' Deleting test repo {repo_name} ...')
api('DELETE', f'{base_url}/api/v1/repos/{username}/{repo_name}',
username=username, password=password)
print('PASS: git push test completed successfully')
if __name__ == '__main__':
main()