mirror of https://github.com/sysown/proxysql
Workflow trigger chain fix: - All 24 test workflows now trigger on CI-builds completion instead of CI-trigger completion, ensuring build artifacts are available before tests start New test group workflows: - Add CI-legacy-g1, CI-legacy-g3, CI-legacy-g5 - Add CI-mysql84-g1 through CI-mysql84-g5 - All use the generic ci-taptests-groups.yml reusable workflow groups.json linter: - Add lint_groups_json.py enforcing compact one-line-per-entry format - Add CI-lint-groups-json.yml workflow triggered on groups.json changes - Reformat groups.json to comply with documented format Makefile fixes: - Fix $(error) call with unescaped ')' that broke all docker-compose builds since Release 3.0.8 - Fix CURVER extraction regex to handle 'v' prefix from git describe CI-taptests-pgsql-cluster rewrite: - Replace old jenkins-build-scripts with Unified CI infrastructure - Use ensure-infras.bash + run-tests-isolated.bash Infrastructure improvements: - Add --hostname test-runner to test-runner container for cross-container DNS resolution - Pass TAP_PGSQL_SYNC_REPLICA_PORT through to test container - Default TAP_PGSQL_SYNC_REPLICA_PORT=6042 when cluster nodes activepull/5590/head
parent
21b3e238ee
commit
9671a414a3
@ -0,0 +1,21 @@
|
||||
name: CI-legacy-g1
|
||||
run-name: '${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }} ${{ github.workflow }} ${{ github.event.workflow_run && github.event.workflow_run.head_sha || github.sha }}'
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
workflow_run:
|
||||
workflows: [ CI-builds ]
|
||||
types: [ completed ]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
run:
|
||||
if: ${{ github.event.workflow_run && github.event.workflow_run.conclusion == 'success' || ! github.event.workflow_run }}
|
||||
uses: sysown/proxysql/.github/workflows/ci-taptests-groups.yml@GH-Actions
|
||||
secrets: inherit
|
||||
with:
|
||||
trigger: ${{ toJson(github) }}
|
||||
testgroup: '["legacy-g1"]'
|
||||
@ -0,0 +1,21 @@
|
||||
name: CI-legacy-g3
|
||||
run-name: '${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }} ${{ github.workflow }} ${{ github.event.workflow_run && github.event.workflow_run.head_sha || github.sha }}'
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
workflow_run:
|
||||
workflows: [ CI-builds ]
|
||||
types: [ completed ]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
run:
|
||||
if: ${{ github.event.workflow_run && github.event.workflow_run.conclusion == 'success' || ! github.event.workflow_run }}
|
||||
uses: sysown/proxysql/.github/workflows/ci-taptests-groups.yml@GH-Actions
|
||||
secrets: inherit
|
||||
with:
|
||||
trigger: ${{ toJson(github) }}
|
||||
testgroup: '["legacy-g3"]'
|
||||
@ -0,0 +1,21 @@
|
||||
name: CI-legacy-g5
|
||||
run-name: '${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }} ${{ github.workflow }} ${{ github.event.workflow_run && github.event.workflow_run.head_sha || github.sha }}'
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
workflow_run:
|
||||
workflows: [ CI-builds ]
|
||||
types: [ completed ]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
run:
|
||||
if: ${{ github.event.workflow_run && github.event.workflow_run.conclusion == 'success' || ! github.event.workflow_run }}
|
||||
uses: sysown/proxysql/.github/workflows/ci-taptests-groups.yml@GH-Actions
|
||||
secrets: inherit
|
||||
with:
|
||||
trigger: ${{ toJson(github) }}
|
||||
testgroup: '["legacy-g5"]'
|
||||
@ -0,0 +1,17 @@
|
||||
name: CI-lint-groups-json
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- 'test/tap/groups/groups.json'
|
||||
push:
|
||||
paths:
|
||||
- 'test/tap/groups/groups.json'
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Lint groups.json format
|
||||
run: python3 test/tap/groups/lint_groups_json.py
|
||||
@ -0,0 +1,21 @@
|
||||
name: CI-mysql84-g1
|
||||
run-name: '${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }} ${{ github.workflow }} ${{ github.event.workflow_run && github.event.workflow_run.head_sha || github.sha }}'
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
workflow_run:
|
||||
workflows: [ CI-builds ]
|
||||
types: [ completed ]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
run:
|
||||
if: ${{ github.event.workflow_run && github.event.workflow_run.conclusion == 'success' || ! github.event.workflow_run }}
|
||||
uses: sysown/proxysql/.github/workflows/ci-taptests-groups.yml@GH-Actions
|
||||
secrets: inherit
|
||||
with:
|
||||
trigger: ${{ toJson(github) }}
|
||||
testgroup: '["mysql84-g1"]'
|
||||
@ -0,0 +1,21 @@
|
||||
name: CI-mysql84-g2
|
||||
run-name: '${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }} ${{ github.workflow }} ${{ github.event.workflow_run && github.event.workflow_run.head_sha || github.sha }}'
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
workflow_run:
|
||||
workflows: [ CI-builds ]
|
||||
types: [ completed ]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
run:
|
||||
if: ${{ github.event.workflow_run && github.event.workflow_run.conclusion == 'success' || ! github.event.workflow_run }}
|
||||
uses: sysown/proxysql/.github/workflows/ci-taptests-groups.yml@GH-Actions
|
||||
secrets: inherit
|
||||
with:
|
||||
trigger: ${{ toJson(github) }}
|
||||
testgroup: '["mysql84-g2"]'
|
||||
@ -0,0 +1,21 @@
|
||||
name: CI-mysql84-g3
|
||||
run-name: '${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }} ${{ github.workflow }} ${{ github.event.workflow_run && github.event.workflow_run.head_sha || github.sha }}'
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
workflow_run:
|
||||
workflows: [ CI-builds ]
|
||||
types: [ completed ]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
run:
|
||||
if: ${{ github.event.workflow_run && github.event.workflow_run.conclusion == 'success' || ! github.event.workflow_run }}
|
||||
uses: sysown/proxysql/.github/workflows/ci-taptests-groups.yml@GH-Actions
|
||||
secrets: inherit
|
||||
with:
|
||||
trigger: ${{ toJson(github) }}
|
||||
testgroup: '["mysql84-g3"]'
|
||||
@ -0,0 +1,21 @@
|
||||
name: CI-mysql84-g4
|
||||
run-name: '${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }} ${{ github.workflow }} ${{ github.event.workflow_run && github.event.workflow_run.head_sha || github.sha }}'
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
workflow_run:
|
||||
workflows: [ CI-builds ]
|
||||
types: [ completed ]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
run:
|
||||
if: ${{ github.event.workflow_run && github.event.workflow_run.conclusion == 'success' || ! github.event.workflow_run }}
|
||||
uses: sysown/proxysql/.github/workflows/ci-taptests-groups.yml@GH-Actions
|
||||
secrets: inherit
|
||||
with:
|
||||
trigger: ${{ toJson(github) }}
|
||||
testgroup: '["mysql84-g4"]'
|
||||
@ -0,0 +1,21 @@
|
||||
name: CI-mysql84-g5
|
||||
run-name: '${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }} ${{ github.workflow }} ${{ github.event.workflow_run && github.event.workflow_run.head_sha || github.sha }}'
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
workflow_run:
|
||||
workflows: [ CI-builds ]
|
||||
types: [ completed ]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
run:
|
||||
if: ${{ github.event.workflow_run && github.event.workflow_run.conclusion == 'success' || ! github.event.workflow_run }}
|
||||
uses: sysown/proxysql/.github/workflows/ci-taptests-groups.yml@GH-Actions
|
||||
secrets: inherit
|
||||
with:
|
||||
trigger: ${{ toJson(github) }}
|
||||
testgroup: '["mysql84-g5"]'
|
||||
@ -0,0 +1,93 @@
|
||||
name: CI-taptests-pgsql-cluster
|
||||
run-name: '${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }} ${{ github.workflow }} ${{ github.event.workflow_run && github.event.workflow_run.head_sha || github.sha }}'
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
workflow_run:
|
||||
workflows: [ CI-builds ]
|
||||
types: [ completed ]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.workflow_run && github.event.workflow_run.head_branch || github.ref_name }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
SHA: ${{ github.event.workflow_run && github.event.workflow_run.head_sha || github.sha }}
|
||||
|
||||
jobs:
|
||||
tests:
|
||||
runs-on: ubuntu-22.04
|
||||
if: ${{ github.event.workflow_run && github.event.workflow_run.conclusion == 'success' || ! github.event.workflow_run }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
testdist: [ 'ubuntu22-tap' ]
|
||||
env:
|
||||
TESTDIST: ${{ matrix.testdist }}
|
||||
BLDCACHE: ${{ github.event.workflow_run && github.event.workflow_run.head_sha || github.sha }}_${{ matrix.testdist }}
|
||||
|
||||
steps:
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Cache restore src
|
||||
id: cache-src
|
||||
uses: actions/cache/restore@v4
|
||||
with:
|
||||
key: ${{ env.BLDCACHE }}_src
|
||||
fail-on-cache-miss: true
|
||||
path: |
|
||||
src/
|
||||
|
||||
- name: Cache restore test
|
||||
id: cache-test
|
||||
uses: actions/cache/restore@v4
|
||||
with:
|
||||
key: ${{ env.BLDCACHE }}_test
|
||||
fail-on-cache-miss: true
|
||||
path: |
|
||||
test/
|
||||
|
||||
- name: Build CI base image
|
||||
run: |
|
||||
cd test/infra/docker-base
|
||||
docker build --network host -t proxysql-ci-base:latest .
|
||||
|
||||
- name: Start infrastructure
|
||||
run: |
|
||||
export WORKSPACE="${GITHUB_WORKSPACE}"
|
||||
export INFRA_ID="pgsql-cluster-${GITHUB_RUN_ID}"
|
||||
export TAP_GROUP="legacy-g3"
|
||||
export TEST_PY_TAP_INCL="test_cluster_sync_pgsql-t"
|
||||
export PROXYSQL_CLUSTER_NODES=2
|
||||
source test/infra/common/env.sh
|
||||
./test/infra/control/ensure-infras.bash
|
||||
|
||||
- name: Run test_cluster_sync_pgsql-t
|
||||
run: |
|
||||
export WORKSPACE="${GITHUB_WORKSPACE}"
|
||||
export INFRA_ID="pgsql-cluster-${GITHUB_RUN_ID}"
|
||||
export TAP_GROUP="legacy-g3"
|
||||
export TEST_PY_TAP_INCL="test_cluster_sync_pgsql-t"
|
||||
export PROXYSQL_CLUSTER_NODES=2
|
||||
source test/infra/common/env.sh
|
||||
./test/infra/control/run-tests-isolated.bash
|
||||
|
||||
- name: Cleanup
|
||||
if: always()
|
||||
run: |
|
||||
export WORKSPACE="${GITHUB_WORKSPACE}"
|
||||
export INFRA_ID="pgsql-cluster-${GITHUB_RUN_ID}"
|
||||
export TAP_GROUP="legacy-g3"
|
||||
source test/infra/common/env.sh
|
||||
./test/infra/control/stop-proxysql-isolated.bash || true
|
||||
./test/infra/control/destroy-infras.bash || true
|
||||
|
||||
- name: Archive logs
|
||||
if: ${{ failure() && !cancelled() }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ github.workflow }}-${{ env.SHA }}-logs-run${{ github.run_number }}
|
||||
path: |
|
||||
ci_infra_logs/
|
||||
@ -0,0 +1,119 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Lint groups.json for format compliance.
|
||||
|
||||
Enforces the conventions documented in test/tap/groups/README.md:
|
||||
- Valid JSON
|
||||
- One entry per line, compact arrays (no multi-line)
|
||||
- Format: ' "test-name-t" : [ "group1","group2" ],' (or no comma for last)
|
||||
- Keys sorted alphabetically
|
||||
- File starts with '{' and ends with '}'
|
||||
|
||||
Exit codes:
|
||||
0 - Format is correct
|
||||
1 - Format violations found
|
||||
"""
|
||||
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
|
||||
def main():
|
||||
groups_path = os.path.join(os.path.dirname(__file__), "groups.json")
|
||||
if len(sys.argv) > 1:
|
||||
groups_path = sys.argv[1]
|
||||
|
||||
if not os.path.isfile(groups_path):
|
||||
print(f"ERROR: {groups_path} not found", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
with open(groups_path, "r") as f:
|
||||
raw = f.read()
|
||||
|
||||
lines = raw.split("\n")
|
||||
errors = []
|
||||
|
||||
# Check 1: valid JSON
|
||||
try:
|
||||
data = json.loads(raw)
|
||||
except json.JSONDecodeError as e:
|
||||
errors.append(f"Invalid JSON: {e}")
|
||||
# Can't do further checks
|
||||
for e in errors:
|
||||
print(f"ERROR: {e}", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
if not isinstance(data, dict):
|
||||
errors.append("Top-level value must be a JSON object")
|
||||
for e in errors:
|
||||
print(f"ERROR: {e}", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
# Check 2: first and last lines
|
||||
if not lines or lines[0].strip() != "{":
|
||||
errors.append("Line 1: must be '{'")
|
||||
if lines[-1].strip() == "":
|
||||
# Allow trailing newline — check second-to-last
|
||||
if len(lines) < 2 or lines[-2].strip() != "}":
|
||||
errors.append(f"Last non-empty line: must be '}}'")
|
||||
elif lines[-1].strip() != "}":
|
||||
errors.append(f"Last line: must be '}}'")
|
||||
|
||||
# Check 3: each entry is one line with correct format
|
||||
entry_pattern = re.compile(
|
||||
r'^ "([^"]+)" : \[ .+ \](,?)$'
|
||||
)
|
||||
keys_in_order = []
|
||||
entry_lines = lines[1:] # skip opening brace
|
||||
for i, line in enumerate(entry_lines, start=2):
|
||||
stripped = line.strip()
|
||||
if stripped == "}" or stripped == "":
|
||||
continue
|
||||
m = entry_pattern.match(line)
|
||||
if not m:
|
||||
errors.append(
|
||||
f"Line {i}: does not match expected format "
|
||||
f"' \"test-name\" : [ \"group1\",\"group2\" ],' "
|
||||
f"Got: {line!r}"
|
||||
)
|
||||
else:
|
||||
keys_in_order.append(m.group(1))
|
||||
|
||||
# Check 4: keys are sorted
|
||||
if keys_in_order != sorted(keys_in_order):
|
||||
# Find first out-of-order key
|
||||
for j in range(len(keys_in_order) - 1):
|
||||
if keys_in_order[j] > keys_in_order[j + 1]:
|
||||
errors.append(
|
||||
f"Keys not sorted: '{keys_in_order[j + 1]}' "
|
||||
f"should come before '{keys_in_order[j]}'"
|
||||
)
|
||||
break
|
||||
|
||||
# Check 5: last entry has no trailing comma, others do
|
||||
entry_indices = []
|
||||
for i, line in enumerate(lines):
|
||||
if entry_pattern.match(line):
|
||||
entry_indices.append(i)
|
||||
if entry_indices:
|
||||
for idx in entry_indices[:-1]:
|
||||
if not lines[idx].rstrip().endswith(","):
|
||||
errors.append(f"Line {idx + 1}: non-last entry must end with comma")
|
||||
last_idx = entry_indices[-1]
|
||||
if lines[last_idx].rstrip().endswith(","):
|
||||
errors.append(f"Line {last_idx + 1}: last entry must not end with comma")
|
||||
|
||||
if errors:
|
||||
print(f"groups.json format lint: {len(errors)} error(s) found:", file=sys.stderr)
|
||||
for e in errors:
|
||||
print(f" {e}", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
print(f"groups.json format lint: OK ({len(data)} entries, sorted, compact)")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Loading…
Reference in new issue