Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
be0eca0
job_runs: add lifecycle.triggers.on_file_change
radakam Aug 18, 2026
926b8cf
job_runs: fix exhaustruct and regenerate refschema for on_file_change
radakam Aug 18, 2026
f181266
job_runs: tighten on_file_change path and directory checks
radakam Aug 18, 2026
7255a17
job_runs: store on_file_change as path-to-hash only
radakam Aug 18, 2026
a02fd3d
job_runs: use maps.Copy in on_file_change hash merge
radakam Aug 18, 2026
43cf3cf
job_runs: drop filepath.Glob jargon from on_file_change schema docs
radakam Aug 19, 2026
47994d8
acc: refresh on_file_change goldens for resource-key progress lines
radakam Aug 19, 2026
132ba7b
acc: cover on_file_change globs, errors, and appear/disappear
radakam Aug 19, 2026
75eaf87
acc: expand on_file_change glob coverage and skip ignored files
radakam Aug 19, 2026
4e43352
acc: force-add gitignored on_file_change fixture
radakam Aug 19, 2026
a7a3275
acc: drop READPLAN from the on_file_change glob test
radakam Aug 20, 2026
786a2d2
acc: restore READPLAN on the on_file_change glob test
radakam Aug 20, 2026
76c0d70
job_runs: address on_file_change review comments
radakam Aug 20, 2026
e1fbadc
job_runs: list every trigger field to satisfy exhaustruct
radakam Aug 20, 2026
eb7c422
job_runs: keep empty nested lifecycle on state and remote
radakam Aug 21, 2026
451d13c
job_runs: keep the lifecycle fingerprint out of the remote type
radakam Aug 21, 2026
9bc1c42
job_runs: store on_file_change hashes on the trigger itself
radakam Aug 24, 2026
5a213cf
job_runs: drop unit tests already covered by acceptance
radakam Aug 24, 2026
be93694
acc: refresh job_runs goldens for the omitted empty trigger
radakam Aug 24, 2026
d5042f3
job_runs: cover cancel-before-delete with an acceptance test
radakam Aug 24, 2026
9e0b681
Add job_runs lifecycle.triggers.on_value_change
radakam Aug 21, 2026
e431088
Regenerate job_runs reference schema fields
radakam Aug 21, 2026
d2ca935
job_runs: add lifecycle.triggers.on_file_change
radakam Aug 18, 2026
b4665d0
job_runs: fix exhaustruct and regenerate refschema for on_file_change
radakam Aug 18, 2026
ecf44ef
job_runs: tighten on_file_change path and directory checks
radakam Aug 18, 2026
4a0a2b4
job_runs: store on_file_change as path-to-hash only
radakam Aug 18, 2026
25f9566
job_runs: use maps.Copy in on_file_change hash merge
radakam Aug 18, 2026
16367e6
job_runs: drop filepath.Glob jargon from on_file_change schema docs
radakam Aug 19, 2026
83bbb02
acc: refresh on_file_change goldens for resource-key progress lines
radakam Aug 19, 2026
1b73b00
acc: cover on_file_change globs, errors, and appear/disappear
radakam Aug 19, 2026
9e7c0fd
acc: expand on_file_change glob coverage and skip ignored files
radakam Aug 19, 2026
4bf37e7
acc: force-add gitignored on_file_change fixture
radakam Aug 19, 2026
4a05a4c
acc: drop READPLAN from the on_file_change glob test
radakam Aug 20, 2026
59d34ca
acc: restore READPLAN on the on_file_change glob test
radakam Aug 20, 2026
f344a7e
job_runs: address on_file_change review comments
radakam Aug 20, 2026
3850eb8
job_runs: list every trigger field to satisfy exhaustruct
radakam Aug 20, 2026
b27c4ff
job_runs: keep empty nested lifecycle on state and remote
radakam Aug 21, 2026
1d77e53
job_runs: keep the lifecycle fingerprint out of the remote type
radakam Aug 21, 2026
1364bf9
job_runs: store on_file_change hashes on the trigger itself
radakam Aug 24, 2026
bd2b531
job_runs: drop unit tests already covered by acceptance
radakam Aug 24, 2026
ee9196b
acc: refresh job_runs goldens for the omitted empty trigger
radakam Aug 24, 2026
9e25ff8
job_runs: cover cancel-before-delete with an acceptance test
radakam Aug 24, 2026
c255530
job_runs: error when on_file_change hashes nothing
radakam Aug 24, 2026
79b269e
acc: fix on_file_change_errors diagnostic line numbers
radakam Aug 24, 2026
4e7b960
acc: removing on_file_change is unchanged, not an update
radakam Aug 24, 2026
95668fb
Merge origin/deco-job-runs-lifecycle-on-file-change into deco-job-run…
radakam Aug 24, 2026
3865b6b
job_runs: drop on_value_change unit tests covered by acceptance
radakam Aug 24, 2026
74b03ca
job_runs: drop unit tests covered by acceptance
radakam Aug 24, 2026
3285057
acc: match job_runs script file mode
radakam Aug 24, 2026
5580fe8
job_runs: add lifecycle.triggers.on_file_change
radakam Aug 18, 2026
8d001bd
job_runs: fix exhaustruct and regenerate refschema for on_file_change
radakam Aug 18, 2026
6959d1d
job_runs: tighten on_file_change path and directory checks
radakam Aug 18, 2026
38df5ff
job_runs: store on_file_change as path-to-hash only
radakam Aug 18, 2026
55e71e0
job_runs: use maps.Copy in on_file_change hash merge
radakam Aug 18, 2026
6eb2db2
job_runs: drop filepath.Glob jargon from on_file_change schema docs
radakam Aug 19, 2026
0ce58fd
acc: refresh on_file_change goldens for resource-key progress lines
radakam Aug 19, 2026
3e384a1
acc: cover on_file_change globs, errors, and appear/disappear
radakam Aug 19, 2026
fd93d18
acc: expand on_file_change glob coverage and skip ignored files
radakam Aug 19, 2026
8763d63
acc: force-add gitignored on_file_change fixture
radakam Aug 19, 2026
bd2b3f8
acc: drop READPLAN from the on_file_change glob test
radakam Aug 20, 2026
8595e98
acc: restore READPLAN on the on_file_change glob test
radakam Aug 20, 2026
ab142ed
job_runs: address on_file_change review comments
radakam Aug 20, 2026
cc95d73
job_runs: list every trigger field to satisfy exhaustruct
radakam Aug 20, 2026
d05a78a
job_runs: keep empty nested lifecycle on state and remote
radakam Aug 21, 2026
55a78ca
job_runs: keep the lifecycle fingerprint out of the remote type
radakam Aug 21, 2026
196a6c6
job_runs: store on_file_change hashes on the trigger itself
radakam Aug 24, 2026
b00042c
acc: refresh job_runs goldens for the omitted empty trigger
radakam Aug 24, 2026
2006c6c
job_runs: error when on_file_change hashes nothing
radakam Aug 24, 2026
7014ae4
acc: fix on_file_change_errors diagnostic line numbers
radakam Aug 24, 2026
2dda9e3
acc: removing on_file_change is unchanged, not an update
radakam Aug 24, 2026
45c4ccd
job_runs: resolve on_file_change relative to the defining YAML file
radakam Aug 24, 2026
7ecdacd
job_runs: reject absolute on_file_change patterns
radakam Aug 25, 2026
e82ba0d
Merge origin/deco-job-runs-lifecycle-on-file-change into deco-job-run…
radakam Aug 25, 2026
d2b9010
Merge origin/deco-job-runs-lifecycle-on-file-change into deco-job-run…
radakam Aug 25, 2026
f3a4479
job_runs: collect the armed trigger names in one place
radakam Aug 25, 2026
2c1d501
structaccess: validate config reference paths strictly
radakam Aug 25, 2026
c12313f
job_runs: fingerprint the values watched by on_value_change
radakam Aug 25, 2026
4f50a39
job_runs: store on_value_change fingerprints as a list
radakam Aug 25, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .nextchanges/bundles/job-runs-on-value-change.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
direct: `resources.job_runs` can set `lifecycle.triggers.on_value_change` to an interpolated expression (for example `${resources.jobs.foo.id}`) to re-fire the run when that value changes. Long resolved values are recorded as a SHA-256 hash. Removing the trigger does not recreate the existing run.
3 changes: 3 additions & 0 deletions acceptance/bundle/refschema/out.fields.txt
Original file line number Diff line number Diff line change
Expand Up @@ -914,9 +914,12 @@ resources.job_runs.*.lifecycle.triggers dresources.JobRunTriggersState STATE
resources.job_runs.*.lifecycle.triggers.on_bundle_deploy string STATE
resources.job_runs.*.lifecycle.triggers.on_file_change map[string]string STATE
resources.job_runs.*.lifecycle.triggers.on_file_change.* string STATE
resources.job_runs.*.lifecycle.triggers.on_value_change []string STATE
resources.job_runs.*.lifecycle.triggers.on_value_change[*] string STATE
resources.job_runs.*.lifecycle.triggers[*] resources.JobRunTrigger INPUT
resources.job_runs.*.lifecycle.triggers[*].on_bundle_deploy *bool INPUT
resources.job_runs.*.lifecycle.triggers[*].on_file_change *string INPUT
resources.job_runs.*.lifecycle.triggers[*].on_value_change *string INPUT
resources.job_runs.*.modified_status string INPUT
resources.job_runs.*.notebook_params map[string]string ALL
resources.job_runs.*.notebook_params.* string ALL
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
bundle:
name: job-runs-on-value-change

