@metasession.co/devaudit-cli 0.3.19 → 0.3.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metasession.co/devaudit-cli",
3
- "version": "0.3.19",
3
+ "version": "0.3.21",
4
4
  "description": "DevAudit CLI — installs, syncs, and operates the Metasession SDLC across consumer projects.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -33,7 +33,7 @@
33
33
  },
34
34
  "dependencies": {
35
35
  "@clack/prompts": "^0.8.2",
36
- "@metasession.co/devaudit-plugin-sdk": "^0.3.19",
36
+ "@metasession.co/devaudit-plugin-sdk": "^0.3.21",
37
37
  "ajv": "^8.20.0",
38
38
  "commander": "^12.1.0",
39
39
  "consola": "^3.2.3",
@@ -58,6 +58,32 @@ jobs:
58
58
  ref: ${{ github.event.pull_request.head.sha || 'develop' }}
59
59
  fetch-depth: 0
60
60
 
61
+ - name: Detect declared standalone housekeeping promotion
62
+ id: standalone
63
+ if: github.event_name == 'pull_request'
64
+ env:
65
+ PR_TITLE: ${{ github.event.pull_request.title }}
66
+ PR_BODY: ${{ github.event.pull_request.body }}
67
+ run: |
68
+ echo "standalone=false" >> "$GITHUB_OUTPUT"
69
+ chmod +x scripts/derive-release-version.sh scripts/standalone-housekeeping-release.sh 2>/dev/null || true
70
+ VERSION=$(bash scripts/derive-release-version.sh)
71
+ if ! [[ "$VERSION" =~ ^v[0-9]{4}\.[0-9]{2}\.[0-9]{2}([.][0-9]+)?$ ]]; then
72
+ exit 0
73
+ fi
74
+ DECLARATION="compliance/standalone-housekeeping/STANDALONE-HOUSEKEEPING-${VERSION}.json"
75
+ if [ ! -f "$DECLARATION" ]; then
76
+ exit 0
77
+ fi
78
+ if ! printf '%s\n%s\n' "$PR_TITLE" "$PR_BODY" | grep -Fq 'Standalone housekeeping promotion'; then
79
+ echo "::error::Standalone declaration exists, but this PR is missing the literal 'Standalone housekeeping promotion' marker."
80
+ exit 1
81
+ fi
82
+ bash scripts/standalone-housekeeping-release.sh validate "$VERSION" "$DECLARATION"
83
+ echo "standalone=true" >> "$GITHUB_OUTPUT"
84
+ echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
85
+ echo "Declared standalone housekeeping promotion ${VERSION}; normal GitHub review and technical checks remain required, but tracked portal approval does not apply."
86
+
61
87
  - name: Resolve DevAudit base URL
62
88
  run: |
63
89
  # Prefer sdlc-config.json (visible in PR review) over repo Variable.
@@ -159,7 +185,7 @@ jobs:
159
185
 
160
186
  - name: Resolve current release
161
187
  id: release
162
- if: env.BOOTSTRAP_MODE != 'true'
188
+ if: env.BOOTSTRAP_MODE != 'true' && steps.standalone.outputs.standalone != 'true'
163
189
  run: |
164
190
  # devaudit#283 — repository_dispatch('release-approved') events
165
191
  # carry the release version in client_payload. Use it directly
@@ -218,7 +244,7 @@ jobs:
218
244
  esac
219
245
 
220
246
  - name: Link PR to release
221
- if: env.BOOTSTRAP_MODE != 'true' && github.event_name == 'pull_request'
247
+ if: env.BOOTSTRAP_MODE != 'true' && steps.standalone.outputs.standalone != 'true' && github.event_name == 'pull_request'
222
248
  run: |
223
249
  RELEASE_ID="${{ steps.release.outputs.release_id }}"
224
250
  PR_URL="${{ github.event.pull_request.html_url }}"
@@ -231,7 +257,7 @@ jobs:
231
257
  echo "Linked PR #${PR_NUMBER} to release ${RELEASE_ID}"
232
258
 
233
259
  - name: Post release link on PR
234
- if: env.BOOTSTRAP_MODE != 'true' && github.event_name == 'pull_request'
260
+ if: env.BOOTSTRAP_MODE != 'true' && steps.standalone.outputs.standalone != 'true' && github.event_name == 'pull_request'
235
261
  env:
236
262
  GH_TOKEN: ${{ github.token }}
237
263
  run: |
@@ -247,7 +273,7 @@ jobs:
247
273
  fi
248
274
 
249
275
  - name: SHA comparison
250
- if: env.BOOTSTRAP_MODE != 'true' && github.event_name == 'pull_request'
276
+ if: env.BOOTSTRAP_MODE != 'true' && steps.standalone.outputs.standalone != 'true' && github.event_name == 'pull_request'
251
277
  run: |
252
278
  PR_HEAD_SHA="${{ github.event.pull_request.head.sha }}"
253
279
  APPROVED_SHA="${{ steps.release.outputs.approved_sha }}"
@@ -77,7 +77,8 @@ jobs:
77
77
  fi
78
78
  [ -n "$BASE" ] || BASE="$DEVAUDIT_BASE_URL_VAR"
79
79
  [ -n "$BASE" ] || { echo "::warning::No DevAudit URL; test execution lifecycle disabled"; exit 0; }
80
- echo "DEVAUDIT_BASE_URL=${BASE%/}" >> "$GITHUB_ENV"
80
+ export DEVAUDIT_BASE_URL="${BASE%/}"
81
+ echo "DEVAUDIT_BASE_URL=${DEVAUDIT_BASE_URL}" >> "$GITHUB_ENV"
81
82
  chmod +x scripts/report-test-execution.sh scripts/report-release-check.sh 2>/dev/null || true
82
83
  bash scripts/report-test-execution.sh start \
83
84
  --project-slug {{PROJECT_SLUG}} \
@@ -0,0 +1,56 @@
1
+ name: Report Release Close-out Completion
2
+
3
+ on:
4
+ pull_request:
5
+ branches: [develop]
6
+ types: [closed]
7
+
8
+ permissions:
9
+ contents: read
10
+ pull-requests: read
11
+
12
+ jobs:
13
+ report-completion:
14
+ if: github.event.pull_request.merged == true && startsWith(github.event.pull_request.head.ref, 'chore/close-out-')
15
+ runs-on: {{RUNNER}}
16
+ env:
17
+ DEVAUDIT_API_KEY: ${{ secrets.DEVAUDIT_API_KEY }}
18
+ PROJECT_SLUG: {{PROJECT_SLUG}}
19
+ steps:
20
+ - uses: actions/checkout@v6
21
+ with:
22
+ ref: ${{ github.event.pull_request.merge_commit_sha }}
23
+
24
+ - name: Report tracked close-out completion
25
+ run: |
26
+ set -euo pipefail
27
+ REQ="$(printf '%s' '${{ github.event.pull_request.head.ref }}' | sed -n 's#^chore/close-out-\(REQ-[0-9][0-9][0-9]*\)$#\1#p')"
28
+ if [ -z "$REQ" ]; then
29
+ echo "Standalone and integration housekeeping have no tracked close-out callback."
30
+ exit 0
31
+ fi
32
+ BASE="$(jq -r '.devaudit.base_url // empty' sdlc-config.json)"
33
+ if [ -z "$BASE" ] || [ -z "$DEVAUDIT_API_KEY" ]; then
34
+ echo "::error::DevAudit base URL and project API key are required for tracked close-out completion."
35
+ exit 1
36
+ fi
37
+ RELEASE="$(curl --fail-with-body -sS -G "${BASE%/}/api/ci/releases/resolve" \
38
+ -H "Authorization: Bearer ${DEVAUDIT_API_KEY}" \
39
+ --data-urlencode "projectSlug=${PROJECT_SLUG}" \
40
+ --data-urlencode "versionPrefix=${REQ}")"
41
+ RELEASE_ID="$(jq -r '.latest.id // empty' <<<"$RELEASE")"
42
+ RELEASE_VERSION="$(jq -r '.latest.version // empty' <<<"$RELEASE")"
43
+ if [ -z "$RELEASE_ID" ] || [ "$RELEASE_VERSION" != "$REQ" ]; then
44
+ echo "::error::Unable to resolve the tracked release ${REQ}; refusing callback."
45
+ exit 1
46
+ fi
47
+ curl --fail-with-body -sS -X POST "${BASE%/}/api/ci/releases/${RELEASE_ID}/close-out" \
48
+ -H "Authorization: Bearer ${DEVAUDIT_API_KEY}" \
49
+ -H 'Content-Type: application/json' \
50
+ --data "$(jq -nc \
51
+ --arg workflowRunId '${{ github.run_id }}' \
52
+ --arg workflowUrl '${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}' \
53
+ --arg pullRequestUrl '${{ github.event.pull_request.html_url }}' \
54
+ --arg mergeSha '${{ github.event.pull_request.merge_commit_sha }}' \
55
+ --argjson pullRequestNumber '${{ github.event.pull_request.number }}' \
56
+ '{status:"completed",workflowRunId:$workflowRunId,workflowUrl:$workflowUrl,pullRequestNumber:$pullRequestNumber,pullRequestUrl:$pullRequestUrl,mergeSha:$mergeSha}')"
@@ -54,8 +54,8 @@ jobs:
54
54
  REQ="${{ github.event.inputs.release }}${{ github.event.client_payload.release }}"
