Zjednotenie Git runnera

This commit is contained in:
Ján Pták 2026-11-06 00:58:12 +01:00
parent e735b52c06
commit 7239620574
4 changed files with 57 additions and 23 deletions

View File

@ -2,11 +2,12 @@
# Manage this runner without changing the API/Neo4j/MCP Compose project.
set -euo pipefail
runner_root="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
env_file="$runner_root/.env"
project_root="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
runner_root="$project_root/tools/git_runner"
env_file="$project_root/.env"
usage() {
echo "Pouzitie: bash tools/git_runner/runner.sh {init|up|status|logs|stop}"
echo "Pouzitie: bash scripts/zpwiki-sync.sh {init|up|status|logs|stop}"
}
if [[ $# -ne 1 ]]; then
@ -19,9 +20,12 @@ if [[ "$1" == "init" ]]; then
mkdir -p "$runner_root/data"
chmod 700 "$runner_root/data"
if [[ ! -e "$env_file" ]]; then
cp "$runner_root/runner.env.example" "$env_file"
touch "$env_file"
fi
chmod 600 "$env_file"
if ! grep -Eq '^[[:space:]]*(export[[:space:]]+)?RUNNER_REGISTRATION_TOKEN[[:space:]]*=' "$env_file"; then
printf '\n# Gitea Actions runner\nRUNNER_REGISTRATION_TOKEN=\n' >> "$env_file"
fi
echo "Vypln RUNNER_REGISTRATION_TOKEN v $env_file a potom spusti prikaz up."
exit 0
fi
@ -33,7 +37,7 @@ case "$1" in
esac
if [[ ! -f "$env_file" ]]; then
echo "Najprv spusti: bash tools/git_runner/runner.sh init" >&2
echo "Najprv spusti: bash scripts/zpwiki-sync.sh init" >&2
exit 1
fi

View File

@ -12,6 +12,7 @@ import yaml
ROOT = Path(__file__).resolve().parents[1]
RUNNER = ROOT / 'tools/git_runner'
LAUNCHER = ROOT / 'scripts/zpwiki-sync.sh'
FORK = 'git@git.kemt.fei.tuke.sk:jp170na/zpwiki.git'
UPSTREAM = 'git@git.kemt.fei.tuke.sk:KEMT/zpwiki.git'
@ -177,26 +178,53 @@ def test_unknown_options_never_change_fork(repositories, args):
assert git(fork, 'rev-parse', 'master') == before
def test_runner_init_preserves_existing_private_token(tmp_path):
for name in ['runner.sh', 'runner.env.example']:
shutil.copy2(RUNNER / name, tmp_path / name)
command = ['bash', str(tmp_path / 'runner.sh'), 'init']
def helper_layout(root):
launcher=root / 'scripts/zpwiki-sync.sh'
launcher.parent.mkdir()
shutil.copy2(LAUNCHER,launcher)
config=root / 'tools/git_runner'
config.mkdir(parents=True)
shutil.copy2(RUNNER / 'compose.yml',config / 'compose.yml')
return launcher,config
def test_runner_init_preserves_main_env_and_existing_private_token(tmp_path):
launcher,config=helper_layout(tmp_path)
command = ['bash', str(launcher), 'init']
subprocess.run(command, check=True, capture_output=True)
env = tmp_path / '.env'
env.write_text('RUNNER_REGISTRATION_TOKEN=private-test-value\n')
content='SEARCH_API_KEY=existing-api-value\nRUNNER_REGISTRATION_TOKEN=private-test-value\n'
env.write_text(content)
env.chmod(0o644)
result = subprocess.run(command, check=True, capture_output=True, text=True)
assert env.read_text() == 'RUNNER_REGISTRATION_TOKEN=private-test-value\n'
assert env.read_text() == content
assert stat.S_IMODE(env.stat().st_mode) == 0o600
assert stat.S_IMODE((tmp_path / 'data').stat().st_mode) == 0o700
assert stat.S_IMODE((config / 'data').stat().st_mode) == 0o700
assert not (config / '.env').exists()
assert 'private-test-value' not in result.stdout + result.stderr
def test_runner_init_adds_token_setting_without_changing_backend_settings(tmp_path):
launcher,config=helper_layout(tmp_path)
env=tmp_path / '.env'
content='SEARCH_API_KEY=existing-api-value\nNEO4J_DATABASE=neo4j\n'
env.write_text(content)
command=['bash',str(launcher),'init']
subprocess.run(command,check=True,capture_output=True)
updated=env.read_text()
assert updated.startswith(content)
assert updated.count('RUNNER_REGISTRATION_TOKEN=')==1
subprocess.run(command,check=True,capture_output=True)
assert env.read_text()==updated
assert not (config / '.env').exists()
def test_runner_helper_targets_only_its_own_compose_project(tmp_path):
for name in ['runner.sh', 'runner.env.example', 'compose.yml']:
shutil.copy2(RUNNER / name, tmp_path / name)
subprocess.run(['bash', str(tmp_path / 'runner.sh'), 'init'], check=True, capture_output=True)
launcher,config=helper_layout(tmp_path)
subprocess.run(['bash', str(launcher), 'init'], check=True, capture_output=True)
(tmp_path / '.env').write_text('RUNNER_REGISTRATION_TOKEN=private-test-value\n')
registration=config / 'data/.runner'
registration.write_text('{"id":1,"token":"keep-existing-registration"}')
executable = tmp_path / 'bin/docker'
executable.parent.mkdir()
executable.write_text('#!/usr/bin/env python3\nimport json,os,sys\n'
@ -206,7 +234,7 @@ def test_runner_helper_targets_only_its_own_compose_project(tmp_path):
record = tmp_path / 'commands.jsonl'
env = {**os.environ, 'PATH':str(executable.parent)+os.pathsep+os.environ['PATH'],
'ZP_DOCKER_CONTEXT':'fixture-context', 'RECORDED_COMMANDS':str(record)}
subprocess.run(['bash', str(tmp_path / 'runner.sh'), 'up'], env=env, check=True, capture_output=True)
subprocess.run(['bash', str(launcher), 'up'], env=env, check=True, capture_output=True)
commands = [json.loads(row) for row in record.read_text().splitlines()]
assert len(commands) == 3
assert commands[0][-2:] == ['config','--quiet']
@ -214,8 +242,11 @@ def test_runner_helper_targets_only_its_own_compose_project(tmp_path):
for command in commands:
assert command[:2] == ['--context','fixture-context']
assert command[command.index('--project-name')+1] == 'zp-git-runner'
assert command[command.index('-f')+1] == str(tmp_path / 'compose.yml')
assert command[command.index('-f')+1] == str(config / 'compose.yml')
assert command[command.index('--env-file')+1] == str(tmp_path / '.env')
assert 'private-test-value' not in ' '.join(command)
assert registration.read_text()=='{"id":1,"token":"keep-existing-registration"}'
assert not (config / '.env').exists()
def test_daily_workflow_and_runner_configuration_match():
@ -226,6 +257,8 @@ def test_daily_workflow_and_runner_configuration_match():
job = workflow['jobs']['sync-wiki']
compose = yaml.safe_load((RUNNER / 'compose.yml').read_text())
runner = compose['services']['runner']
assert runner['container_name']=='zpwiki-sync'
assert runner['environment']['GITEA_RUNNER_NAME']=='zpwiki-sync'
assert runner['environment']['GITEA_RUNNER_LABELS'].startswith(job['runs-on']+':docker://')
assert 'RUNNER_REGISTRATION_TOKEN' in runner['environment']['GITEA_RUNNER_REGISTRATION_TOKEN']
step = job['steps'][-1]

View File

@ -3,12 +3,12 @@ name: zp-git-runner
services:
runner:
image: docker.io/gitea/act_runner:latest@sha256:b5c35d6bdbb9bb25e531230bfc7cc663cb751406cbec90a2a891b85fea54de86
container_name: zpwiki-actions-runner
container_name: zpwiki-sync
restart: unless-stopped
environment:
GITEA_INSTANCE_URL: https://git.kemt.fei.tuke.sk
GITEA_RUNNER_REGISTRATION_TOKEN: ${RUNNER_REGISTRATION_TOKEN:?Vypln registracny token v tools/git_runner/.env}
GITEA_RUNNER_NAME: zpwiki-sync-runner
GITEA_RUNNER_REGISTRATION_TOKEN: ${RUNNER_REGISTRATION_TOKEN:?Vypln RUNNER_REGISTRATION_TOKEN v hlavnom .env}
GITEA_RUNNER_NAME: zpwiki-sync
GITEA_RUNNER_LABELS: "zpwiki-sync:docker://alpine:3.22"
volumes:
- ./data:/data

View File

@ -1,3 +0,0 @@
# Registration token from dp-zp-agent -> Settings -> Actions -> Runners.
# This is NOT the ZPWIKI_SYNC_SSH_KEY used by the synchronization workflow.
RUNNER_REGISTRATION_TOKEN=