Skip to content

Skip app drift on deploy-only fields when there is no active deployment - #5943

Merged
radakam merged 4 commits into
mainfrom
fix-app-config-no-deployment-drift
Jul 22, 2026
Merged

Skip app drift on deploy-only fields when there is no active deployment#5943
radakam merged 4 commits into
mainfrom
fix-app-config-no-deployment-drift

Conversation

@radakam

@radakamradakam commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Changes

Skip drift reporting on the deploy-only app fields source_code_path, config, and git_source whenever the app has no active deployment, unifying all three under a single ActiveDeployment == nil check (reason: no active deployment). Also fix the test server's stop handler to clear the active deployment, matching the real backend, and add a test covering the stopped-app case.

Why

DoRead can only read these fields back from the app's active deployment. An app created without lifecycle.started (the default no_compute case) has none, so the fields read back empty while the bundle sets them — producing a phantom update in bundle plan that can never converge (these fields are excluded from the App Update call and only deploy on start). A stop can also clear the active_deployment for some apps (pending_deployment is always cleared), so the same spurious diff applies to a stopped app that has none; the previous source_code_path-only check and the "no deployment" wording didn't capture that. Verified against a real workspace: a never-started app and a stopped app that cleared its deployment both return active_deployment: null, while a running app returns it, so real out-of-band drift is still reported once a deployment exists. This is a plan-idempotency fix. A config/git_source change made while the app has no active deployment is applied on the next start (see manageLifecycle), not silently lost — it is deferred, not applied while stopped, because the API neither exposes nor accepts deployed config for a non-running app.

Tests

  • config-no-deployment / git-source-no-deployment: no-op plan on a never-started app.
  • config-drift-stopped: drift is detected while running, then skipped after stop.

This gap was found by fuzz testing.

@eng-dev-ecosystem-bot

eng-dev-ecosystem-bot commented Jul 16, 2026

Copy link
Copy Markdown
Collaborator

Integration test report

Commit: 167a01c

Run: 29810311210

Env💚​RECOVERED🙈​SKIP✅​pass🙈​skipTime
💚​aws linux4422711303:02
💚​aws windows4422911283:12
💚​aws-ucws linux4431410473:42
💚​aws-ucws windows4431610454:45
💚​azure linux4422711293:05
💚​azure windows4422911273:56
💚​azure-ucws linux4431610444:13
💚​azure-ucws windows4431810424:35
💚​gcp linux4422611312:36
💚​gcp windows4422811293:03
8 interesting tests: 4 RECOVERED, 4 SKIP
Test Nameaws linuxaws windowsaws-ucws linuxaws-ucws windowsazure linuxazure windowsazure-ucws linuxazure-ucws windowsgcp linuxgcp windows
💚​TestAccept💚​R💚​R💚​R💚​R💚​R💚​R💚​R💚​R💚​R💚​R
🙈​TestAccept/bundle/invariant/no_drift🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S
🙈​TestAccept/bundle/resources/vector_search_endpoints/drift/recreated_same_name🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S
🙈​TestAccept/bundle/resources/vector_search_indexes/recreate/embedding_dimension🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S
🙈​TestAccept/ssh/connection🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S
💚​TestFetchRepositoryInfoAPI_FromRepo💚​R💚​R💚​R💚​R💚​R💚​R💚​R💚​R💚​R💚​R
💚​TestFetchRepositoryInfoAPI_FromRepo/root💚​R💚​R💚​R💚​R💚​R💚​R💚​R💚​R💚​R💚​R
💚​TestFetchRepositoryInfoAPI_FromRepo/subdir💚​R💚​R💚​R💚​R💚​R💚​R💚​R💚​R💚​R💚​R
Top 5 slowest tests (at least 2 minutes):
durationenvtestname
3:26azure windowsTestAccept
3:16aws-ucws windowsTestAccept
2:40azure-ucws windowsTestAccept
2:19gcp windowsTestAccept
2:07aws windowsTestAccept