55
55
  PR="${{ github.event.inputs.release_pr }}${{ github.event.client_payload.release_pr }}"
56
56
  if ! printf '%s' "$REQ" | grep -qE '^REQ-[0-9]{3,}$'; then
57
- echo "::error::No valid REQ-XXX supplied (inputs.release / client_payload.release)."
58
- exit 1
57
+ echo "Standalone and integration housekeeping have no ticket/RTM close-out. No-op."
58
+ exit 0
59
59
  fi
60
60
  echo "req=${REQ}" >> "$GITHUB_OUTPUT"
61
61
  echo "pr=${PR}" >> "$GITHUB_OUTPUT"
@@ -910,6 +910,10 @@ jobs:
910
910
  fi
911
911
 
912
912
  if [ "${#REQS[@]}" -eq 0 ]; then
913
+ if echo "$DERIVED_RELEASE" | grep -qE '^v[0-9]{4}\.[0-9]{2}\.[0-9]{2}([.][0-9]+)?$'; then
914
+ echo "No tracked REQ was executed for standalone/integration housekeeping ${DERIVED_RELEASE}; preserving this as GitHub historical CI without portal approval evidence."
915
+ exit 0
916
+ fi
913
917
  REQS=(_compliance-docs)
914
918
  fi
915
919
  # A bounded Playwright process exits the workflow with `failure`
