clean up
CI Feature / Load example-gitea-env.conf to pipeline env (push) Successful in 20s
acc-tests Cucumber test report
CI Feature / Cucumber tests (push) Failing after 26s
unit-tests Bats test report
CI Feature / Bats tests (push) Failing after 1m25s
CI Feature / Report Summary (push) Successful in 5s
CI Feature / Load example-gitea-env.conf to pipeline env (push) Successful in 20s
acc-tests Cucumber test report
CI Feature / Cucumber tests (push) Failing after 26s
unit-tests Bats test report
CI Feature / Bats tests (push) Failing after 1m25s
CI Feature / Report Summary (push) Successful in 5s
This commit is contained in:
@@ -1,67 +0,0 @@
|
|||||||
name: POC GitOps E2E
|
|
||||||
run-name: "POC E2E (${{ inputs.dispatch_id || 'orchestrator' }})"
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- feature/gitops
|
|
||||||
workflow_dispatch:
|
|
||||||
inputs:
|
|
||||||
dispatch_id:
|
|
||||||
required: false
|
|
||||||
type: string
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
e2e:
|
|
||||||
if: github.event_name == 'push'
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Generate dispatch_id
|
|
||||||
id: gen
|
|
||||||
run: |
|
|
||||||
ID=$(date +%s | md5sum | head -c 8)
|
|
||||||
echo "dispatch_id=$ID" >> "$GITHUB_OUTPUT"
|
|
||||||
|
|
||||||
- name: Dispatch to gitea-ci-gitops-tests
|
|
||||||
run: |
|
|
||||||
INPUTS=$(jq -nc \
|
|
||||||
--arg dispatch_id "${{ steps.gen.outputs.dispatch_id }}" \
|
|
||||||
--arg file "dev/Chart.yaml" \
|
|
||||||
--arg yq_tpl '.version = "{{VERSION}}"' \
|
|
||||||
--arg version "0.2.0" \
|
|
||||||
--arg source_repo "${{ github.repository }}" \
|
|
||||||
--arg source_commit "${{ github.sha }}" \
|
|
||||||
--arg git_tag_prefix "poc-test" \
|
|
||||||
'{dispatch_id: $dispatch_id, file: $file, yq_tpl: $yq_tpl, version: $version, source_repo: $source_repo, source_commit: $source_commit, git_tag_prefix: $git_tag_prefix}')
|
|
||||||
curl -s -X POST \
|
|
||||||
"https://gitea.app.keskikuja.site/api/v1/repos/niko/gitea-ci-gitops-tests/actions/workflows/gitops-service.yaml/dispatches" \
|
|
||||||
-H "Authorization: token ${{ secrets.GITOPS_DISPATCH_TOKEN }}" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d "$(jq -nc --arg ref "main" --argjson inputs "$INPUTS" '{ref: "main", inputs: $inputs}')"
|
|
||||||
|
|
||||||
- name: Poll for completion
|
|
||||||
run: |
|
|
||||||
ID=${{ steps.gen.outputs.dispatch_id }}
|
|
||||||
for i in $(seq 1 60); do
|
|
||||||
RUNS=$(curl -s "https://gitea.app.keskikuja.site/api/v1/repos/niko/gitea-ci-gitops-tests/actions/runs?event=workflow_dispatch&limit=10" \
|
|
||||||
-H "Authorization: token ${{ secrets.GITOPS_DISPATCH_TOKEN }}")
|
|
||||||
FOUND=$(echo "$RUNS" | jq -r --arg id "$ID" \
|
|
||||||
'[.workflow_runs[] | select(.display_title | contains($id))] | .[0]')
|
|
||||||
if [ -n "$FOUND" ] && [ "$FOUND" != "null" ]; then
|
|
||||||
STATUS=$(echo "$FOUND" | jq -r '.status')
|
|
||||||
CONCLUSION=$(echo "$FOUND" | jq -r '.conclusion // ""')
|
|
||||||
RUN_NUM=$(echo "$FOUND" | jq -r '.run_number')
|
|
||||||
echo "run found: id=$(echo $FOUND | jq -r '.id') number=$RUN_NUM display_title=$(echo $FOUND | jq -r '.display_title') status=$STATUS"
|
|
||||||
if [ "$STATUS" = "completed" ]; then
|
|
||||||
if [ "$CONCLUSION" = "success" ]; then
|
|
||||||
echo "POC PASS: gitops workflow completed successfully"
|
|
||||||
exit 0
|
|
||||||
else
|
|
||||||
echo "POC FAIL: gitops workflow completed with conclusion=$CONCLUSION"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
sleep 5
|
|
||||||
done
|
|
||||||
echo "POC FAIL: timeout waiting for gitops workflow"
|
|
||||||
exit 124
|
|
||||||
@@ -1,189 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
#
|
|
||||||
# POC: testaa display_title-matchingia dispatchatuille workflow runeille.
|
|
||||||
#
|
|
||||||
# Ajaa kaksi testiä:
|
|
||||||
# A — dispatchaa gitea-ci-library:n poc-dispatch.yml (tämä repo, feature-haara)
|
|
||||||
# B — dispatchaa gitea-ci-gitops-tests:n gitops-service.yaml
|
|
||||||
#
|
|
||||||
# Käyttö:
|
|
||||||
# export GITEA_API_URL=https://gitea.app.keskikuja.site
|
|
||||||
# export GITEA_TOKEN=...
|
|
||||||
# bash scripts/poc-dispatch-match.sh
|
|
||||||
#
|
|
||||||
|
|
||||||
GITEA_API_URL="${GITEA_API_URL:?GITEA_API_URL is required}"
|
|
||||||
GITEA_TOKEN="${GITEA_TOKEN:?GITEA_TOKEN is required}"
|
|
||||||
BRANCH="${BRANCH:-feature/gitops}"
|
|
||||||
TIMEOUT_SECONDS="${TIMEOUT_SECONDS:-60}"
|
|
||||||
POLL_INTERVAL="${POLL_INTERVAL:-5}"
|
|
||||||
GITOPS_REPO="${GITOPS_REPO:-niko/gitea-ci-gitops-tests}"
|
|
||||||
GITOPS_WORKFLOW="${GITOPS_WORKFLOW:-gitops-service.yaml}"
|
|
||||||
LIB_REPO="${LIB_REPO:-niko/gitea-ci-library}"
|
|
||||||
LIB_WORKFLOW="${LIB_WORKFLOW:-poc-dispatch.yml}"
|
|
||||||
|
|
||||||
PASS=0
|
|
||||||
FAIL=0
|
|
||||||
|
|
||||||
_ts() {
|
|
||||||
date -u +%Y-%m-%dT%H:%M:%SZ
|
|
||||||
}
|
|
||||||
|
|
||||||
_report() {
|
|
||||||
local label="$1" status="$2" detail="$3"
|
|
||||||
if [ "$status" = "PASS" ]; then
|
|
||||||
PASS=$((PASS + 1))
|
|
||||||
echo " ✅ $label: $detail"
|
|
||||||
else
|
|
||||||
FAIL=$((FAIL + 1))
|
|
||||||
echo " ❌ $label: $detail"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
_dispatch_and_poll() {
|
|
||||||
local label="$1" target_repo="$2" workflow_file="$3" ref="$4" dispatch_id="$5"
|
|
||||||
local inputs_json="$6"
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "=== Test: $label ==="
|
|
||||||
echo " target: $target_repo"
|
|
||||||
echo " workflow: $workflow_file"
|
|
||||||
echo " ref: $ref"
|
|
||||||
echo " dispatch_id: $dispatch_id"
|
|
||||||
|
|
||||||
# 1. Ennen dispatchia: ota snapshot viimeisimmästä run_number:sta
|
|
||||||
local before_resp before_run before_count
|
|
||||||
before_resp=$(curl -s --connect-timeout 5 --max-time 10 \
|
|
||||||
"$GITEA_API_URL/api/v1/repos/$target_repo/actions/runs?event=workflow_dispatch&limit=1" \
|
|
||||||
-H "Authorization: token $GITEA_TOKEN")
|
|
||||||
|
|
||||||
before_run=$(echo "$before_resp" | jq -r '.workflow_runs[0].run_number // 0')
|
|
||||||
before_count=$(echo "$before_resp" | jq -r '.total_count // 0')
|
|
||||||
echo " before: $before_count runs, latest run_number=$before_run"
|
|
||||||
|
|
||||||
# 2. Dispatch
|
|
||||||
local dispatch_url="$GITEA_API_URL/api/v1/repos/$target_repo/actions/workflows/$workflow_file/dispatches"
|
|
||||||
local dispatch_body
|
|
||||||
dispatch_body=$(jq -nc --arg ref "$ref" --argjson inputs "$inputs_json" '{ref: $ref, inputs: $inputs}')
|
|
||||||
|
|
||||||
local dispatch_code
|
|
||||||
dispatch_code=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout 5 --max-time 10 \
|
|
||||||
-X POST "$dispatch_url" \
|
|
||||||
-H "Authorization: token $GITEA_TOKEN" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d "$dispatch_body")
|
|
||||||
|
|
||||||
if [ "$dispatch_code" != "201" ] && [ "$dispatch_code" != "204" ]; then
|
|
||||||
_report "$label" "FAIL" "Dispatch failed with HTTP $dispatch_code"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
echo " dispatch: HTTP $dispatch_code — started"
|
|
||||||
|
|
||||||
# 3. Pollaa: etsi run jossa display_title sisältää dispatch_id:n
|
|
||||||
local start_time elapsed found=""
|
|
||||||
start_time=$(date +%s)
|
|
||||||
|
|
||||||
while true; do
|
|
||||||
elapsed=$(( $(date +%s) - start_time ))
|
|
||||||
if [ "$elapsed" -ge "$TIMEOUT_SECONDS" ]; then
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
|
|
||||||
local runs_resp found_id found_display found_status found_run_num
|
|
||||||
runs_resp=$(curl -s --connect-timeout 5 --max-time 10 \
|
|
||||||
"$GITEA_API_URL/api/v1/repos/$target_repo/actions/runs?event=workflow_dispatch&limit=20" \
|
|
||||||
-H "Authorization: token $GITEA_TOKEN")
|
|
||||||
|
|
||||||
found_id=$(echo "$runs_resp" | jq -r --arg id "$dispatch_id" \
|
|
||||||
'[.workflow_runs[] | select(.display_title | contains($id))] | .[0].id // empty')
|
|
||||||
|
|
||||||
if [ -n "$found_id" ] && [ "$found_id" != "null" ]; then
|
|
||||||
found_display=$(echo "$runs_resp" | jq -r --arg id "$dispatch_id" \
|
|
||||||
'[.workflow_runs[] | select(.display_title | contains($id))] | .[0].display_title // "?"')
|
|
||||||
found_status=$(echo "$runs_resp" | jq -r --arg id "$dispatch_id" \
|
|
||||||
'[.workflow_runs[] | select(.display_title | contains($id))] | .[0].status // "?"')
|
|
||||||
found_run_num=$(echo "$runs_resp" | jq -r --arg id "$dispatch_id" \
|
|
||||||
'[.workflow_runs[] | select(.display_title | contains($id))] | .[0].run_number // "?"')
|
|
||||||
|
|
||||||
echo " found: id=$found_id run_number=$found_run_num status=$found_status display_title=\"$found_display\" (after ${elapsed}s)"
|
|
||||||
|
|
||||||
# Odota että run on completed
|
|
||||||
local poll_url="$GITEA_API_URL/api/v1/repos/$target_repo/actions/runs/$found_id"
|
|
||||||
while [ "$elapsed" -lt "$TIMEOUT_SECONDS" ]; do
|
|
||||||
local run_resp run_status run_conclusion
|
|
||||||
run_resp=$(curl -s --connect-timeout 5 --max-time 10 \
|
|
||||||
"$poll_url" -H "Authorization: token $GITEA_TOKEN")
|
|
||||||
run_status=$(echo "$run_resp" | jq -r '.status // "unknown"')
|
|
||||||
|
|
||||||
if [ "$run_status" = "completed" ]; then
|
|
||||||
run_conclusion=$(echo "$run_resp" | jq -r '.conclusion // "?"')
|
|
||||||
elapsed=$(( $(date +%s) - start_time ))
|
|
||||||
_report "$label" "PASS" "display_title matched, status=$run_status conclusion=$run_conclusion run_number=$found_run_num (${elapsed}s)"
|
|
||||||
echo " run detail: id=$found_id display_title=\"$found_display\""
|
|
||||||
echo " endpoint: $GITEA_API_URL/$target_repo/actions/runs/$found_id"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
sleep "$POLL_INTERVAL"
|
|
||||||
elapsed=$(( $(date +%s) - start_time ))
|
|
||||||
done
|
|
||||||
|
|
||||||
_report "$label" "FAIL" "Run found but didn't complete within ${TIMEOUT_SECONDS}s"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
sleep "$POLL_INTERVAL"
|
|
||||||
done
|
|
||||||
|
|
||||||
_report "$label" "FAIL" "No run with display_title containing \"$dispatch_id\" found within ${TIMEOUT_SECONDS}s"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Tallenna aloitusaika
|
|
||||||
POC_START=$(_ts)
|
|
||||||
echo "=============================================="
|
|
||||||
echo "POC: dispatch-workflow display_title matching"
|
|
||||||
echo "Started: $POC_START"
|
|
||||||
echo "API URL: $GITEA_API_URL"
|
|
||||||
echo "=============================================="
|
|
||||||
|
|
||||||
# Testi A: dispatchaa tämän repon poc-dispatch.yml
|
|
||||||
DISPATCH_ID_A=$(xxd -l 4 -p /dev/urandom 2>/dev/null || openssl rand -hex 4 2>/dev/null || date +%s | md5sum | head -c 8)
|
|
||||||
INPUTS_A=$(jq -nc \
|
|
||||||
--arg dispatch_id "$DISPATCH_ID_A" \
|
|
||||||
--arg type "local" \
|
|
||||||
'{dispatch_id: $dispatch_id, type: $type}')
|
|
||||||
|
|
||||||
_dispatch_and_poll \
|
|
||||||
"A: local poc-dispatch" \
|
|
||||||
"$LIB_REPO" "$LIB_WORKFLOW" "$BRANCH" \
|
|
||||||
"$DISPATCH_ID_A" "$INPUTS_A"
|
|
||||||
|
|
||||||
# Testi B: dispatchaa gitea-ci-gitops-tests gitops-service.yaml
|
|
||||||
DISPATCH_ID_B=$(xxd -l 4 -p /dev/urandom 2>/dev/null || openssl rand -hex 4 2>/dev/null || date +%s | md5sum | head -c 8)
|
|
||||||
INPUTS_B=$(jq -nc \
|
|
||||||
--arg dispatch_id "$DISPATCH_ID_B" \
|
|
||||||
--arg file "dev/Chart.yaml" \
|
|
||||||
--arg yq_tpl '.version = "{{VERSION}}"' \
|
|
||||||
--arg version "0.1.1" \
|
|
||||||
--arg source_repo "$LIB_REPO" \
|
|
||||||
--arg source_commit "poc-test-$(date +%s)" \
|
|
||||||
'{dispatch_id: $dispatch_id, file: $file, yq_tpl: $yq_tpl, version: $version, source_repo: $source_repo, source_commit: $source_commit}')
|
|
||||||
|
|
||||||
_dispatch_and_poll \
|
|
||||||
"B: gitops test" \
|
|
||||||
"$GITOPS_REPO" "$GITOPS_WORKFLOW" "main" \
|
|
||||||
"$DISPATCH_ID_B" "$INPUTS_B"
|
|
||||||
|
|
||||||
# Loppuraportti
|
|
||||||
echo ""
|
|
||||||
echo "=============================================="
|
|
||||||
echo "POC complete"
|
|
||||||
echo " PASS: $PASS"
|
|
||||||
echo " FAIL: $FAIL"
|
|
||||||
echo "=============================================="
|
|
||||||
|
|
||||||
if [ "$FAIL" -gt 0 ]; then
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
Feature: GitOps update
|
Feature: GitOps update
|
||||||
As a GitOps repository
|
As a GitOps repository
|
||||||
I want to update version references and report results back to the caller
|
I want to update version references and report results to the caller
|
||||||
So that the deployment chain is traceable from source to GitOps commit
|
So that the deployment chain is traceable from source to GitOps commit
|
||||||
|
|
||||||
Background:
|
Background:
|
||||||
@@ -8,37 +8,35 @@ Feature: GitOps update
|
|||||||
And a commit has been pushed to the repository
|
And a commit has been pushed to the repository
|
||||||
|
|
||||||
@mock
|
@mock
|
||||||
Scenario: Not enough env vars — caller commit gets failure status
|
Scenario: Not enough env vars — script fails, no status set
|
||||||
Given insufficient environment variables are provided for the GitOps update
|
Given insufficient environment variables are provided for the GitOps update
|
||||||
When the GitOps update script runs
|
When the GitOps update script runs
|
||||||
Then the caller commit shows a failure status with the missing variable name
|
Then the script exits with error
|
||||||
And the script exits with error
|
|
||||||
|
|
||||||
@mock
|
@mock
|
||||||
Scenario: GitOps job fails — caller commit gets failure status
|
Scenario: GitOps job fails — no status set (SHA not yet known)
|
||||||
Given the GitOps repository clone will fail
|
Given the GitOps repository clone will fail
|
||||||
When the GitOps update script runs
|
When the GitOps update script runs
|
||||||
Then the caller commit shows a failure status
|
Then the script exits with error
|
||||||
And the script exits with error
|
|
||||||
|
|
||||||
@mock
|
@mock
|
||||||
Scenario: Everything succeeds — caller and GitOps get success
|
Scenario: Everything succeeds — GitOps repo gets success status with link to caller
|
||||||
Given a valid GitOps update dispatch
|
Given a valid GitOps update dispatch
|
||||||
When the GitOps update script runs
|
When the GitOps update script runs
|
||||||
Then the script exits successfully
|
Then the script exits successfully
|
||||||
And the caller commit shows a success status with a link to the GitOps commit
|
And the GitOps repo commit shows a success status with a link to the caller commit
|
||||||
And the GitOps repo commit shows a success status with a link to the caller
|
|
||||||
|
|
||||||
@mock
|
@mock
|
||||||
Scenario: GitOps push fails — both repos get failure status
|
Scenario: GitOps push fails — GitOps repo gets failure status
|
||||||
Given the GitOps repo push will fail after the version is committed
|
Given the GitOps repo push will fail after the version is committed
|
||||||
When the GitOps update script runs
|
When the GitOps update script runs
|
||||||
Then the script exits with error
|
Then the script exits with error
|
||||||
And the caller commit shows a failure status
|
And the GitOps repo commit shows a failure status linking to the caller commit
|
||||||
And the GitOps repo commit shows a failure status linking to the caller
|
|
||||||
|
|
||||||
@mock
|
@mock
|
||||||
Scenario: GitOps update succeeds — this repo commit status links to caller
|
Scenario: No changes — GitOps repo gets "no change" status
|
||||||
Given a valid GitOps update dispatch
|
Given the version file already has the target version
|
||||||
When the GitOps update script runs
|
When the GitOps update script runs
|
||||||
Then the GitOps repo commit shows a source context status linking to the caller commit
|
Then the script exits successfully
|
||||||
|
And the GitOps repo commit shows a "no change" status
|
||||||
|
And no Git commit or push was performed
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ Before({ tags: '@mock' }, function () {
|
|||||||
|
|
||||||
After({ tags: '@mock' }, function () {
|
After({ tags: '@mock' }, function () {
|
||||||
spawnSync('bash', ['-c', `source "${MOCK_SCRIPT}" && mock_stop 2>/dev/null`], { stdio: 'ignore' });
|
spawnSync('bash', ['-c', `source "${MOCK_SCRIPT}" && mock_stop 2>/dev/null`], { stdio: 'ignore' });
|
||||||
try { execSync('rm -f /tmp/gitops-mock-requests.log', { stdio: 'ignore' }); } catch (_) {}
|
try { execSync('rm -f /tmp/gitops-mock-requests.log /tmp/gitops-git-calls.log', { stdio: 'ignore' }); } catch (_) {}
|
||||||
});
|
});
|
||||||
|
|
||||||
function bash(cmd) {
|
function bash(cmd) {
|
||||||
@@ -73,6 +73,11 @@ function requestCount() {
|
|||||||
return parseInt(bash(`grep -c '^POST ' "${REQ_FILE}" 2>/dev/null || echo 0`).stdout.trim(), 10) || 0;
|
return parseInt(bash(`grep -c '^POST ' "${REQ_FILE}" 2>/dev/null || echo 0`).stdout.trim(), 10) || 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function gitCalls() {
|
||||||
|
const out = bash(`cat "${GIT_CALLS_FILE:-/dev/null}" 2>/dev/null || echo ""`).stdout;
|
||||||
|
return out.split('\n').filter(l => l.length > 0);
|
||||||
|
}
|
||||||
|
|
||||||
function runScript(envOverrides) {
|
function runScript(envOverrides) {
|
||||||
const env = { ...BASE_ENV, ...envOverrides };
|
const env = { ...BASE_ENV, ...envOverrides };
|
||||||
const scriptPath = `/tmp/gitops-run-${Date.now()}.sh`;
|
const scriptPath = `/tmp/gitops-run-${Date.now()}.sh`;
|
||||||
@@ -88,7 +93,6 @@ function runScript(envOverrides) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Given('insufficient environment variables are provided for the GitOps update', function () {
|
Given('insufficient environment variables are provided for the GitOps update', function () {
|
||||||
this.missingVar = 'INPUT_FILE';
|
|
||||||
this.envOverrides = { INPUT_FILE: '' };
|
this.envOverrides = { INPUT_FILE: '' };
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -104,29 +108,17 @@ Given('the GitOps repo push will fail after the version is committed', function
|
|||||||
this.envOverrides = { GIT_MOCK_FAIL_PUSH: '1' };
|
this.envOverrides = { GIT_MOCK_FAIL_PUSH: '1' };
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Given('the version file already has the target version', function () {
|
||||||
|
this.envOverrides = {
|
||||||
|
GIT_MOCK_DIFF_NO_CHANGES: '1',
|
||||||
|
GIT_CALLS_FILE: '/tmp/gitops-git-calls.log',
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
When('the GitOps update script runs', function () {
|
When('the GitOps update script runs', function () {
|
||||||
this.result = runScript(this.envOverrides || {});
|
this.result = runScript(this.envOverrides || {});
|
||||||
});
|
});
|
||||||
|
|
||||||
Then('the caller commit shows a failure status with the missing variable name', function () {
|
|
||||||
const body = getFirstBody();
|
|
||||||
if (!body.includes('"state":"failure"')) throw new Error(`Expected failure state, body: ${body.substring(0,200)}`);
|
|
||||||
if (!body.includes('"context":"gitops/niko/app"')) throw new Error(`Expected gitops context, body: ${body.substring(0,200)}`);
|
|
||||||
if (!body.includes(`"description":"${this.missingVar} is required`)) {
|
|
||||||
throw new Error(`Expected description mentioning ${this.missingVar}, body: ${body.substring(0,200)}`);
|
|
||||||
}
|
|
||||||
const pathStr = getFirstPath();
|
|
||||||
if (!pathStr.includes('/repos/niko/app/statuses/')) throw new Error(`Expected source repo path, got: ${pathStr}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
Then('the caller commit shows a failure status', function () {
|
|
||||||
const body = getFirstBody();
|
|
||||||
if (!body.includes('"state":"failure"')) throw new Error(`Expected failure state, body: ${body.substring(0,200)}`);
|
|
||||||
if (!body.includes('"context":"gitops/niko/app"')) throw new Error(`Expected gitops context, body: ${body.substring(0,200)}`);
|
|
||||||
const pathStr = getFirstPath();
|
|
||||||
if (!pathStr.includes('/repos/niko/app/statuses/')) throw new Error(`Expected source repo path, got: ${pathStr}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
Then('the script exits with error', function () {
|
Then('the script exits with error', function () {
|
||||||
if (this.result.status === 0) throw new Error(`Expected non-zero exit, got 0. stderr: ${this.result.stderr.substring(0,200)}`);
|
if (this.result.status === 0) throw new Error(`Expected non-zero exit, got 0. stderr: ${this.result.stderr.substring(0,200)}`);
|
||||||
});
|
});
|
||||||
@@ -135,41 +127,45 @@ Then('the script exits successfully', function () {
|
|||||||
if (this.result.status !== 0) throw new Error(`Expected exit 0, got ${this.result.status}: ${this.result.stderr.substring(0,200)}`);
|
if (this.result.status !== 0) throw new Error(`Expected exit 0, got ${this.result.status}: ${this.result.stderr.substring(0,200)}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
Then('the caller commit shows a success status with a link to the GitOps commit', function () {
|
Then('the GitOps repo commit shows a success status with a link to the caller commit', function () {
|
||||||
|
const count = requestCount();
|
||||||
|
if (count < 1) throw new Error(`Expected at least 1 request, got ${count}`);
|
||||||
const body = getFirstBody();
|
const body = getFirstBody();
|
||||||
if (!body.includes('"state":"success"')) throw new Error(`Expected success state, body: ${body.substring(0,200)}`);
|
if (!body.includes('"state":"success"')) throw new Error(`Expected success state, body: ${body.substring(0,200)}`);
|
||||||
if (!body.includes('"context":"gitops/niko/app"')) throw new Error(`Expected gitops context, body: ${body.substring(0,200)}`);
|
if (!body.includes('"context":"app unknown"')) throw new Error(`Expected context "app unknown", body: ${body.substring(0,200)}`);
|
||||||
if (!body.includes('niko/app-gitops/commits/')) throw new Error(`Expected link to GitOps commit, body: ${body.substring(0,200)}`);
|
if (!body.includes('"description":"Install to dev 0.2.0"')) throw new Error(`Expected description, body: ${body.substring(0,200)}`);
|
||||||
|
if (!body.includes('niko/app/commit/abc123def456')) throw new Error(`Expected link to caller commit, body: ${body.substring(0,200)}`);
|
||||||
const pathStr = getFirstPath();
|
const pathStr = getFirstPath();
|
||||||
if (!pathStr.includes('/repos/niko/app/statuses/')) throw new Error(`Expected source repo path, got: ${pathStr}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
Then('the GitOps repo commit shows a success status with a link to the caller', function () {
|
|
||||||
if (requestCount() < 2) throw new Error(`Expected at least 2 requests, got ${requestCount()}`);
|
|
||||||
const body = getLastBody();
|
|
||||||
if (!body.includes('"state":"success"')) throw new Error(`Expected success state, body: ${body.substring(0,200)}`);
|
|
||||||
if (!body.includes('"context":"source/niko/app"')) throw new Error(`Expected source context, body: ${body.substring(0,200)}`);
|
|
||||||
if (!body.includes('niko/app/commits/abc123def456')) throw new Error(`Expected link to caller commit, body: ${body.substring(0,200)}`);
|
|
||||||
const pathStr = getLastPath();
|
|
||||||
if (!pathStr.includes('/repos/niko/app-gitops/statuses/')) throw new Error(`Expected gitops repo path, got: ${pathStr}`);
|
if (!pathStr.includes('/repos/niko/app-gitops/statuses/')) throw new Error(`Expected gitops repo path, got: ${pathStr}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
Then('the GitOps repo commit shows a failure status linking to the caller', function () {
|
Then('the GitOps repo commit shows a failure status linking to the caller commit', function () {
|
||||||
if (requestCount() < 2) throw new Error(`Expected at least 2 requests, got ${requestCount()}`);
|
const count = requestCount();
|
||||||
const body = getLastBody();
|
if (count < 1) throw new Error(`Expected at least 1 request, got ${count}`);
|
||||||
|
const body = getFirstBody();
|
||||||
if (!body.includes('"state":"failure"')) throw new Error(`Expected failure state, body: ${body.substring(0,200)}`);
|
if (!body.includes('"state":"failure"')) throw new Error(`Expected failure state, body: ${body.substring(0,200)}`);
|
||||||
if (!body.includes('"context":"source/niko/app"')) throw new Error(`Expected source context, body: ${body.substring(0,200)}`);
|
if (!body.includes('"context":"app unknown"')) throw new Error(`Expected context "app unknown", body: ${body.substring(0,200)}`);
|
||||||
if (!body.includes('niko/app/commits/abc123def456')) throw new Error(`Expected link to caller commit, body: ${body.substring(0,200)}`);
|
if (!body.includes('"description":"Install to dev 0.2.0"')) throw new Error(`Expected description, body: ${body.substring(0,200)}`);
|
||||||
const pathStr = getLastPath();
|
if (!body.includes('niko/app/commit/abc123def456')) throw new Error(`Expected link to caller commit, body: ${body.substring(0,200)}`);
|
||||||
|
const pathStr = getFirstPath();
|
||||||
if (!pathStr.includes('/repos/niko/app-gitops/statuses/')) throw new Error(`Expected gitops repo path, got: ${pathStr}`);
|
if (!pathStr.includes('/repos/niko/app-gitops/statuses/')) throw new Error(`Expected gitops repo path, got: ${pathStr}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
Then('the GitOps repo commit shows a source context status linking to the caller commit', function () {
|
Then('the GitOps repo commit shows a "no change" status', function () {
|
||||||
if (requestCount() < 2) throw new Error(`Expected at least 2 requests, got ${requestCount()}`);
|
const count = requestCount();
|
||||||
const body = getLastBody();
|
if (count < 1) throw new Error(`Expected at least 1 request, got ${count}`);
|
||||||
|
const body = getFirstBody();
|
||||||
if (!body.includes('"state":"success"')) throw new Error(`Expected success state, body: ${body.substring(0,200)}`);
|
if (!body.includes('"state":"success"')) throw new Error(`Expected success state, body: ${body.substring(0,200)}`);
|
||||||
if (!body.includes('"context":"source/niko/app"')) throw new Error(`Expected source context, body: ${body.substring(0,200)}`);
|
if (!body.includes('"description":"Install to dev 0.2.0 \u2014 no change"')) {
|
||||||
if (!body.includes('niko/app/commits/abc123def456')) throw new Error(`Expected link to caller, body: ${body.substring(0,200)}`);
|
throw new Error(`Expected "no change" description, body: ${body.substring(0,200)}`);
|
||||||
const pathStr = getLastPath();
|
}
|
||||||
|
const pathStr = getFirstPath();
|
||||||
if (!pathStr.includes('/repos/niko/app-gitops/statuses/')) throw new Error(`Expected gitops repo path, got: ${pathStr}`);
|
if (!pathStr.includes('/repos/niko/app-gitops/statuses/')) throw new Error(`Expected gitops repo path, got: ${pathStr}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Then('no Git commit or push was performed', function () {
|
||||||
|
const calls = gitCalls();
|
||||||
|
if (calls.some(l => l.includes(' commit ') || l.includes(' push '))) {
|
||||||
|
throw new Error(`Expected no commit or push, got: ${calls.join(', ')}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|||||||
@@ -139,10 +139,9 @@ teardown() {
|
|||||||
mock_stop
|
mock_stop
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "two commit-status calls: code-repo and gitops-repo" {
|
@test "one commit-status call: gitops-repo only" {
|
||||||
source tests/helpers/mock-api.sh
|
source tests/helpers/mock-api.sh
|
||||||
mock_set_sequence '[
|
mock_set_sequence '[
|
||||||
{"code":201},
|
|
||||||
{"code":201}
|
{"code":201}
|
||||||
]'
|
]'
|
||||||
mock_start
|
mock_start
|
||||||
@@ -159,14 +158,12 @@ teardown() {
|
|||||||
export GITEA_TOKEN=test-token
|
export GITEA_TOKEN=test-token
|
||||||
run bash scripts/gitops-update.sh
|
run bash scripts/gitops-update.sh
|
||||||
[ "$status" -eq 0 ]
|
[ "$status" -eq 0 ]
|
||||||
path1=$(mock_get_first_request_path)
|
path=$(mock_get_first_request_path)
|
||||||
body1=$(mock_get_first_request_body)
|
body=$(mock_get_first_request_body)
|
||||||
[[ "$path1" == *"/repos/niko/app/statuses/"* ]]
|
[[ "$path" == *"/repos/niko/app-gitops/statuses/"* ]]
|
||||||
[[ "$body1" == *'"context":"gitops/niko/app"'* ]]
|
[[ "$body" == *'"context":"app unknown"'* ]]
|
||||||
path2=$(mock_get_request_path)
|
[[ "$body" == *'"description":"Install to dev 0.2.3"'* ]]
|
||||||
body2=$(mock_get_request_body)
|
[[ "$body" == *'"state":"success"'* ]]
|
||||||
[[ "$path2" == *"/repos/niko/app-gitops/statuses/"* ]]
|
|
||||||
[[ "$body2" == *'"context":"source/niko/app"'* ]]
|
|
||||||
rm -f "$GIT_CALLS_FILE" "$YQ_CALLS_FILE"
|
rm -f "$GIT_CALLS_FILE" "$YQ_CALLS_FILE"
|
||||||
mock_stop
|
mock_stop
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,11 @@ if [ "${1:-}" = "push" ] && [ -n "${GIT_MOCK_FAIL_PUSH:-}" ]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Skip -c config arguments
|
||||||
|
while [ "${1:-}" = "-c" ]; do
|
||||||
|
shift 2
|
||||||
|
done
|
||||||
|
|
||||||
case "$1" in
|
case "$1" in
|
||||||
clone)
|
clone)
|
||||||
TARGET_DIR="${@: -1}"
|
TARGET_DIR="${@: -1}"
|
||||||
@@ -17,6 +22,14 @@ case "$1" in
|
|||||||
;;
|
;;
|
||||||
add|commit|push|config|init)
|
add|commit|push|config|init)
|
||||||
;;
|
;;
|
||||||
|
diff)
|
||||||
|
# Default: exit 1 = has changes → proceed to commit
|
||||||
|
# GIT_MOCK_DIFF_NO_CHANGES=1 → exit 0 = no changes → "no change" path
|
||||||
|
if [ -n "${GIT_MOCK_DIFF_NO_CHANGES:-}" ]; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
rev-parse)
|
rev-parse)
|
||||||
echo "mock-sha-9876543210fedcba9876543210fedcba98765432"
|
echo "mock-sha-9876543210fedcba9876543210fedcba98765432"
|
||||||
;;
|
;;
|
||||||
|
|||||||
Reference in New Issue
Block a user