mirror of
https://github.com/Xahau/xahaud.git
synced 2025-11-22 19:45:49 +00:00
experiment: testing
This commit is contained in:
102
.ci/gitea.py
102
.ci/gitea.py
@@ -6,6 +6,34 @@ Persistent Gitea for Conan on Self-Hosted GA Runner
|
|||||||
- Idempotent - safe to run multiple times
|
- Idempotent - safe to run multiple times
|
||||||
- Reuses existing container if already running
|
- Reuses existing container if already running
|
||||||
- Uses pre-baked app.ini to bypass web setup wizard
|
- Uses pre-baked app.ini to bypass web setup wizard
|
||||||
|
|
||||||
|
What This Script Uses Conan For
|
||||||
|
--------------------------------
|
||||||
|
This script uses Conan only for testing and verification:
|
||||||
|
- Configures conan client to add Gitea as a remote repository
|
||||||
|
- Tests the repository by uploading/downloading a sample package (zlib)
|
||||||
|
- Verifies authentication and package management work correctly
|
||||||
|
- Does NOT build or manage your actual project dependencies
|
||||||
|
|
||||||
|
Your actual Conan package building happens in GitHub Actions workflows,
|
||||||
|
not in this setup script. This script just ensures the repository is ready.
|
||||||
|
|
||||||
|
Docker Networking
|
||||||
|
-----------------
|
||||||
|
The Gitea container can be accessed two ways:
|
||||||
|
|
||||||
|
1. From the host machine (where this script runs):
|
||||||
|
http://localhost:3000
|
||||||
|
|
||||||
|
2. From other Docker containers (e.g., GitHub Actions jobs):
|
||||||
|
http://gitea-conan-persistent:3000
|
||||||
|
|
||||||
|
Containers can reach Gitea by its container name through Docker's
|
||||||
|
default bridge network. No network configuration changes needed.
|
||||||
|
|
||||||
|
Example in GitHub Actions workflow running in a container:
|
||||||
|
conan remote add gitea-local http://gitea-conan-persistent:3000/api/packages/conan/conan
|
||||||
|
conan user -p conan-pass-2024 -r gitea-local conan
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
@@ -98,6 +126,9 @@ class PersistentGiteaConan:
|
|||||||
# Conan execution context cache
|
# Conan execution context cache
|
||||||
self._conan_prefix: Optional[str] = None # '' for direct, full sudo+shell for delegated; None if unavailable
|
self._conan_prefix: Optional[str] = None # '' for direct, full sudo+shell for delegated; None if unavailable
|
||||||
|
|
||||||
|
# Track sensitive values that should be masked in logs
|
||||||
|
self._sensitive_values: set = {self.passwd} # Start with password
|
||||||
|
|
||||||
def _setup_logging(self, debug: bool, verbose: bool):
|
def _setup_logging(self, debug: bool, verbose: bool):
|
||||||
# Determine level: debug > verbose > default WARNING
|
# Determine level: debug > verbose > default WARNING
|
||||||
if debug:
|
if debug:
|
||||||
@@ -111,20 +142,51 @@ class PersistentGiteaConan:
|
|||||||
# Be slightly quieter for noisy libs
|
# Be slightly quieter for noisy libs
|
||||||
logging.getLogger('urllib3').setLevel(logging.WARNING)
|
logging.getLogger('urllib3').setLevel(logging.WARNING)
|
||||||
|
|
||||||
def run(self, cmd, check=True, env=None):
|
def _mask_sensitive(self, text: str) -> str:
|
||||||
"""Run command with minimal output"""
|
"""Mask any sensitive values in text for safe logging"""
|
||||||
|
if not text:
|
||||||
|
return text
|
||||||
|
masked = text
|
||||||
|
for sensitive in self._sensitive_values:
|
||||||
|
if sensitive and sensitive in masked:
|
||||||
|
masked = masked.replace(sensitive, "***REDACTED***")
|
||||||
|
return masked
|
||||||
|
|
||||||
|
def run(self, cmd, check=True, env=None, sensitive=False):
|
||||||
|
"""Run command with minimal output
|
||||||
|
|
||||||
|
Args:
|
||||||
|
cmd: Command to run
|
||||||
|
check: Raise exception on non-zero exit
|
||||||
|
env: Environment variables
|
||||||
|
sensitive: If True, command and output are completely hidden
|
||||||
|
"""
|
||||||
run_env = os.environ.copy()
|
run_env = os.environ.copy()
|
||||||
if env:
|
if env:
|
||||||
run_env.update(env)
|
run_env.update(env)
|
||||||
self.logger.debug(f"EXEC: {cmd}")
|
|
||||||
|
# Log command (masked or hidden based on sensitivity)
|
||||||
|
if sensitive:
|
||||||
|
self.logger.debug("EXEC: [sensitive command hidden]")
|
||||||
|
else:
|
||||||
|
self.logger.debug(f"EXEC: {self._mask_sensitive(cmd)}")
|
||||||
|
|
||||||
result = subprocess.run(cmd, shell=True, capture_output=True, text=True, env=run_env)
|
result = subprocess.run(cmd, shell=True, capture_output=True, text=True, env=run_env)
|
||||||
|
|
||||||
|
# Log output (masked or hidden based on sensitivity)
|
||||||
|
if not sensitive:
|
||||||
if result.stdout:
|
if result.stdout:
|
||||||
self.logger.debug(f"STDOUT: {result.stdout.strip()}"[:1000])
|
self.logger.debug(f"STDOUT: {self._mask_sensitive(result.stdout.strip())}"[:1000])
|
||||||
if result.stderr:
|
if result.stderr:
|
||||||
self.logger.debug(f"STDERR: {result.stderr.strip()}"[:1000])
|
self.logger.debug(f"STDERR: {self._mask_sensitive(result.stderr.strip())}"[:1000])
|
||||||
|
|
||||||
if result.returncode != 0 and check:
|
if result.returncode != 0 and check:
|
||||||
self.logger.error(f"Command failed ({result.returncode}) for: {cmd}")
|
if sensitive:
|
||||||
raise RuntimeError(f"Command failed: {result.stderr}")
|
self.logger.error(f"Command failed ({result.returncode})")
|
||||||
|
raise RuntimeError("Command failed (details hidden for security)")
|
||||||
|
else:
|
||||||
|
self.logger.error(f"Command failed ({result.returncode}) for: {self._mask_sensitive(cmd)}")
|
||||||
|
raise RuntimeError(f"Command failed: {self._mask_sensitive(result.stderr)}")
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def is_running(self):
|
def is_running(self):
|
||||||
@@ -183,8 +245,12 @@ class PersistentGiteaConan:
|
|||||||
def _generate_secret(self, secret_type):
|
def _generate_secret(self, secret_type):
|
||||||
"""Generate a secret using Gitea's built-in generator"""
|
"""Generate a secret using Gitea's built-in generator"""
|
||||||
cmd = f"docker run --rm gitea/gitea:latest gitea generate secret {secret_type}"
|
cmd = f"docker run --rm gitea/gitea:latest gitea generate secret {secret_type}"
|
||||||
result = self.run(cmd)
|
result = self.run(cmd, sensitive=True) # Don't log the output
|
||||||
return result.stdout.strip()
|
secret = result.stdout.strip()
|
||||||
|
if secret:
|
||||||
|
self._sensitive_values.add(secret) # Track this secret for masking
|
||||||
|
self.logger.debug(f"Generated {secret_type} successfully")
|
||||||
|
return secret
|
||||||
|
|
||||||
def _create_app_ini(self, gitea_conf_dir):
|
def _create_app_ini(self, gitea_conf_dir):
|
||||||
"""Create a pre-configured app.ini file"""
|
"""Create a pre-configured app.ini file"""
|
||||||
@@ -547,6 +613,18 @@ SHOW_FOOTER_VERSION = false
|
|||||||
return Dummy()
|
return Dummy()
|
||||||
return self.run(full_cmd, check=check)
|
return self.run(full_cmd, check=check)
|
||||||
|
|
||||||
|
def _run_conan_sensitive(self, inner_args: str, check: bool = False):
|
||||||
|
"""Run a sensitive Conan subcommand (e.g., with passwords) using the resolved execution context."""
|
||||||
|
full_cmd = self._build_conan_cmd(inner_args)
|
||||||
|
if full_cmd is None:
|
||||||
|
class Dummy:
|
||||||
|
returncode = 127
|
||||||
|
stdout = ''
|
||||||
|
stderr = 'conan: not found'
|
||||||
|
self.logger.error("❌ Conan CLI is not available. Skipping sensitive command")
|
||||||
|
return Dummy()
|
||||||
|
return self.run(full_cmd, check=check, sensitive=True)
|
||||||
|
|
||||||
def _create_user(self):
|
def _create_user(self):
|
||||||
"""Create Conan user (idempotent)"""
|
"""Create Conan user (idempotent)"""
|
||||||
self.logger.info("👤 Setting up admin user...")
|
self.logger.info("👤 Setting up admin user...")
|
||||||
@@ -569,7 +647,7 @@ SHOW_FOOTER_VERSION = false
|
|||||||
--email {self.email} \
|
--email {self.email} \
|
||||||
--admin \
|
--admin \
|
||||||
--must-change-password=false"""
|
--must-change-password=false"""
|
||||||
create_res = self.run(create_cmd, check=False)
|
create_res = self.run(create_cmd, check=False, sensitive=True)
|
||||||
if create_res.returncode == 0:
|
if create_res.returncode == 0:
|
||||||
self.logger.info(f"✅ Created admin user: {self.user}")
|
self.logger.info(f"✅ Created admin user: {self.user}")
|
||||||
return
|
return
|
||||||
@@ -602,8 +680,8 @@ SHOW_FOOTER_VERSION = false
|
|||||||
# Add Gitea as remote (localhost only)
|
# Add Gitea as remote (localhost only)
|
||||||
self._run_conan(f"remote add gitea-local {conan_url}")
|
self._run_conan(f"remote add gitea-local {conan_url}")
|
||||||
|
|
||||||
# Authenticate (Conan masks password in process list)
|
# Authenticate (mark as sensitive even though Conan masks password in process list)
|
||||||
self._run_conan(f"user -p {self.passwd} -r gitea-local {self.user}")
|
self._run_conan_sensitive(f"user -p {self.passwd} -r gitea-local {self.user}")
|
||||||
|
|
||||||
# Enable revisions if not already
|
# Enable revisions if not already
|
||||||
self._run_conan("config set general.revisions_enabled=1", check=False)
|
self._run_conan("config set general.revisions_enabled=1", check=False)
|
||||||
|
|||||||
8
.github/workflows/build-in-docker.yml
vendored
8
.github/workflows/build-in-docker.yml
vendored
@@ -58,8 +58,14 @@ jobs:
|
|||||||
pipx install "conan<2.0"
|
pipx install "conan<2.0"
|
||||||
/root/.local/bin/conan --version # PATH doesn't seem to be set correctly
|
/root/.local/bin/conan --version # PATH doesn't seem to be set correctly
|
||||||
|
|
||||||
- name: Verify Gitea
|
- name: Teardown && Verify Gitea
|
||||||
run: |
|
run: |
|
||||||
|
PATH="/root/.local/bin:$PATH" python .ci/gitea.py teardown --debug || true
|
||||||
|
PATH="/root/.local/bin:$PATH" python .ci/gitea.py verify --debug || PATH="/root/.local/bin:$PATH" python .ci/gitea.py setup --debug
|
||||||
|
|
||||||
|
- name: Setup network
|
||||||
|
run: |
|
||||||
|
PATH="/root/.local/bin:$PATH" python .ci/gitea.py teardown --debug || true
|
||||||
PATH="/root/.local/bin:$PATH" python .ci/gitea.py verify --debug || PATH="/root/.local/bin:$PATH" python .ci/gitea.py setup --debug
|
PATH="/root/.local/bin:$PATH" python .ci/gitea.py verify --debug || PATH="/root/.local/bin:$PATH" python .ci/gitea.py setup --debug
|
||||||
|
|
||||||
- name: Test Gitea from build container
|
- name: Test Gitea from build container
|
||||||
|
|||||||
Reference in New Issue
Block a user