@@ -167,11 +167,47 @@ jobs:
167
167
  if [ -d playwright-report ]; then
168
168
  zip -qr playwright-report.zip playwright-report/ 2>/dev/null || true
169
169
  fi
170
+ LINEAGE_FLAGS=(--test-execution "${{ github.run_id }}")
171
+ if [ "${{ steps.exec.outputs.execution_supported }}" = "true" ] && [ -n "${{ steps.exec.outputs.execution_record_id }}" ]; then
172
+ LINEAGE_FLAGS+=(--evidence-scope execution --test-execution-record-id "${{ steps.exec.outputs.execution_record_id }}")
173
+ fi
174
+ UPLOAD_FAILURES=0
175
+
176
+ if [ ! -f e2e-results.json ]; then
177
+ echo "::error::Feature E2E produced no e2e-results.json"
178
+ exit 1
179
+ fi
180
+ bash scripts/upload-evidence.sh \
181
+ {{PROJECT_SLUG}} "$REQ_ID" e2e_result e2e-results.json \
182
+ --category e2e_result --release "$REQ_ID" --create-release-if-missing \
183
+ --environment uat --sdlc-stage 2 \
184
+ --git-sha "${{ github.event.pull_request.head.sha }}" \
185
+ --ci-run-id "${{ github.run_id }}" --branch "${{ github.head_ref }}" \
186
+ "${LINEAGE_FLAGS[@]}" \
187
+ --meta-key "origin=feature" \
188
+ || UPLOAD_FAILURES=$((UPLOAD_FAILURES + 1))
189
+
190
+ SHOT_DIR="compliance/evidence/${REQ_ID}/screenshots"
191
+ shopt -s nullglob
192
+ SHOTS=("${SHOT_DIR}"/*.png)
193
+ shopt -u nullglob
194
+ if [ "${#SHOTS[@]}" -eq 0 ]; then
195
+ echo "::error::No evidenceShot screenshots were captured for ${REQ_ID}."
196
+ exit 1
197
+ fi
198
+ for shot in "${SHOTS[@]}"; do
199
+ bash scripts/upload-evidence.sh \
200
+ {{PROJECT_SLUG}} "$REQ_ID" screenshot "$shot" \
201
+ --category screenshot --release "$REQ_ID" --create-release-if-missing \
202
+ --environment uat --sdlc-stage 2 \
203
+ --git-sha "${{ github.event.pull_request.head.sha }}" \
204
+ --ci-run-id "${{ github.run_id }}" --branch "${{ github.head_ref }}" \
205
+ "${LINEAGE_FLAGS[@]}" \
206
+ --meta-key "origin=feature" \
207
+ || UPLOAD_FAILURES=$((UPLOAD_FAILURES + 1))
208
+ done
209
+
170
210
  if [ -f playwright-report.zip ]; then
171
- LINEAGE_FLAGS=(--test-execution "${{ github.run_id }}")
172
- if [ "${{ steps.exec.outputs.execution_supported }}" = "true" ] && [ -n "${{ steps.exec.outputs.execution_record_id }}" ]; then
173
- LINEAGE_FLAGS+=(--evidence-scope execution --test-execution-record-id "${{ steps.exec.outputs.execution_record_id }}")
174
- fi
175
211
  bash scripts/upload-evidence.sh \
176
212
  {{PROJECT_SLUG}} "$REQ_ID" feature_e2e_report playwright-report.zip \
177
213
  --category e2e_report --release "$REQ_ID" --create-release-if-missing \
@@ -182,6 +218,10 @@ jobs:
182
218
  --meta-key "origin=feature" \
183
219
  || echo "::warning::feature E2E report upload failed"
184
220
  fi
221
+ if [ "$UPLOAD_FAILURES" -gt 0 ]; then
222
+ echo "::error::${UPLOAD_FAILURES} feature E2E evidence upload(s) failed"
223
+ exit 1
224
+ fi
185
225
 
186
226
  - name: Complete feature E2E execution
187
227
  if: always()
package/sdlc/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metasession.co/devaudit-sdlc",
3
- "version": "0.3.19",
3
+ "version": "0.3.21",
4
4
  "description": "DevAudit SDLC CLI Engine — cross-agent terminal-driven SDLC orchestrator.",
5
5
  "bin": {
6
6
  "devaudit-sdlc": "./src/bin/devaudit-sdlc.js"