You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat: add bidirectionalLabelMatch option and deprecate exactMatch (#5031)
## Description
Introduce a new `bidirectionalLabelMatch` option that performs strict
two-way label matching (runner labels must equal workflow labels as a
set). This preserves the existing `exactMatch` behavior (unidirectional
subset check) to avoid breaking changes.
The `bidirectionalLabelMatch` option requires labels to be identical in
both directions. Previously, a runner with labels `[A, B, C, D]` would
match a job requesting `[A, B, C]` when `exactMatch` was `true`. With
`bidirectionalLabelMatch=true`, the runner will only match if the job
requests exactly `[A, B, C, D]`.
```
Before: Job [A,B,C] + Runner [A,B,C,D] + exactMatch=true → Match
After: Job [A,B,C] + Runner [A,B,C,D] + bidirectionalLabelMatch=true → No Match
```
`exactMatch` was supposed to have this behavior, but to avoid breaking
changes, the variable will be deprecated to give users time to migrate.
**Changes:**
- Add `bidirectionalLabelMatch` to `MatcherConfig` interface (optional,
defaults to `false`)
- Update `canRunJob` to support bidirectional matching when enabled —
now accepts both `bidirectionalLabelMatch` and `enableDynamicLabels`
parameters; bidirectional matching correctly respects dynamic label
sanitization
- Deprecate `exactMatch` in Terraform variables with migration guidance
- Add `bidirectionalLabelMatch` to multi-runner and webhook variable
types
- Add new root variable `enable_runner_bidirectional_label_match`
- Add comprehensive test coverage for bidirectional matching
**Migration:** To migrate, use `bidirectionalLabelMatch` instead of
`exactMatch` in your runner configs. Then either:
1. Remove extra labels from runner configurations, or
2. Add the extra labels to your workflow job `runs-on`
Co-authored-by: Stuart Pearson
## Test Plan
- Added/updated unit tests in `dispatch.test.ts` covering bidirectional
label matching, interaction with `exactMatch`, case-insensitivity, empty
labels, and combined use with `enableDynamicLabels` — 36 tests passing
## Related Issues
---------
Signed-off-by: Brend Smits <brend.smits@philips.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Copy file name to clipboardExpand all lines: README.md
+2-1Lines changed: 2 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -128,10 +128,11 @@ Join our discord community via [this invite link](https://discord.gg/bxgXW8jJGh)
128
128
| <aname="input_enable_job_queued_check"></a> [enable\_job\_queued\_check](#input\_enable\_job\_queued\_check)| Only scale if the job event received by the scale up lambda is in the queued state. By default enabled for non ephemeral runners and disabled for ephemeral. Set this variable to overwrite the default behavior. |`bool`|`null`| no |
129
129
| <aname="input_enable_managed_runner_security_group"></a> [enable\_managed\_runner\_security\_group](#input\_enable\_managed\_runner\_security\_group)| Enables creation of the default managed security group. Unmanaged security groups can be specified via `runner_additional_security_group_ids`. |`bool`|`true`| no |
130
130
| <aname="input_enable_organization_runners"></a> [enable\_organization\_runners](#input\_enable\_organization\_runners)| Register runners to organization, instead of repo level |`bool`|`false`| no |
131
+
| <aname="input_enable_runner_bidirectional_label_match"></a> [enable\_runner\_bidirectional\_label\_match](#input\_enable\_runner\_bidirectional\_label\_match)| If set to true, the runner labels and workflow job labels must be an exact two-way match (same set, any order, no extras or missing labels). This is stricter than `enable_runner_workflow_job_labels_check_all` which only checks that workflow labels are a subset of runner labels. When false, if __any__ label matches it will trigger the webhook. |`bool`|`false`| no |
131
132
| <aname="input_enable_runner_binaries_syncer"></a> [enable\_runner\_binaries\_syncer](#input\_enable\_runner\_binaries\_syncer)| Option to disable the lambda to sync GitHub runner distribution, useful when using a pre-build AMI. |`bool`|`true`| no |
132
133
| <aname="input_enable_runner_detailed_monitoring"></a> [enable\_runner\_detailed\_monitoring](#input\_enable\_runner\_detailed\_monitoring)| Should detailed monitoring be enabled for the runner. Set this to true if you want to use detailed monitoring. See https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-cloudwatch-new.html for details. |`bool`|`false`| no |
133
134
| <aname="input_enable_runner_on_demand_failover_for_errors"></a> [enable\_runner\_on\_demand\_failover\_for\_errors](#input\_enable\_runner\_on\_demand\_failover\_for\_errors)| Enable on-demand failover. For example to fall back to on demand when no spot capacity is available the variable can be set to `InsufficientInstanceCapacity`. When not defined the default behavior is to retry later. |`list(string)`|`[]`| no |
134
-
| <aname="input_enable_runner_workflow_job_labels_check_all"></a> [enable\_runner\_workflow\_job\_labels\_check\_all](#input\_enable\_runner\_workflow\_job\_labels\_check\_all)| If set to true all labels in the workflow job must match the GitHub labels (os, architecture and `self-hosted`). When false if __any__ label matches it will trigger the webhook. |`bool`|`true`| no |
135
+
| <aname="input_enable_runner_workflow_job_labels_check_all"></a> [enable\_runner\_workflow\_job\_labels\_check\_all](#input\_enable\_runner\_workflow\_job\_labels\_check\_all)|DEPRECATED: Use `enable_runner_bidirectional_label_match` instead. If set to true all labels in the workflow job must match the GitHub labels (os, architecture and `self-hosted`). When false if __any__ label matches it will trigger the webhook. Note: this only checks that workflow labels are a subset of runner labels, not the reverse. |`bool`|`true`| no |
135
136
| <aname="input_enable_ssm_on_runners"></a> [enable\_ssm\_on\_runners](#input\_enable\_ssm\_on\_runners)| Enable to allow access to the runner instances for debugging purposes via SSM. Note that this adds additional permissions to the runner instances. |`bool`|`false`| no |
136
137
| <aname="input_enable_user_data_debug_logging_runner"></a> [enable\_user\_data\_debug\_logging\_runner](#input\_enable\_user\_data\_debug\_logging\_runner)| Option to enable debug logging for user-data, this logs all secrets as well. |`bool`|`false`| no |
137
138
| <aname="input_enable_userdata"></a> [enable\_userdata](#input\_enable\_userdata)| Should the userdata script be enabled for the runner. Set this to false if you are using your own prebuilt AMI. |`bool`|`true`| no |
'Failed to load config: Failed to load parameter for matcherConfig from path /path/to/matcher/config: Failed to load matcher config',// eslint-disable-line max-len
168
+
'Failed to load config: Failed to load parameter for matcherConfig from path /path/to/matcher/config: Failed to load matcher config',
'Failed to load config: Environment variable for eventBusName is not set and no default value provided., Failed to load parameter for webhookSecret from path undefined: Parameter undefined not found',// eslint-disable-line max-len
259
+
'Failed to load config: Environment variable for eventBusName is not set and no default value provided., Failed to load parameter for webhookSecret from path undefined: Parameter undefined not found',
Copy file name to clipboardExpand all lines: lambdas/functions/webhook/src/ConfigLoader.ts
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -61,7 +61,7 @@ abstract class BaseConfig {
61
61
this.loadProperty(propertyName,value);
62
62
})
63
63
.catch((error)=>{
64
-
consterrorMessage=`Failed to load parameter for ${String(propertyName)} from path ${paramPath}: ${(errorasError).message}`;// eslint-disable-line max-len
64
+
consterrorMessage=`Failed to load parameter for ${String(propertyName)} from path ${paramPath}: ${(errorasError).message}`;
labelMatchers: "The list of list of labels supported by the runner configuration. `[[self-hosted, linux, x64, example]]`"
279
-
exactMatch: "If set to true all labels in the workflow job must match the GitHub labels (os, architecture and `self-hosted`). When false if __any__ workflow label matches it will trigger the webhook."
280
+
exactMatch: "DEPRECATED: Use `bidirectionalLabelMatch` instead. If set to true all labels in the workflow job must match the GitHub labels (os, architecture and `self-hosted`). When false if __any__ workflow label matches it will trigger the webhook. Note: this only checks that workflow labels are a subset of runner labels, not the reverse."
281
+
bidirectionalLabelMatch: "If set to true, the runner labels and workflow job labels must be an exact two-way match (same set, any order, no extras or missing labels). This is stricter than `exactMatch` which only checks that workflow labels are a subset of runner labels. When false, if __any__ workflow label matches it will trigger the webhook."
280
282
priority: "If set it defines the priority of the matcher, the matcher with the lowest priority will be evaluated first. Default is 999, allowed values 0-999."
281
283
enableDynamicLabels: "Experimental! When true the dispatcher allows `ghr-*` dynamic labels for jobs routed to this runner. Default false."
282
284
ec2DynamicLabelsPolicy: "Optional policy for `ghr-ec2-*` labels evaluated by the dispatcher. Only effective when `enableDynamicLabels = true`. Jobs whose EC2 dynamic labels violate every matching runner's policy are rejected with a 202 (a warning is logged). Evaluation: keys in `blocked_keys` are always rejected; keys in `restricted_keys` are allowed only when their value passes the rule; unlisted keys are allowed. Schema: `{ blocked_keys = [<key>], restricted_keys = { <key> = { allowed = [globs], denied = [globs], max = number|string } } }`. Keys use the dynamic label suffix, e.g. `instance-type` for `ghr-ec2-instance-type`."
0 commit comments