feat: add declarative cross-module script ordering via coder_script_order#27160
Draft
SasSwart wants to merge 1 commit into
Draft
feat: add declarative cross-module script ordering via coder_script_order#27160SasSwart wants to merge 1 commit into
SasSwart wants to merge 1 commit into
Conversation
…rder
Introduce a coder_script_order resource that lets templates declare ordering
dependencies between coder_script resources across modules. Each rule states
that the scripts in `run` must wait for the scripts in `after` to reach a
lifecycle state ("completes" -> completed, "starts" -> started).
The Terraform provider resource is added separately in
coder/terraform-provider-coder. This change wires the dependencies end to end:
- provisionersdk/agent protos carry ScriptDependency ({resource_address,
required_status}) on scripts.
- The Terraform state converter reads coder_script_order rules and records
dependencies on the referenced run scripts, keyed by resource address.
- provisionerdserver persists dependencies as a jsonb column on
workspace_agent_scripts (migration 000544); the agent manifest exposes them.
- The agent's script runner registers each script as a sync unit, adds the
declared ordering edges, and gates execution: a script blocks until its
dependencies reach the required status, with a fail-open timeout so a stuck
dependency cannot hang workspace startup.
The unit.Manager gains WaitUntilReady for broadcast-based readiness waiting.
Generated by Coder Agents on behalf of @SasSwart.
Docs preview📖 View docs preview for |
This was referenced Jul 10, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
Adds a
coder_script_orderresource that lets templates declare ordering dependencies betweencoder_scriptresources across modules, and enforces them in the agent so a script waits for its declared predecessors before running. The ordering is also recorded in the unit graph so it shows up incoder exp sync timeline.Target HCL:
A rule means: every script in
runwaits for every script inafterto reachstate("completes"->completed,"starts"->started; defaultcompletes). Multiplecoder_script_orderblocks are additive.This is the new tip of the sync-units stack (#27149 → #27150 → #27152 → #27153 → #27154 → this).
How it works (end to end)
ScriptDependency {resource_address, required_status}added toprovisionersdkScriptand to the agentWorkspaceAgentScript.provisioner/terraform/resources.go): a new pass overcoder_script_orderresources resolves each rule'srun/aftercoder_script.<name>.idreferences to the scripts' Terraformresource_addressand records dependencies on the referenced run scripts. Unknown references and invalidstatevalues are rejected with a clear error.jsonbcolumn onworkspace_agent_scripts(migration000544). The agent consumes them by resource address, which avoids a UUID join table and insert-order resolution.agent/agentscripts): each script is registered as a sync unit, the declared ordering edges are added, andrun()gates execution by waiting until the script's unit is ready.unit.ManagergainsWaitUntilReady(broadcast-based) for this.Design notes
"starts"state matches the dependency's status exactly. If a dependency advancesstarted→completedbefore the dependent re-checks, a"starts"dependency can be momentarily unsatisfied; the fail-open timeout mitigates this."completes"is the default and common case.db2sdk.go'sWorkspaceAgentScriptwas intentionally left unchanged. The agent manifest is the only consumer of this field; it is not part of the REST workspace-agent representation.started, briefly making dependents "not ready". Acceptable for startup ordering.Cross-repo dependency
The provisioner keys off the
coder_script_ordertype name in Terraform state, so parsing is developed and tested here againsttfjson/inlineConvertStatefixtures. End-to-end CI that runs real Terraform needs the resource in the pinned provider, so full green depends on the companion terraform-provider-coder PR being released and a provider version bump. Kept as a draft until then.Tests
agent/unit:WaitUntilReady(ready, blocks-then-unblocks, ctx cancel, unregistered).agent/agentscripts: edges added from manifest, unmet dependency waits then unblocks, timeout fail-open.provisioner/terraform:coder_script_order→Dependencies(completes/starts/invalid/unknown reference).coderd/provisionerdserver+coderd/agentapi+codersdk/agentsdk: round-trip of dependencies through DB, manifest, and proto conversion.Implementation plan
Plan: declarative cross-module script ordering (
coder_script_order)Express dependencies between
coder_scriptresources in Terraform and enforce them in the agent, so scripts wait for their declared predecessors before running and the ordering is visible incoder exp sync timeline.Decisions (confirmed)
coder_script_order(not a data source).coder_script.<name>.id(Terraform-validated), resolved by Coder's provisioner to each script'sresource_address(the unit name).Semantics
rundepends on every script inafterreachingstate. Edge direction inunit.Manager:AddDependency(run, after, requiredStatus)(run depends on after).statemapping:"completes"->unit.StatusComplete,"starts"->unit.StatusStarted. Default"completes".resource_address(e.g.module.code-server.coder_script.code-server), already plumbed on the current stack.PR 1 - terraform-provider-coder
Config-only managed resource, same pattern as
coder_script/coder_env:scriptOrderResource()with a repeatableruleblock (run,after,statewith defaultcompletesand StringInSlice validation), registered inResourcesMap, plus example and unit tests,make fmt/make gen.PR 2 - coder/coder (this PR)
coder_script_orderresolving run/after ids to resource addresses and appendingproto.ScriptDependencyto run scripts.ScriptDependency/WorkspaceAgentScriptDependencymessages +dependenciesfields.jsonbdependenciescolumn (migration 000544); insert/select carry it.WaitUntilReadybroadcast wait primitive.Init(), gate execution inrun()with a bounded fail-open wait.Risks / notes
started, briefly making dependents "not ready"; acceptable for startup ordering.Generated by Coder Agents on behalf of @SasSwart.