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

This commit is contained in:
moilanik
2026-06-22 06:57:09 +03:00
parent f58497f5e8
commit 84978784fe
6 changed files with 76 additions and 328 deletions
+14 -16
View File
@@ -1,6 +1,6 @@
Feature: GitOps update
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
Background:
@@ -8,37 +8,35 @@ Feature: GitOps update
And a commit has been pushed to the repository
@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
When the GitOps update script runs
Then the caller commit shows a failure status with the missing variable name
And the script exits with error
Then the script exits with error
@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
When the GitOps update script runs
Then the caller commit shows a failure status
And the script exits with error
Then the script exits with error
@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
When the GitOps update script runs
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
And the GitOps repo commit shows a success status with a link to the caller commit
@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
When the GitOps update script runs
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
And the GitOps repo commit shows a failure status linking to the caller commit
@mock
Scenario: GitOps update succeeds — this repo commit status links to caller
Given a valid GitOps update dispatch
Scenario: No changes — GitOps repo gets "no change" status
Given the version file already has the target version
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 () {
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) {
@@ -73,6 +73,11 @@ function requestCount() {
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) {
const env = { ...BASE_ENV, ...envOverrides };
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 () {
this.missingVar = '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' };
});
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 () {
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 () {
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)}`);
});
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();
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('niko/app-gitops/commits/')) throw new Error(`Expected link to GitOps commit, 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('"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();
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}`);
});
Then('the GitOps repo commit shows a failure status linking to the caller', function () {
if (requestCount() < 2) throw new Error(`Expected at least 2 requests, got ${requestCount()}`);
const body = getLastBody();
Then('the GitOps repo commit shows a failure status linking to the caller commit', function () {
const count = requestCount();
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('"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 (!body.includes('"context":"app unknown"')) throw new Error(`Expected context "app unknown", 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();
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 () {
if (requestCount() < 2) throw new Error(`Expected at least 2 requests, got ${requestCount()}`);
const body = getLastBody();
Then('the GitOps repo commit shows a "no change" status', function () {
const count = requestCount();
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('"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, body: ${body.substring(0,200)}`);
const pathStr = getLastPath();
if (!body.includes('"description":"Install to dev 0.2.0 \u2014 no change"')) {
throw new Error(`Expected "no change" description, 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}`);
});
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(', ')}`);
}
});