@radakam
radakamforce-pushed the fix-app-config-no-deployment-drift branch from 79153bb to 1957de9CompareJuly 16, 2026 12:21
The app deploy-only fields (config, git_source) are applied through an app
deployment, which only happens once the app compute is started (manageLifecycle).
Until then DoRead leaves them nil, so an app that set config or git_source
without lifecycle.started=true planned a perpetual update for a field that was
never deployed.
Extend OverrideChangeDesc to skip config and git_source while there is no active
deployment, keying off remote.ActiveDeployment. source_code_path was already
skipped; matching on the top-level field (Prefix(1)) now also catches nested
config diffs. Real out-of-band drift is still reported once a deployment exists.
Adds acceptance tests for the config and git_source cases.
@radakam
radakamforce-pushed the fix-app-config-no-deployment-drift branch from 1957de9 to a9a9561CompareJuly 16, 2026 12:26
@radakamradakam changed the title Skip app config/git_source drift when the app has no deploymentSkip spurious app config/git_source drift when app has no deploymentJul 17, 2026
Unify the deploy-only drift skip (source_code_path, config, git_source) on
ActiveDeployment == nil, which the backend also returns for a stopped app, not
just before the first deploy. Update the reason to "no active deployment" and fix
the test server's stop handler to clear the active deployment so acceptance tests
match cloud behavior. Add config-drift-stopped covering the stopped case.
@radakamradakam changed the title Skip spurious app config/git_source drift when app has no deploymentSkip app drift on deploy-only fields when there is no active deploymentJul 17, 2026
The active deployment is cleared on stop only for non-scalable apps; scalable
apps retain it (pending is always cleared). Soften the OverrideChangeDesc and
test-server comments accordingly. Comment-only, no behavior change.
@radakam
radakam marked this pull request as ready for review July 17, 2026 10:51
Comment threadlibs/testserver/apps.go Outdated
if remote.ActiveDeployment == nil {
change.Action = deployplan.Skip
change.Reason = "no active deployment"
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@andrewnester Is there impact for the lifecycle block?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From looks of it the change seems to be correct, the tets coverage for lifecycle seems to be pretty okay so I'd also rely on it to validate

The OverrideChangeDesc and test-server stop comments used an informal
"scalable/non-scalable" distinction that isn't API/SDK terminology and that the
skip logic never branches on (it only checks ActiveDeployment == nil). Reword
both to describe the observable behavior instead. Comment-only, no behavior change.
}
}

=== Stop the app: the backend clears the active deployment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure stopping actually clears active deployment, could you confirm this with real backend behaviour? I think active is only empty when the app was created but never deployed

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed against dogfood: a normally stopped app that was previously deployed returns active_deployment: null, so it seems that it's not limited to never-deployed apps.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for confirming!

@radakam
radakam added this pull request to the merge queueJul 22, 2026
Merged via the queue into main with commit 09d2395Jul 22, 2026
31 checks passed
@radakam
radakam deleted the fix-app-config-no-deployment-drift branch July 22, 2026 08:42
@eng-dev-ecosystem-bot

Copy link
Copy Markdown
Collaborator

Integration test report

Commit: 09d2395

Run: 29905087847

