@codyswann/lisa 4.74.2 → 4.74.3
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/cdk/create-only/.github/workflows/deploy.yml +58 -1
- package/dist/core/nightly-e2e-guard-behavior-certificate.js +2 -2
- package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
- package/dist/core/upstream-evidence-manifest.js +8 -6
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/expo/create-only/.github/workflows/deploy.yml +106 -3
- package/harper-fabric/create-only/.github/workflows/deploy.yml +97 -0
- package/nestjs/create-only/.github/workflows/deploy.yml +135 -2
- package/package.json +4 -4
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-agy/plugin.json +1 -1
- package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-agy/plugin.json +1 -1
- package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-agy/plugin.json +1 -1
- package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-agy/plugin.json +1 -1
- package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-agy/plugin.json +1 -1
- package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-agy/plugin.json +1 -1
- package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-agy/plugin.json +1 -1
- package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-agy/plugin.json +1 -1
- package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
- package/rails/create-only/.github/workflows/deploy.yml +97 -2
- package/scripts/two-channel-couplings.json +1 -1
|
@@ -22,6 +22,16 @@ on:
|
|
|
22
22
|
- dev
|
|
23
23
|
workflow_dispatch:
|
|
24
24
|
inputs:
|
|
25
|
+
rollback_commit:
|
|
26
|
+
description: 'Commit SHA to deploy for a deliberate rollback; leave empty for the run commit'
|
|
27
|
+
required: false
|
|
28
|
+
default: ''
|
|
29
|
+
type: string
|
|
30
|
+
force_stale_deploy:
|
|
31
|
+
description: "Allow a deliberate rollback to this run's old commit (may overwrite a newer deployment)"
|
|
32
|
+
required: false
|
|
33
|
+
default: false
|
|
34
|
+
type: boolean
|
|
25
35
|
environment:
|
|
26
36
|
description: 'Environment to deploy to'
|
|
27
37
|
required: true
|
|
@@ -43,6 +53,53 @@ concurrency:
|
|
|
43
53
|
cancel-in-progress: true
|
|
44
54
|
|
|
45
55
|
jobs:
|
|
56
|
+
# Re-runs retain their original SHA. Refuse an old run before release or deployment.
|
|
57
|
+
validate_deploy_commit:
|
|
58
|
+
name: 🚦 Validate Deployment Commit
|
|
59
|
+
runs-on: ubuntu-latest
|
|
60
|
+
timeout-minutes: 5
|
|
61
|
+
permissions:
|
|
62
|
+
contents: read
|
|
63
|
+
steps:
|
|
64
|
+
- uses: actions/checkout@v6
|
|
65
|
+
with:
|
|
66
|
+
ref: ${{ github.event_name == 'workflow_dispatch' && inputs.rollback_commit || github.sha }}
|
|
67
|
+
# Check the actual checkout again on job-only retries; earlier jobs may not rerun.
|
|
68
|
+
- name: 🚦 Refuse stale deployment
|
|
69
|
+
shell: bash
|
|
70
|
+
env:
|
|
71
|
+
DEPLOY_BRANCH: ${{ github.event_name == 'workflow_dispatch' && inputs.environment || github.ref_name }}
|
|
72
|
+
DEPLOY_EVENT: ${{ github.event_name }}
|
|
73
|
+
FORCE_STALE_DEPLOY: ${{ github.event_name == 'workflow_dispatch' && inputs.force_stale_deploy == true }}
|
|
74
|
+
run: |
|
|
75
|
+
set -euo pipefail
|
|
76
|
+
DEPLOY_SHA=$(git rev-parse HEAD)
|
|
77
|
+
TARGET_REF="refs/heads/$DEPLOY_BRANCH"
|
|
78
|
+
if ! git check-ref-format "$TARGET_REF"; then
|
|
79
|
+
echo "::error::Invalid deployment branch: $DEPLOY_BRANCH. Choose an existing branch."
|
|
80
|
+
exit 1
|
|
81
|
+
fi
|
|
82
|
+
if ! REMOTE=$(git ls-remote --exit-code --heads origin "$TARGET_REF"); then
|
|
83
|
+
echo "::error::Cannot read the current tip of $DEPLOY_BRANCH. Nothing will be deployed. Check repository access and the branch name, then retry."
|
|
84
|
+
exit 1
|
|
85
|
+
fi
|
|
86
|
+
read -r TIP RESOLVED_REF <<< "$REMOTE"
|
|
87
|
+
if [[ ! "$TIP" =~ ^[0-9a-f]{40}$ ]] || [ "$RESOLVED_REF" != "$TARGET_REF" ]; then
|
|
88
|
+
echo "::error::Could not verify the current tip of $DEPLOY_BRANCH. Nothing will be deployed."
|
|
89
|
+
exit 1
|
|
90
|
+
fi
|
|
91
|
+
if [ "$DEPLOY_SHA" = "$TIP" ]; then
|
|
92
|
+
echo "✅ Deployment commit $DEPLOY_SHA is the current tip of $DEPLOY_BRANCH."
|
|
93
|
+
exit 0
|
|
94
|
+
fi
|
|
95
|
+
if [ "$DEPLOY_EVENT" = "workflow_dispatch" ] && [ "$FORCE_STALE_DEPLOY" = "true" ]; then
|
|
96
|
+
echo "::warning title=Deliberate stale deployment::Deploying non-tip commit $DEPLOY_SHA to $DEPLOY_BRANCH; the current branch tip is $TIP. force_stale_deploy was explicitly enabled."
|
|
97
|
+
echo "### ⚠️ Deliberate rollback: deploying $DEPLOY_SHA to $DEPLOY_BRANCH instead of current tip $TIP." >> "${GITHUB_STEP_SUMMARY:-/dev/stdout}"
|
|
98
|
+
exit 0
|
|
99
|
+
fi
|
|
100
|
+
echo "::error title=Stale deployment refused::This run would deploy $DEPLOY_SHA, but $DEPLOY_BRANCH is now at $TIP. This is probably a re-run of an old run and would roll the environment back. Re-run the latest deploy run for this branch, or start workflow_dispatch on the branch tip. For a deliberate rollback only, explicitly enable force_stale_deploy in a manual run."
|
|
101
|
+
exit 1
|
|
102
|
+
|
|
46
103
|
# Environment setup
|
|
47
104
|
determine_environment:
|
|
48
105
|
name: 🌍 Determine Environment
|
|
@@ -104,7 +161,7 @@ jobs:
|
|
|
104
161
|
pre_deploy_gates:
|
|
105
162
|
name: 🚦 Pre-Deploy Gates
|
|
106
163
|
uses: CodySwannGT/lisa/.github/workflows/gates.yml@main
|
|
107
|
-
needs: [determine_environment]
|
|
164
|
+
needs: [determine_environment, validate_deploy_commit]
|
|
108
165
|
with:
|
|
109
166
|
# Travels with the `uses:` line above — the two are one unit. Lisa's
|
|
110
167
|
# reusable workflows are tracked at `@main`, so that file changes under
|
|
@@ -238,7 +295,14 @@ jobs:
|
|
|
238
295
|
# Trigger EAS Build if needed (only runs if app config changed)
|
|
239
296
|
trigger_eas_build:
|
|
240
297
|
name: Trigger EAS Build
|
|
241
|
-
needs:
|
|
298
|
+
needs:
|
|
299
|
+
[
|
|
300
|
+
determine_environment,
|
|
301
|
+
check_eas_setup,
|
|
302
|
+
check_app_config_changes,
|
|
303
|
+
validate_deploy_commit,
|
|
304
|
+
release,
|
|
305
|
+
]
|
|
242
306
|
if: needs.check_eas_setup.outputs.has_eas_setup == 'true' && (needs.check_app_config_changes.outputs.app_config_changed == 'true' || inputs.force_build == true)
|
|
243
307
|
uses: CodySwannGT/lisa/.github/workflows/build.yml@main
|
|
244
308
|
permissions:
|
|
@@ -252,6 +316,9 @@ jobs:
|
|
|
252
316
|
# (CodySwannGT/lisa#3698).
|
|
253
317
|
expected_workflow_contract_major: '1'
|
|
254
318
|
environment: ${{ needs.determine_environment.outputs.environment }}
|
|
319
|
+
deployment_branch: ${{ needs.determine_environment.outputs.environment }}
|
|
320
|
+
source_ref: ${{ inputs.force_stale_deploy == true && (inputs.rollback_commit || github.sha) || needs.release.outputs.release_commit || github.sha }}
|
|
321
|
+
force_stale_deploy: ${{ github.event_name == 'workflow_dispatch' && inputs.force_stale_deploy == true }}
|
|
255
322
|
secrets:
|
|
256
323
|
EXPO_TOKEN: ${{ secrets.EXPO_TOKEN }}
|
|
257
324
|
LISA_SECRETS_BOOTSTRAP: ${{ secrets.BWS_ACCESS_TOKEN }}
|
|
@@ -325,7 +392,43 @@ jobs:
|
|
|
325
392
|
- name: Checkout repository
|
|
326
393
|
uses: actions/checkout@v6
|
|
327
394
|
with:
|
|
328
|
-
ref: ${{
|
|
395
|
+
ref: ${{ inputs.force_stale_deploy == true && (inputs.rollback_commit || github.sha) || needs.release.outputs.release_commit || github.sha }}
|
|
396
|
+
# Check the actual checkout again on job-only retries; earlier jobs may not rerun.
|
|
397
|
+
- name: 🚦 Refuse stale deployment
|
|
398
|
+
shell: bash
|
|
399
|
+
env:
|
|
400
|
+
DEPLOY_BRANCH: ${{ github.event_name == 'workflow_dispatch' && inputs.environment || github.ref_name }}
|
|
401
|
+
DEPLOY_EVENT: ${{ github.event_name }}
|
|
402
|
+
FORCE_STALE_DEPLOY: ${{ github.event_name == 'workflow_dispatch' && inputs.force_stale_deploy == true }}
|
|
403
|
+
run: |
|
|
404
|
+
set -euo pipefail
|
|
405
|
+
DEPLOY_SHA=$(git rev-parse HEAD)
|
|
406
|
+
TARGET_REF="refs/heads/$DEPLOY_BRANCH"
|
|
407
|
+
if ! git check-ref-format "$TARGET_REF"; then
|
|
408
|
+
echo "::error::Invalid deployment branch: $DEPLOY_BRANCH. Choose an existing branch."
|
|
409
|
+
exit 1
|
|
410
|
+
fi
|
|
411
|
+
if ! REMOTE=$(git ls-remote --exit-code --heads origin "$TARGET_REF"); then
|
|
412
|
+
echo "::error::Cannot read the current tip of $DEPLOY_BRANCH. Nothing will be deployed. Check repository access and the branch name, then retry."
|
|
413
|
+
exit 1
|
|
414
|
+
fi
|
|
415
|
+
read -r TIP RESOLVED_REF <<< "$REMOTE"
|
|
416
|
+
if [[ ! "$TIP" =~ ^[0-9a-f]{40}$ ]] || [ "$RESOLVED_REF" != "$TARGET_REF" ]; then
|
|
417
|
+
echo "::error::Could not verify the current tip of $DEPLOY_BRANCH. Nothing will be deployed."
|
|
418
|
+
exit 1
|
|
419
|
+
fi
|
|
420
|
+
if [ "$DEPLOY_SHA" = "$TIP" ]; then
|
|
421
|
+
echo "✅ Deployment commit $DEPLOY_SHA is the current tip of $DEPLOY_BRANCH."
|
|
422
|
+
exit 0
|
|
423
|
+
fi
|
|
424
|
+
if [ "$DEPLOY_EVENT" = "workflow_dispatch" ] && [ "$FORCE_STALE_DEPLOY" = "true" ]; then
|
|
425
|
+
echo "::warning title=Deliberate stale deployment::Deploying non-tip commit $DEPLOY_SHA to $DEPLOY_BRANCH; the current branch tip is $TIP. force_stale_deploy was explicitly enabled."
|
|
426
|
+
echo "### ⚠️ Deliberate rollback: deploying $DEPLOY_SHA to $DEPLOY_BRANCH instead of current tip $TIP." >> "${GITHUB_STEP_SUMMARY:-/dev/stdout}"
|
|
427
|
+
exit 0
|
|
428
|
+
fi
|
|
429
|
+
echo "::error title=Stale deployment refused::This run would deploy $DEPLOY_SHA, but $DEPLOY_BRANCH is now at $TIP. This is probably a re-run of an old run and would roll the environment back. Re-run the latest deploy run for this branch, or start workflow_dispatch on the branch tip. For a deliberate rollback only, explicitly enable force_stale_deploy in a manual run."
|
|
430
|
+
exit 1
|
|
431
|
+
|
|
329
432
|
- name: 🔧 Setup Node.js
|
|
330
433
|
uses: actions/setup-node@v6
|
|
331
434
|
with:
|
|
@@ -11,12 +11,70 @@ on:
|
|
|
11
11
|
branches:
|
|
12
12
|
- main
|
|
13
13
|
workflow_dispatch:
|
|
14
|
+
inputs:
|
|
15
|
+
rollback_commit:
|
|
16
|
+
description: 'Commit SHA to deploy for a deliberate rollback; leave empty for the run commit'
|
|
17
|
+
required: false
|
|
18
|
+
default: ''
|
|
19
|
+
type: string
|
|
20
|
+
force_stale_deploy:
|
|
21
|
+
description: "Allow a deliberate rollback to this run's old commit (may overwrite a newer deployment)"
|
|
22
|
+
required: false
|
|
23
|
+
default: false
|
|
24
|
+
type: boolean
|
|
14
25
|
|
|
15
26
|
concurrency:
|
|
16
27
|
group: harper-fabric-deploy-${{ github.ref }}
|
|
17
28
|
cancel-in-progress: true
|
|
18
29
|
|
|
19
30
|
jobs:
|
|
31
|
+
# Re-runs retain their original SHA. Refuse an old run before release or deployment.
|
|
32
|
+
validate_deploy_commit:
|
|
33
|
+
name: 🚦 Validate Deployment Commit
|
|
34
|
+
runs-on: ubuntu-latest
|
|
35
|
+
timeout-minutes: 5
|
|
36
|
+
permissions:
|
|
37
|
+
contents: read
|
|
38
|
+
steps:
|
|
39
|
+
- uses: actions/checkout@v6
|
|
40
|
+
with:
|
|
41
|
+
ref: ${{ github.event_name == 'workflow_dispatch' && inputs.rollback_commit || github.sha }}
|
|
42
|
+
# Check the actual checkout again on job-only retries; earlier jobs may not rerun.
|
|
43
|
+
- name: 🚦 Refuse stale deployment
|
|
44
|
+
shell: bash
|
|
45
|
+
env:
|
|
46
|
+
DEPLOY_BRANCH: ${{ github.event_name == 'workflow_dispatch' && inputs.environment || github.ref_name }}
|
|
47
|
+
DEPLOY_EVENT: ${{ github.event_name }}
|
|
48
|
+
FORCE_STALE_DEPLOY: ${{ github.event_name == 'workflow_dispatch' && inputs.force_stale_deploy == true }}
|
|
49
|
+
run: |
|
|
50
|
+
set -euo pipefail
|
|
51
|
+
DEPLOY_SHA=$(git rev-parse HEAD)
|
|
52
|
+
TARGET_REF="refs/heads/$DEPLOY_BRANCH"
|
|
53
|
+
if ! git check-ref-format "$TARGET_REF"; then
|
|
54
|
+
echo "::error::Invalid deployment branch: $DEPLOY_BRANCH. Choose an existing branch."
|
|
55
|
+
exit 1
|
|
56
|
+
fi
|
|
57
|
+
if ! REMOTE=$(git ls-remote --exit-code --heads origin "$TARGET_REF"); then
|
|
58
|
+
echo "::error::Cannot read the current tip of $DEPLOY_BRANCH. Nothing will be deployed. Check repository access and the branch name, then retry."
|
|
59
|
+
exit 1
|
|
60
|
+
fi
|
|
61
|
+
read -r TIP RESOLVED_REF <<< "$REMOTE"
|
|
62
|
+
if [[ ! "$TIP" =~ ^[0-9a-f]{40}$ ]] || [ "$RESOLVED_REF" != "$TARGET_REF" ]; then
|
|
63
|
+
echo "::error::Could not verify the current tip of $DEPLOY_BRANCH. Nothing will be deployed."
|
|
64
|
+
exit 1
|
|
65
|
+
fi
|
|
66
|
+
if [ "$DEPLOY_SHA" = "$TIP" ]; then
|
|
67
|
+
echo "✅ Deployment commit $DEPLOY_SHA is the current tip of $DEPLOY_BRANCH."
|
|
68
|
+
exit 0
|
|
69
|
+
fi
|
|
70
|
+
if [ "$DEPLOY_EVENT" = "workflow_dispatch" ] && [ "$FORCE_STALE_DEPLOY" = "true" ]; then
|
|
71
|
+
echo "::warning title=Deliberate stale deployment::Deploying non-tip commit $DEPLOY_SHA to $DEPLOY_BRANCH; the current branch tip is $TIP. force_stale_deploy was explicitly enabled."
|
|
72
|
+
echo "### ⚠️ Deliberate rollback: deploying $DEPLOY_SHA to $DEPLOY_BRANCH instead of current tip $TIP." >> "${GITHUB_STEP_SUMMARY:-/dev/stdout}"
|
|
73
|
+
exit 0
|
|
74
|
+
fi
|
|
75
|
+
echo "::error title=Stale deployment refused::This run would deploy $DEPLOY_SHA, but $DEPLOY_BRANCH is now at $TIP. This is probably a re-run of an old run and would roll the environment back. Re-run the latest deploy run for this branch, or start workflow_dispatch on the branch tip. For a deliberate rollback only, explicitly enable force_stale_deploy in a manual run."
|
|
76
|
+
exit 1
|
|
77
|
+
|
|
20
78
|
# ── Pre-deploy gates ──────────────────────────────────────────────────────
|
|
21
79
|
# Resolves `pre-deploy:<branch>` from the `gates` block of .lisa.config.json
|
|
22
80
|
# and runs whatever is declared there, BEFORE the deploy job.
|
|
@@ -30,6 +88,7 @@ jobs:
|
|
|
30
88
|
# nothing is deployed. A gate job running BESIDE the deploy would go red after
|
|
31
89
|
# the thing had already shipped, which is a report.
|
|
32
90
|
pre_deploy_gates:
|
|
91
|
+
needs: [validate_deploy_commit]
|
|
33
92
|
name: 🚦 Pre-Deploy Gates
|
|
34
93
|
uses: CodySwannGT/lisa/.github/workflows/gates.yml@main
|
|
35
94
|
with:
|
|
@@ -60,6 +119,44 @@ jobs:
|
|
|
60
119
|
steps:
|
|
61
120
|
- name: Checkout
|
|
62
121
|
uses: actions/checkout@v6
|
|
122
|
+
with:
|
|
123
|
+
ref: ${{ inputs.force_stale_deploy == true && (inputs.rollback_commit || github.sha) || github.sha }}
|
|
124
|
+
|
|
125
|
+
# Check the actual checkout again on job-only retries; earlier jobs may not rerun.
|
|
126
|
+
- name: 🚦 Refuse stale deployment
|
|
127
|
+
shell: bash
|
|
128
|
+
env:
|
|
129
|
+
DEPLOY_BRANCH: ${{ github.event_name == 'workflow_dispatch' && inputs.environment || github.ref_name }}
|
|
130
|
+
DEPLOY_EVENT: ${{ github.event_name }}
|
|
131
|
+
FORCE_STALE_DEPLOY: ${{ github.event_name == 'workflow_dispatch' && inputs.force_stale_deploy == true }}
|
|
132
|
+
run: |
|
|
133
|
+
set -euo pipefail
|
|
134
|
+
DEPLOY_SHA=$(git rev-parse HEAD)
|
|
135
|
+
TARGET_REF="refs/heads/$DEPLOY_BRANCH"
|
|
136
|
+
if ! git check-ref-format "$TARGET_REF"; then
|
|
137
|
+
echo "::error::Invalid deployment branch: $DEPLOY_BRANCH. Choose an existing branch."
|
|
138
|
+
exit 1
|
|
139
|
+
fi
|
|
140
|
+
if ! REMOTE=$(git ls-remote --exit-code --heads origin "$TARGET_REF"); then
|
|
141
|
+
echo "::error::Cannot read the current tip of $DEPLOY_BRANCH. Nothing will be deployed. Check repository access and the branch name, then retry."
|
|
142
|
+
exit 1
|
|
143
|
+
fi
|
|
144
|
+
read -r TIP RESOLVED_REF <<< "$REMOTE"
|
|
145
|
+
if [[ ! "$TIP" =~ ^[0-9a-f]{40}$ ]] || [ "$RESOLVED_REF" != "$TARGET_REF" ]; then
|
|
146
|
+
echo "::error::Could not verify the current tip of $DEPLOY_BRANCH. Nothing will be deployed."
|
|
147
|
+
exit 1
|
|
148
|
+
fi
|
|
149
|
+
if [ "$DEPLOY_SHA" = "$TIP" ]; then
|
|
150
|
+
echo "✅ Deployment commit $DEPLOY_SHA is the current tip of $DEPLOY_BRANCH."
|
|
151
|
+
exit 0
|
|
152
|
+
fi
|
|
153
|
+
if [ "$DEPLOY_EVENT" = "workflow_dispatch" ] && [ "$FORCE_STALE_DEPLOY" = "true" ]; then
|
|
154
|
+
echo "::warning title=Deliberate stale deployment::Deploying non-tip commit $DEPLOY_SHA to $DEPLOY_BRANCH; the current branch tip is $TIP. force_stale_deploy was explicitly enabled."
|
|
155
|
+
echo "### ⚠️ Deliberate rollback: deploying $DEPLOY_SHA to $DEPLOY_BRANCH instead of current tip $TIP." >> "${GITHUB_STEP_SUMMARY:-/dev/stdout}"
|
|
156
|
+
exit 0
|
|
157
|
+
fi
|
|
158
|
+
echo "::error title=Stale deployment refused::This run would deploy $DEPLOY_SHA, but $DEPLOY_BRANCH is now at $TIP. This is probably a re-run of an old run and would roll the environment back. Re-run the latest deploy run for this branch, or start workflow_dispatch on the branch tip. For a deliberate rollback only, explicitly enable force_stale_deploy in a manual run."
|
|
159
|
+
exit 1
|
|
63
160
|
|
|
64
161
|
- name: Setup Node.js
|
|
65
162
|
uses: actions/setup-node@v6
|
|
@@ -22,6 +22,16 @@ on:
|
|
|
22
22
|
- dev
|
|
23
23
|
workflow_dispatch:
|
|
24
24
|
inputs:
|
|
25
|
+
rollback_commit:
|
|
26
|
+
description: 'Commit SHA to deploy for a deliberate rollback; leave empty for the run commit'
|
|
27
|
+
required: false
|
|
28
|
+
default: ''
|
|
29
|
+
type: string
|
|
30
|
+
force_stale_deploy:
|
|
31
|
+
description: "Allow a deliberate rollback to this run's old commit (may overwrite a newer deployment)"
|
|
32
|
+
required: false
|
|
33
|
+
default: false
|
|
34
|
+
type: boolean
|
|
25
35
|
environment:
|
|
26
36
|
description: 'Environment to deploy to'
|
|
27
37
|
required: true
|
|
@@ -38,6 +48,53 @@ concurrency:
|
|
|
38
48
|
cancel-in-progress: true
|
|
39
49
|
|
|
40
50
|
jobs:
|
|
51
|
+
# Re-runs retain their original SHA. Refuse an old run before release or deployment.
|
|
52
|
+
validate_deploy_commit:
|
|
53
|
+
name: 🚦 Validate Deployment Commit
|
|
54
|
+
runs-on: ubuntu-latest
|
|
55
|
+
timeout-minutes: 5
|
|
56
|
+
permissions:
|
|
57
|
+
contents: read
|
|
58
|
+
steps:
|
|
59
|
+
- uses: actions/checkout@v6
|
|
60
|
+
with:
|
|
61
|
+
ref: ${{ github.event_name == 'workflow_dispatch' && inputs.rollback_commit || github.sha }}
|
|
62
|
+
# Check the actual checkout again on job-only retries; earlier jobs may not rerun.
|
|
63
|
+
- name: 🚦 Refuse stale deployment
|
|
64
|
+
shell: bash
|
|
65
|
+
env:
|
|
66
|
+
DEPLOY_BRANCH: ${{ github.event_name == 'workflow_dispatch' && inputs.environment || github.ref_name }}
|
|
67
|
+
DEPLOY_EVENT: ${{ github.event_name }}
|
|
68
|
+
FORCE_STALE_DEPLOY: ${{ github.event_name == 'workflow_dispatch' && inputs.force_stale_deploy == true }}
|
|
69
|
+
run: |
|
|
70
|
+
set -euo pipefail
|
|
71
|
+
DEPLOY_SHA=$(git rev-parse HEAD)
|
|
72
|
+
TARGET_REF="refs/heads/$DEPLOY_BRANCH"
|
|
73
|
+
if ! git check-ref-format "$TARGET_REF"; then
|
|
74
|
+
echo "::error::Invalid deployment branch: $DEPLOY_BRANCH. Choose an existing branch."
|
|
75
|
+
exit 1
|
|
76
|
+
fi
|
|
77
|
+
if ! REMOTE=$(git ls-remote --exit-code --heads origin "$TARGET_REF"); then
|
|
78
|
+
echo "::error::Cannot read the current tip of $DEPLOY_BRANCH. Nothing will be deployed. Check repository access and the branch name, then retry."
|
|
79
|
+
exit 1
|
|
80
|
+
fi
|
|
81
|
+
read -r TIP RESOLVED_REF <<< "$REMOTE"
|
|
82
|
+
if [[ ! "$TIP" =~ ^[0-9a-f]{40}$ ]] || [ "$RESOLVED_REF" != "$TARGET_REF" ]; then
|
|
83
|
+
echo "::error::Could not verify the current tip of $DEPLOY_BRANCH. Nothing will be deployed."
|
|
84
|
+
exit 1
|
|
85
|
+
fi
|
|
86
|
+
if [ "$DEPLOY_SHA" = "$TIP" ]; then
|
|
87
|
+
echo "✅ Deployment commit $DEPLOY_SHA is the current tip of $DEPLOY_BRANCH."
|
|
88
|
+
exit 0
|
|
89
|
+
fi
|
|
90
|
+
if [ "$DEPLOY_EVENT" = "workflow_dispatch" ] && [ "$FORCE_STALE_DEPLOY" = "true" ]; then
|
|
91
|
+
echo "::warning title=Deliberate stale deployment::Deploying non-tip commit $DEPLOY_SHA to $DEPLOY_BRANCH; the current branch tip is $TIP. force_stale_deploy was explicitly enabled."
|
|
92
|
+
echo "### ⚠️ Deliberate rollback: deploying $DEPLOY_SHA to $DEPLOY_BRANCH instead of current tip $TIP." >> "${GITHUB_STEP_SUMMARY:-/dev/stdout}"
|
|
93
|
+
exit 0
|
|
94
|
+
fi
|
|
95
|
+
echo "::error title=Stale deployment refused::This run would deploy $DEPLOY_SHA, but $DEPLOY_BRANCH is now at $TIP. This is probably a re-run of an old run and would roll the environment back. Re-run the latest deploy run for this branch, or start workflow_dispatch on the branch tip. For a deliberate rollback only, explicitly enable force_stale_deploy in a manual run."
|
|
96
|
+
exit 1
|
|
97
|
+
|
|
41
98
|
# Environment setup
|
|
42
99
|
determine_environment:
|
|
43
100
|
name: 🌍 Determine Environment
|
|
@@ -100,7 +157,7 @@ jobs:
|
|
|
100
157
|
pre_deploy_gates:
|
|
101
158
|
name: 🚦 Pre-Deploy Gates
|
|
102
159
|
uses: CodySwannGT/lisa/.github/workflows/gates.yml@main
|
|
103
|
-
needs: [determine_environment]
|
|
160
|
+
needs: [determine_environment, validate_deploy_commit]
|
|
104
161
|
with:
|
|
105
162
|
# Travels with the `uses:` line above — the two are one unit. Lisa's
|
|
106
163
|
# reusable workflows are tracked at `@main`, so that file changes under
|
|
@@ -235,13 +292,51 @@ jobs:
|
|
|
235
292
|
migrate:
|
|
236
293
|
name: Schema Migrations
|
|
237
294
|
runs-on: ubuntu-latest
|
|
238
|
-
needs: verify_vpn
|
|
295
|
+
needs: [verify_vpn, release]
|
|
239
296
|
if: always() && needs.verify_vpn.outputs.has_vpn_setup == 'true'
|
|
240
297
|
permissions:
|
|
241
298
|
id-token: write # needed to interact with GitHub's OIDC Token endpoint.
|
|
242
299
|
contents: read
|
|
243
300
|
steps:
|
|
244
301
|
- uses: actions/checkout@v6
|
|
302
|
+
with:
|
|
303
|
+
ref: ${{ inputs.force_stale_deploy == true && (inputs.rollback_commit || github.sha) || needs.release.outputs.release_commit || github.sha }}
|
|
304
|
+
# Check the actual checkout again on job-only retries; earlier jobs may not rerun.
|
|
305
|
+
- name: 🚦 Refuse stale deployment
|
|
306
|
+
shell: bash
|
|
307
|
+
env:
|
|
308
|
+
DEPLOY_BRANCH: ${{ github.event_name == 'workflow_dispatch' && inputs.environment || github.ref_name }}
|
|
309
|
+
DEPLOY_EVENT: ${{ github.event_name }}
|
|
310
|
+
FORCE_STALE_DEPLOY: ${{ github.event_name == 'workflow_dispatch' && inputs.force_stale_deploy == true }}
|
|
311
|
+
run: |
|
|
312
|
+
set -euo pipefail
|
|
313
|
+
DEPLOY_SHA=$(git rev-parse HEAD)
|
|
314
|
+
TARGET_REF="refs/heads/$DEPLOY_BRANCH"
|
|
315
|
+
if ! git check-ref-format "$TARGET_REF"; then
|
|
316
|
+
echo "::error::Invalid deployment branch: $DEPLOY_BRANCH. Choose an existing branch."
|
|
317
|
+
exit 1
|
|
318
|
+
fi
|
|
319
|
+
if ! REMOTE=$(git ls-remote --exit-code --heads origin "$TARGET_REF"); then
|
|
320
|
+
echo "::error::Cannot read the current tip of $DEPLOY_BRANCH. Nothing will be deployed. Check repository access and the branch name, then retry."
|
|
321
|
+
exit 1
|
|
322
|
+
fi
|
|
323
|
+
read -r TIP RESOLVED_REF <<< "$REMOTE"
|
|
324
|
+
if [[ ! "$TIP" =~ ^[0-9a-f]{40}$ ]] || [ "$RESOLVED_REF" != "$TARGET_REF" ]; then
|
|
325
|
+
echo "::error::Could not verify the current tip of $DEPLOY_BRANCH. Nothing will be deployed."
|
|
326
|
+
exit 1
|
|
327
|
+
fi
|
|
328
|
+
if [ "$DEPLOY_SHA" = "$TIP" ]; then
|
|
329
|
+
echo "✅ Deployment commit $DEPLOY_SHA is the current tip of $DEPLOY_BRANCH."
|
|
330
|
+
exit 0
|
|
331
|
+
fi
|
|
332
|
+
if [ "$DEPLOY_EVENT" = "workflow_dispatch" ] && [ "$FORCE_STALE_DEPLOY" = "true" ]; then
|
|
333
|
+
echo "::warning title=Deliberate stale deployment::Deploying non-tip commit $DEPLOY_SHA to $DEPLOY_BRANCH; the current branch tip is $TIP. force_stale_deploy was explicitly enabled."
|
|
334
|
+
echo "### ⚠️ Deliberate rollback: deploying $DEPLOY_SHA to $DEPLOY_BRANCH instead of current tip $TIP." >> "${GITHUB_STEP_SUMMARY:-/dev/stdout}"
|
|
335
|
+
exit 0
|
|
336
|
+
fi
|
|
337
|
+
echo "::error title=Stale deployment refused::This run would deploy $DEPLOY_SHA, but $DEPLOY_BRANCH is now at $TIP. This is probably a re-run of an old run and would roll the environment back. Re-run the latest deploy run for this branch, or start workflow_dispatch on the branch tip. For a deliberate rollback only, explicitly enable force_stale_deploy in a manual run."
|
|
338
|
+
exit 1
|
|
339
|
+
|
|
245
340
|
- uses: noliran/branch-based-secrets@ef9182f16f118c7c3d05c36973546ebc990b8c69 # v1 (2020-10-09, no semver tag)
|
|
246
341
|
with:
|
|
247
342
|
secrets: AWS_ACCOUNT_ID
|
|
@@ -306,6 +401,44 @@ jobs:
|
|
|
306
401
|
contents: read
|
|
307
402
|
steps:
|
|
308
403
|
- uses: actions/checkout@v6
|
|
404
|
+
with:
|
|
405
|
+
ref: ${{ inputs.force_stale_deploy == true && (inputs.rollback_commit || github.sha) || needs.release.outputs.release_commit || github.sha }}
|
|
406
|
+
# Check the actual checkout again on job-only retries; earlier jobs may not rerun.
|
|
407
|
+
- name: 🚦 Refuse stale deployment
|
|
408
|
+
shell: bash
|
|
409
|
+
env:
|
|
410
|
+
DEPLOY_BRANCH: ${{ github.event_name == 'workflow_dispatch' && inputs.environment || github.ref_name }}
|
|
411
|
+
DEPLOY_EVENT: ${{ github.event_name }}
|
|
412
|
+
FORCE_STALE_DEPLOY: ${{ github.event_name == 'workflow_dispatch' && inputs.force_stale_deploy == true }}
|
|
413
|
+
run: |
|
|
414
|
+
set -euo pipefail
|
|
415
|
+
DEPLOY_SHA=$(git rev-parse HEAD)
|
|
416
|
+
TARGET_REF="refs/heads/$DEPLOY_BRANCH"
|
|
417
|
+
if ! git check-ref-format "$TARGET_REF"; then
|
|
418
|
+
echo "::error::Invalid deployment branch: $DEPLOY_BRANCH. Choose an existing branch."
|
|
419
|
+
exit 1
|
|
420
|
+
fi
|
|
421
|
+
if ! REMOTE=$(git ls-remote --exit-code --heads origin "$TARGET_REF"); then
|
|
422
|
+
echo "::error::Cannot read the current tip of $DEPLOY_BRANCH. Nothing will be deployed. Check repository access and the branch name, then retry."
|
|
423
|
+
exit 1
|
|
424
|
+
fi
|
|
425
|
+
read -r TIP RESOLVED_REF <<< "$REMOTE"
|
|
426
|
+
if [[ ! "$TIP" =~ ^[0-9a-f]{40}$ ]] || [ "$RESOLVED_REF" != "$TARGET_REF" ]; then
|
|
427
|
+
echo "::error::Could not verify the current tip of $DEPLOY_BRANCH. Nothing will be deployed."
|
|
428
|
+
exit 1
|
|
429
|
+
fi
|
|
430
|
+
if [ "$DEPLOY_SHA" = "$TIP" ]; then
|
|
431
|
+
echo "✅ Deployment commit $DEPLOY_SHA is the current tip of $DEPLOY_BRANCH."
|
|
432
|
+
exit 0
|
|
433
|
+
fi
|
|
434
|
+
if [ "$DEPLOY_EVENT" = "workflow_dispatch" ] && [ "$FORCE_STALE_DEPLOY" = "true" ]; then
|
|
435
|
+
echo "::warning title=Deliberate stale deployment::Deploying non-tip commit $DEPLOY_SHA to $DEPLOY_BRANCH; the current branch tip is $TIP. force_stale_deploy was explicitly enabled."
|
|
436
|
+
echo "### ⚠️ Deliberate rollback: deploying $DEPLOY_SHA to $DEPLOY_BRANCH instead of current tip $TIP." >> "${GITHUB_STEP_SUMMARY:-/dev/stdout}"
|
|
437
|
+
exit 0
|
|
438
|
+
fi
|
|
439
|
+
echo "::error title=Stale deployment refused::This run would deploy $DEPLOY_SHA, but $DEPLOY_BRANCH is now at $TIP. This is probably a re-run of an old run and would roll the environment back. Re-run the latest deploy run for this branch, or start workflow_dispatch on the branch tip. For a deliberate rollback only, explicitly enable force_stale_deploy in a manual run."
|
|
440
|
+
exit 1
|
|
441
|
+
|
|
309
442
|
- name: Use Node.js 24.21.0
|
|
310
443
|
uses: actions/setup-node@v6
|
|
311
444
|
with:
|
package/package.json
CHANGED
|
@@ -189,7 +189,7 @@
|
|
|
189
189
|
"qs": "^6.16.0"
|
|
190
190
|
},
|
|
191
191
|
"name": "@codyswann/lisa",
|
|
192
|
-
"version": "4.74.
|
|
192
|
+
"version": "4.74.3",
|
|
193
193
|
"description": "Claude Code governance framework that applies guardrails, guidance, and automated enforcement to projects",
|
|
194
194
|
"main": "dist/index.js",
|
|
195
195
|
"exports": {
|
|
@@ -345,7 +345,7 @@
|
|
|
345
345
|
"test": "tests"
|
|
346
346
|
},
|
|
347
347
|
"types": "./dist/index.d.ts",
|
|
348
|
-
"lisaReleaseCommit": "
|
|
349
|
-
"gitHead": "
|
|
350
|
-
"lisaReleaseTag": "v4.74.
|
|
348
|
+
"lisaReleaseCommit": "5c1778a99257c712d1ce7314a3e4fac988dd5332",
|
|
349
|
+
"gitHead": "5c1778a99257c712d1ce7314a3e4fac988dd5332",
|
|
350
|
+
"lisaReleaseTag": "v4.74.3"
|
|
351
351
|
}
|