variables:
stamp:
default: v1
other:
default: a1
long:
default: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

resources:
jobs:
my_job:
name: my-job
tasks:
- task_key: main
notebook_task:
notebook_path: /Workspace/test

job_runs:
my_run:
job_id: ${resources.jobs.my_job.id}
lifecycle:
triggers:
- on_value_change: ${var.stamp}
- on_value_change: ${var.other}
- on_value_change: ${var.long}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

187 changes: 187 additions & 0 deletions acceptance/bundle/resources/job_runs/on_value_change/output.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@

=== first deploy triggers a run
>>> [CLI] bundle deploy
Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/job-runs-on-value-change/default/files...
Output from job_runs.my_run: id=[MY_RUN_ID]: Run URL: [DATABRICKS_URL]/jobs/[MY_JOB_ID]/runs/[MY_RUN_ID]?o=[NUMID]
Output from job_runs.my_run: id=[MY_RUN_ID]: SUCCESS
Created job_runs.my_run
Created jobs.my_job
Files: 4 uploaded, 0 deleted
Resources: 2 created, 0 changed, 0 deleted, 0 unchanged

>>> read_id.py my_job
[MY_JOB_ID]

>>> print_requests.py //jobs/run-now
{
"method": "POST",
"path": "/api/2.2/jobs/run-now",
"body": {
"idempotency_token": "[UUID]",
"job_id": [MY_JOB_ID]
}
}