Env❌​FAIL🟨​KNOWN🔄​flaky💚​RECOVERED🙈​SKIP✅​pass🙈​skipTime
❌​aws linux24152963878249:02
❌​aws windows141452911896337:07
🔄​azure linux352880914202:37
❌​azure windows21852814932261:10
❌​gcp linux22422848920210:53
❌​gcp windows23422789938214:30
53 interesting tests: 39 FAIL, 6 flaky, 4 KNOWN, 2 RECOVERED, 2 SKIP
Test Nameaws linuxaws windowsazure linuxazure windowsgcp linuxgcp windows
🟨​TestAccept🟨​K🟨​K🔄​f🟨​K🟨​K🟨​K
❌​TestAccept/bundle/deployment/bind/pipelines/recreate❌​F✅​p✅​p✅​p✅​p✅​p
❌​TestAccept/bundle/deployment/bind/pipelines/recreate/DATABRICKS_BUNDLE_ENGINE=direct❌​F✅​p✅​p✅​p✅​p✅​p
💚​TestAccept/bundle/invariant/no_drift💚​R💚​R💚​R💚​R💚​R💚​R
🔄​TestAccept/bundle/resources/apps/inline_config✅​p✅​p✅​p🔄​f✅​p✅​p
🔄​TestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=terraform✅​p✅​p✅​p🔄​f✅​p✅​p
❌​TestAccept/bundle/resources/apps/lifecycle-started-omitted❌​F✅​p✅​p✅​p✅​p❌​F
❌​TestAccept/bundle/resources/apps/lifecycle-started-omitted/DATABRICKS_BUNDLE_ENGINE=direct❌​F✅​p✅​p✅​p✅​p❌​F
❌​TestAccept/bundle/resources/apps/lifecycle-started-toggle❌​F🔄​f✅​p✅​p✅​p❌​F
❌​TestAccept/bundle/resources/apps/lifecycle-started-toggle/DATABRICKS_BUNDLE_ENGINE=direct❌​F🔄​f✅​p✅​p✅​p❌​F
❌​TestAccept/bundle/resources/catalogs/basic❌​F🔄​f✅​p✅​p❌​F❌​F
❌​TestAccept/bundle/resources/catalogs/basic/DATABRICKS_BUNDLE_ENGINE=direct❌​F🔄​f✅​p✅​p❌​F❌​F
❌​TestAccept/bundle/resources/catalogs/with-schemas❌​F❌​F✅​p✅​p❌​F❌​F
❌​TestAccept/bundle/resources/catalogs/with-schemas/DATABRICKS_BUNDLE_ENGINE=direct❌​F❌​F✅​p✅​p❌​F❌​F
❌​TestAccept/bundle/resources/clusters/lifecycle-started✅​p✅​p✅​p❌​F✅​p✅​p
❌​TestAccept/bundle/resources/clusters/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct✅​p✅​p✅​p❌​F✅​p✅​p
❌​TestAccept/bundle/resources/clusters/resize-terminated-fallback✅​p❌​F✅​p✅​p✅​p✅​p
❌​TestAccept/bundle/resources/clusters/resize-terminated-fallback/DATABRICKS_BUNDLE_ENGINE=direct✅​p❌​F✅​p✅​p✅​p✅​p
🔄​TestAccept/bundle/resources/dashboards/change-embed-credentials✅​p✅​p✅​p🔄​f✅​p✅​p
🔄​TestAccept/bundle/resources/dashboards/change-embed-credentials/DATABRICKS_BUNDLE_ENGINE=direct✅​p✅​p✅​p🔄​f✅​p✅​p
❌​TestAccept/bundle/resources/dashboards/change-name❌​F✅​p🔄​f🔄​f✅​p✅​p
🔄​TestAccept/bundle/resources/dashboards/change-name/DATABRICKS_BUNDLE_ENGINE=direct✅​p✅​p✅​p🔄​f✅​p✅​p
❌​TestAccept/bundle/resources/dashboards/change-name/DATABRICKS_BUNDLE_ENGINE=terraform❌​F✅​p🔄​f✅​p✅​p✅​p
❌​TestAccept/bundle/resources/dashboards/change-serialized-dashboard❌​F✅​p✅​p✅​p✅​p✅​p
❌​TestAccept/bundle/resources/dashboards/change-serialized-dashboard/DATABRICKS_BUNDLE_ENGINE=direct❌​F✅​p✅​p✅​p✅​p✅​p
❌​TestAccept/bundle/resources/dashboards/dataset-catalog-schema❌​F✅​p✅​p✅​p✅​p❌​F
❌​TestAccept/bundle/resources/dashboards/dataset-catalog-schema/DATABRICKS_BUNDLE_ENGINE=terraform❌​F✅​p✅​p✅​p✅​p❌​F
❌​TestAccept/bundle/resources/grants/catalogs✅​p❌​F✅​p✅​p❌​F❌​F
❌​TestAccept/bundle/resources/grants/catalogs/DATABRICKS_BUNDLE_ENGINE=direct✅​p❌​F✅​p✅​p❌​F❌​F
❌​TestAccept/bundle/resources/grants/schemas/change_privilege❌​F❌​F✅​p✅​p❌​F❌​F
❌​TestAccept/bundle/resources/grants/schemas/change_privilege/DATABRICKS_BUNDLE_ENGINE=direct❌​F❌​F✅​p✅​p❌​F❌​F
❌​TestAccept/bundle/resources/grants/schemas/duplicate_principals❌​F❌​F✅​p✅​p❌​F❌​F
❌​TestAccept/bundle/resources/grants/schemas/duplicate_principals/DATABRICKS_BUNDLE_ENGINE=direct❌​F❌​F✅​p✅​p❌​F❌​F
❌​TestAccept/bundle/resources/grants/schemas/out_of_band_principal❌​F❌​F✅​p✅​p❌​F❌​F
❌​TestAccept/bundle/resources/grants/schemas/out_of_band_principal/DATABRICKS_BUNDLE_ENGINE=direct❌​F❌​F✅​p✅​p❌​F❌​F
❌​TestAccept/bundle/resources/grants/schemas/out_of_band_principal/DATABRICKS_BUNDLE_ENGINE=terraform✅​p✅​p✅​p✅​p✅​p❌​F
❌​TestAccept/bundle/resources/grants/volumes❌​F✅​p✅​p✅​p❌​F❌​F
❌​TestAccept/bundle/resources/grants/volumes/DATABRICKS_BUNDLE_ENGINE=direct❌​F✅​p✅​p✅​p❌​F❌​F
❌​TestAccept/bundle/resources/pipelines/update✅​p✅​p✅​p✅​p❌​F✅​p
❌​TestAccept/bundle/resources/pipelines/update/DATABRICKS_BUNDLE_ENGINE=direct✅​p✅​p✅​p✅​p❌​F✅​p
❌​TestAccept/bundle/resources/secret_scopes/basic✅​p✅​p✅​p🔄​f❌​F✅​p
❌​TestAccept/bundle/resources/secret_scopes/basic/DATABRICKS_BUNDLE_ENGINE=direct✅​p✅​p✅​p✅​p❌​F✅​p
🔄​TestAccept/bundle/resources/secret_scopes/basic/DATABRICKS_BUNDLE_ENGINE=terraform✅​p✅​p✅​p🔄​f✅​p✅​p
💚​TestAccept/bundle/resources/vector_search_endpoints/drift/recreated_same_name💚​R💚​R💚​R💚​R💚​R💚​R
🙈​TestAccept/bundle/resources/vector_search_indexes/recreate/embedding_dimension🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S
❌​TestAccept/bundle/resources/volumes/uppercase-name✅​p❌​F✅​p✅​p❌​F❌​F
❌​TestAccept/bundle/resources/volumes/uppercase-name/DATABRICKS_BUNDLE_ENGINE=direct✅​p❌​F✅​p✅​p❌​F❌​F
❌​TestAccept/bundle/templates/default-python/combinations/classic✅​p✅​p✅​p✅​p❌​F✅​p
❌​TestAccept/bundle/templates/default-python/combinations/classic/DATABRICKS_BUNDLE_ENGINE=direct/DLT=no/NBOOK=yes/PY=no/READPLAN=✅​p✅​p✅​p✅​p❌​F✅​p
🙈​TestAccept/ssh/connection🙈​S🙈​S🙈​S🙈​S🙈​S🙈​S
🟨​TestFetchRepositoryInfoAPI_FromRepo💚​R💚​R💚​R💚​R🟨​K🟨​K
🟨​TestFetchRepositoryInfoAPI_FromRepo/root💚​R💚​R💚​R💚​R🟨​K🟨​K
🟨​TestFetchRepositoryInfoAPI_FromRepo/subdir💚​R💚​R💚​R💚​R🟨​K🟨​K
Top 50 slowest tests (at least 2 minutes):
durationenvtestname
27:23aws windowsTestAccept/bundle/resources/clusters/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct
24:43aws windowsTestAccept/bundle/resources/clusters/lifecycle-started-toggle/DATABRICKS_BUNDLE_ENGINE=direct
15:35gcp windowsTestAccept/bundle/resources/apps/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct
14:49aws windowsTestAccept/bundle/resources/apps/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct
13:54aws linuxTestAccept/bundle/resources/apps/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct
13:46gcp linuxTestAccept/bundle/resources/apps/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct
13:42aws linuxTestAccept/bundle/resources/clusters/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct
13:01aws windowsTestAccept/bundle/resources/clusters/deploy/data_security_mode/DATABRICKS_BUNDLE_ENGINE=direct
12:45gcp windowsTestAccept/bundle/resources/clusters/deploy/local_ssd_count/DATABRICKS_BUNDLE_ENGINE=direct
12:31azure windowsTestAccept/bundle/resources/apps/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct
9:40gcp windowsTestAccept/bundle/resources/clusters/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct
9:33azure linuxTestAccept/bundle/resources/apps/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct
9:13azure linuxTestAccept/bundle/resources/clusters/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct
9:08gcp linuxTestAccept/bundle/resources/clusters/lifecycle-started-toggle/DATABRICKS_BUNDLE_ENGINE=direct
9:01aws windowsTestAccept/bundle/resources/clusters/deploy/update-after-create/DATABRICKS_BUNDLE_ENGINE=direct
8:58aws windowsTestAccept/bundle/resources/clusters/deploy/update-after-create/DATABRICKS_BUNDLE_ENGINE=terraform
8:47azure linuxTestAccept/bundle/config-remote-sync/multiple_resources/DATABRICKS_BUNDLE_ENGINE=terraform
8:30azure windowsTestAccept/bundle/resources/registered_models/basic/DATABRICKS_BUNDLE_ENGINE=terraform
8:17aws linuxTestAccept/bundle/deploy/spark-jar-task/DATABRICKS_BUNDLE_ENGINE=terraform
8:05gcp linuxTestAccept/bundle/resources/models/basic/DATABRICKS_BUNDLE_ENGINE=terraform
8:04gcp linuxTestAccept/bundle/resources/apps/inline_config/DATABRICKS_BUNDLE_ENGINE=direct
8:00gcp linuxTestAccept/bundle/resources/clusters/lifecycle-started/DATABRICKS_BUNDLE_ENGINE=direct
7:46aws windowsTestAccept/bundle/resources/apps/lifecycle-started-toggle/DATABRICKS_BUNDLE_ENGINE=direct
7:28gcp linuxTestAccept/bundle/resources/clusters/deploy/simple/DATABRICKS_BUNDLE_ENGINE=direct
7:24gcp linuxTestAccept/bundle/resources/registered_models/basic/DATABRICKS_BUNDLE_ENGINE=direct
7:19aws linuxTestAccept/bundle/apps/job_permissions/DATABRICKS_BUNDLE_ENGINE=direct
7:17aws windowsTestAccept/bundle/templates/default-python/combinations/classic/DATABRICKS_BUNDLE_ENGINE=direct/DLT=yes/NBOOK=no/PY=no/READPLAN=1
7:14aws windowsTestAccept/bundle/deploy/spark-jar-task/DATABRICKS_BUNDLE_ENGINE=direct
7:10gcp linuxTestAccept/bundle/templates/default-python/combinations/serverless/DATABRICKS_BUNDLE_ENGINE=terraform/DLT=no/NBOOK=yes/PY=yes/READPLAN=
7:06gcp linuxTestAccept/bundle/resources/clusters/deploy/local_ssd_count/DATABRICKS_BUNDLE_ENGINE=direct
6:43aws windowsTestAccept/bundle/resources/apps/lifecycle-started-omitted/DATABRICKS_BUNDLE_ENGINE=direct
6:32azure windowsTestAccept/bundle/resources/registered_models/basic/DATABRICKS_BUNDLE_ENGINE=direct
6:30azure windowsTestAccept/bundle/resources/apps/lifecycle-started-omitted/DATABRICKS_BUNDLE_ENGINE=direct
6:18gcp windowsTestAccept/bundle/resources/clusters/lifecycle-started-toggle/DATABRICKS_BUNDLE_ENGINE=direct
6:16azure windowsTestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=genie_space.yml.tmpl/READPLAN=
6:14azure linuxTestAccept/bundle/deploy/spark-jar-task/DATABRICKS_BUNDLE_ENGINE=direct
6:12aws windowsTestAccept/bundle/templates/default-python/combinations/classic/DATABRICKS_BUNDLE_ENGINE=direct/DLT=no/NBOOK=no/PY=yes/READPLAN=1
6:12gcp linuxTestAccept/bundle/resources/models/basic/DATABRICKS_BUNDLE_ENGINE=direct
6:12gcp linuxTestAccept/bundle/resources/model_serving_endpoints/basic/DATABRICKS_BUNDLE_ENGINE=terraform
6:09azure linuxTestAccept/bundle/apps/job_permissions/DATABRICKS_BUNDLE_ENGINE=direct
6:07aws linuxTestAccept/bundle/invariant/continue_293/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=job_pydabs_10_tasks.yml.tmpl
6:07gcp linuxTestAccept/bundle/deploy/spark-jar-task/DATABRICKS_BUNDLE_ENGINE=terraform
6:05aws windowsTestAccept/bundle/templates/default-python/combinations/classic/DATABRICKS_BUNDLE_ENGINE=terraform/DLT=yes/NBOOK=yes/PY=yes/READPLAN=
6:04gcp linuxTestAccept/bundle/templates/default-python/combinations/classic/DATABRICKS_BUNDLE_ENGINE=direct/DLT=yes/NBOOK=no/PY=no/READPLAN=
6:04azure windowsTestAccept/bundle/templates/default-python/combinations/classic/DATABRICKS_BUNDLE_ENGINE=terraform/DLT=yes/NBOOK=yes/PY=no/READPLAN=
6:02azure windowsTestAccept/bundle/deployment/bind/dashboard/recreation/DATABRICKS_BUNDLE_ENGINE=direct
6:02gcp windowsTestAccept/bundle/invariant/no_drift/DATABRICKS_BUNDLE_ENGINE=direct/INPUT_CONFIG=cluster_apply_policy_default_values.yml.tmpl/READPLAN=
6:02gcp linuxTestAccept/bundle/templates/default-python/combinations/serverless/DATABRICKS_BUNDLE_ENGINE=direct/DLT=no/NBOOK=no/PY=yes/READPLAN=1
6:00gcp linuxTestAccept/bundle/templates/default-python/combinations/classic/DATABRICKS_BUNDLE_ENGINE=direct/DLT=no/NBOOK=no/PY=yes/READPLAN=
5:55aws linuxTestAccept/bundle/config-remote-sync/multiple_resources/DATABRICKS_BUNDLE_ENGINE=terraform

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@radakam@eng-dev-ecosystem-bot@pietern@andrewnester