=== long values are stored as hashes
>>> print_state.py
[
"v1",
"a1",
"sha256:d66304b6180365e47c858f6c84d3da065caf4b3350c9f45277a1af82e3dbb055"
]

=== redeploy with unchanged values plans nothing
>>> [CLI] bundle plan
Plan: 0 to add, 0 to change, 0 to delete, 2 unchanged

>>> [CLI] bundle deploy
Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/job-runs-on-value-change/default/files...
Files: 2 uploaded, 0 deleted
Resources: 0 created, 0 changed, 0 deleted, 2 unchanged

>>> print_requests.py //jobs/run-now

=== changing one value re-fires
>>> [CLI] bundle plan
recreate job_runs.my_run

Plan: 1 to add, 0 to change, 1 to delete, 1 unchanged

>>> changes
{
"lifecycle.triggers.on_value_change": {
"action": "recreate",
"reason": "immutable",
"old": [
"v1",
"a1",
"sha256:d66304b6180365e47c858f6c84d3da065caf4b3350c9f45277a1af82e3dbb055"
],
"new": [
"v2",
"a1",
"sha256:d66304b6180365e47c858f6c84d3da065caf4b3350c9f45277a1af82e3dbb055"
]
},
"result_state": {
"action": "skip",
"reason": "remote_already_set",
"new": "SUCCESS",
"remote": "SUCCESS"
}
}

>>> [CLI] bundle deploy
Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/job-runs-on-value-change/default/files...
Output from job_runs.my_run: id=[MY_RUN_ID_2]: Run URL: [DATABRICKS_URL]/jobs/[MY_JOB_ID]/runs/[MY_RUN_ID_2]?o=[NUMID]
Output from job_runs.my_run: id=[MY_RUN_ID_2]: SUCCESS
Recreated job_runs.my_run
Files: 3 uploaded, 0 deleted
Resources: 1 created, 0 changed, 1 deleted, 1 unchanged

>>> print_requests.py --keep //jobs/runs/delete
{
"method": "POST",
"path": "/api/2.2/jobs/runs/delete",
"body": {
"run_id": [MY_RUN_ID]
}
}

>>> print_requests.py //jobs/run-now
{
"method": "POST",
"path": "/api/2.2/jobs/run-now",
"body": {
"idempotency_token": "[UUID]",
"job_id": [MY_JOB_ID]
}
}

=== converging two values re-fires
>>> [CLI] bundle plan
recreate job_runs.my_run

Plan: 1 to add, 0 to change, 1 to delete, 1 unchanged

>>> changes
{
"lifecycle.triggers.on_value_change": {
"action": "recreate",
"reason": "immutable",
"old": [
"v2",
"a1",
"sha256:d66304b6180365e47c858f6c84d3da065caf4b3350c9f45277a1af82e3dbb055"
],
"new": [
"v2",
"v2",
"sha256:d66304b6180365e47c858f6c84d3da065caf4b3350c9f45277a1af82e3dbb055"
]
},
"result_state": {
"action": "skip",
"reason": "remote_already_set",
"new": "SUCCESS",
"remote": "SUCCESS"
}
}

>>> [CLI] bundle deploy
Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/job-runs-on-value-change/default/files...
Output from job_runs.my_run: id=[MY_RUN_ID_3]: Run URL: [DATABRICKS_URL]/jobs/[MY_JOB_ID]/runs/[MY_RUN_ID_3]?o=[NUMID]
Output from job_runs.my_run: id=[MY_RUN_ID_3]: SUCCESS
Recreated job_runs.my_run
Files: 3 uploaded, 0 deleted
Resources: 1 created, 0 changed, 1 deleted, 1 unchanged

>>> print_requests.py --keep //jobs/runs/delete
{
"method": "POST",
"path": "/api/2.2/jobs/runs/delete",
"body": {
"run_id": [MY_RUN_ID_2]
}
}

>>> print_requests.py //jobs/run-now
{
"method": "POST",
"path": "/api/2.2/jobs/run-now",
"body": {
"idempotency_token": "[UUID]",
"job_id": [MY_JOB_ID]
}
}

=== removing one on_value_change is unchanged and does not run
>>> [CLI] bundle plan
Plan: 0 to add, 0 to change, 0 to delete, 2 unchanged

>>> [CLI] bundle deploy
Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/job-runs-on-value-change/default/files...
Files: 3 uploaded, 0 deleted
Resources: 0 created, 0 changed, 0 deleted, 2 unchanged

>>> print_requests.py //jobs/run-now

=== removing the last on_value_change is unchanged and does not run
>>> [CLI] bundle plan
Plan: 0 to add, 0 to change, 0 to delete, 2 unchanged

>>> [CLI] bundle deploy
Uploading bundle files to /Workspace/Users/[USERNAME]/.bundle/job-runs-on-value-change/default/files...
Files: 3 uploaded, 0 deleted
Resources: 0 created, 0 changed, 0 deleted, 2 unchanged

>>> print_requests.py //jobs/run-now

>>> [CLI] bundle destroy --auto-approve
The following resources will be deleted:
delete resources.job_runs.my_run
delete resources.jobs.my_job

All files and directories at the following location will be deleted: /Workspace/Users/[USERNAME]/.bundle/job-runs-on-value-change/default

Destroy: 2 deleted
58 changes: 58 additions & 0 deletions acceptance/bundle/resources/job_runs/on_value_change/script
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
cleanup() {
trace $CLI bundle destroy --auto-approve
rm -f out.requests.txt
}
trap cleanup EXIT

changes() {
$CLI bundle plan -o json | jq '.plan["resources.job_runs.my_run"].changes'
}

title "first deploy triggers a run"
trace $CLI bundle deploy
trace read_id.py my_job
read_id.py my_run > /dev/null
trace print_requests.py //jobs/run-now

title "long values are stored as hashes"
trace print_state.py | jq '.state["resources.job_runs.my_run"].state.lifecycle.triggers.on_value_change'

title "redeploy with unchanged values plans nothing"
trace $CLI bundle plan
trace $CLI bundle deploy
trace print_requests.py //jobs/run-now

title "changing one value re-fires"
update_file.py databricks.yml "default: v1" "default: v2"
trace $CLI bundle plan
trace changes
trace $CLI bundle deploy
read_id.py my_run > /dev/null
trace print_requests.py --keep //jobs/runs/delete
trace print_requests.py //jobs/run-now

title "converging two values re-fires"
update_file.py databricks.yml "default: a1" "default: v2"
trace $CLI bundle plan
trace changes
trace $CLI bundle deploy
read_id.py my_run > /dev/null
trace print_requests.py --keep //jobs/runs/delete
trace print_requests.py //jobs/run-now

title "removing one on_value_change is unchanged and does not run"
update_file.py databricks.yml ' - on_value_change: ${var.other}
' ''
trace $CLI bundle plan
trace $CLI bundle deploy
trace print_requests.py //jobs/run-now

title "removing the last on_value_change is unchanged and does not run"
update_file.py databricks.yml ' lifecycle:
triggers:
- on_value_change: ${var.stamp}
- on_value_change: ${var.long}
' ''
trace $CLI bundle plan
trace $CLI bundle deploy
trace print_requests.py //jobs/run-now
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
bundle:
name: job-runs-on-value-change-ref

resources:
jobs:
my_job:
name: my-job
tasks:
- task_key: main
notebook_task:
notebook_path: /Workspace/test

other:
name: other-job
tasks:
- task_key: main
notebook_task:
notebook_path: /Workspace/test

extra:
name: extra-job
tasks:
- task_key: main
notebook_task:
notebook_path: /Workspace/test

job_runs:
my_run:
job_id: ${resources.jobs.my_job.id}
lifecycle:
triggers:
- on_value_change: ${resources.jobs.other.id}-${resources.jobs.extra.id}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading