Skip to content

feat(wfctl): validate project config#672

Merged
intel352 merged 1 commit into
mainfrom
fix/wfctl-config-validate
May 14, 2026
Merged

feat(wfctl): validate project config#672
intel352 merged 1 commit into
mainfrom
fix/wfctl-config-validate

Conversation

@intel352
Copy link
Copy Markdown
Contributor

Summary

  • add wfctl config validate for wfctl.yaml and .wfctl-lock.yaml
  • make wfctl validate reject canonical wfctl manifests with guidance to the project-config validator
  • keep subprocess infra E2E skipped when the local DigitalOcean IaC plugin fixture is unavailable

Verification

  • GOWORK=off go test ./cmd/wfctl -count=1
  • GOWORK=off go test ./config -count=1
  • GOWORK=off go run ./cmd/wfctl config validate --manifest /Users/jon/workspace/workflow-compute/wfctl.yaml --lock-file /Users/jon/workspace/workflow-compute/.wfctl-lock.yaml
  • GOWORK=off go run ./cmd/wfctl validate /Users/jon/workspace/workflow-compute/wfctl.yaml rejects with wfctl config validate guidance

Context

Addresses the workflow-compute deferred gap where wfctl validate treated wfctl.yaml as a runtime Workflow config instead of wfctl project configuration.

Copilot AI review requested due to automatic review settings May 14, 2026 18:26
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a new wfctl config validate subcommand that validates the human-edited wfctl.yaml project manifest and the generated .wfctl-lock.yaml lockfile, and teaches wfctl validate (runtime workflow config validator) to detect and reject canonical wfctl project manifests with guidance to use the new subcommand. Also makes the infra multi-env E2E test skip cleanly when the DigitalOcean IaC plugin is not installed for the subprocess wfctl.

Changes:

  • New config_validate.go implements wfctl config validate with --manifest, --lock-file, and --skip-lock flags; manifest validates required fields and detects duplicates, lockfile validates URLs and SHA-256s.
  • validate.go/migrate.go/wfctl.yaml: wire the new subcommand into the embedded CLI dispatch, add --manifest/--lock-file to the flag reorderer, refactor migrateDeprecationWriter into a default var, and make runValidate short-circuit with guidance when a likely wfctl project manifest is passed.
  • Tests cover dispatch wiring, acceptance/rejection of project vs. runtime configs, and a regression for buf.gen.yaml-style false positives; infra E2E now skips on missing DO plugin.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
cmd/wfctl/config_validate.go New subcommand implementing manifest + lockfile validation.
cmd/wfctl/validate.go Rejects wfctl manifests with guidance, adds indentErrorMessage helper and new flag names to reorderer.
cmd/wfctl/migrate.go Adds validate to config subcommand dispatch and refactors deprecation writer default.
cmd/wfctl/wfctl.yaml Registers config CLI command and cmd-config pipeline in the embedded CLI manifest.
cmd/wfctl/config_migrate_test.go Adds tests for embedded wiring, accept/reject behavior, and updated writer default check.
cmd/wfctl/infra_e2e_test.go Skips subprocess infra E2E when DO IaC plugin is unavailable.
docs/WFCTL.md Documents the new wfctl config validate subcommand and cross-references from wfctl validate.

Comment thread cmd/wfctl/validate.go
Comment on lines +121 to +128
func indentErrorMessage(message string) string {
lines := strings.Split(message, "\n")
if len(lines) == 0 {
return message
}
return strings.TrimSpace(lines[len(lines)-1])
}

Comment thread docs/WFCTL.md
Comment on lines +440 to +441
Use `wfctl config validate` for `wfctl.yaml` and `.wfctl-lock.yaml`; this
command validates runtime Workflow configs such as `workflow.yaml`.
Comment on lines +93 to +94
}
seen[name] = struct{}{}
@codecov
Copy link
Copy Markdown

codecov Bot commented May 14, 2026

Codecov Report

❌ Patch coverage is 73.52941% with 36 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
cmd/wfctl/config_validate.go 72.95% 20 Missing and 13 partials ⚠️
cmd/wfctl/validate.go 80.00% 1 Missing and 1 partial ⚠️
cmd/wfctl/migrate.go 75.00% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 14, 2026

⏱ Benchmark Results

No significant performance regressions detected.

benchstat comparison (baseline → PR)
## benchstat: baseline → PR
baseline-bench.txt:276: parsing iteration count: invalid syntax
baseline-bench.txt:276565: parsing iteration count: invalid syntax
baseline-bench.txt:576800: parsing iteration count: invalid syntax
baseline-bench.txt:889596: parsing iteration count: invalid syntax
baseline-bench.txt:1237114: parsing iteration count: invalid syntax
baseline-bench.txt:1539878: parsing iteration count: invalid syntax
benchmark-results.txt:276: parsing iteration count: invalid syntax
benchmark-results.txt:304285: parsing iteration count: invalid syntax
benchmark-results.txt:563651: parsing iteration count: invalid syntax
benchmark-results.txt:867885: parsing iteration count: invalid syntax
benchmark-results.txt:1176760: parsing iteration count: invalid syntax
benchmark-results.txt:1473161: parsing iteration count: invalid syntax
goos: linux
goarch: amd64
pkg: github.com/GoCodeAlone/workflow/dynamic
cpu: AMD EPYC 9V74 80-Core Processor                
                            │ baseline-bench.txt │        benchmark-results.txt        │
                            │       sec/op       │    sec/op      vs base              │
InterpreterCreation-4               5.486m ± 88%   4.416m ± 120%       ~ (p=0.394 n=6)
ComponentLoad-4                     3.592m ±  1%   3.484m ±   0%  -3.01% (p=0.002 n=6)
ComponentExecute-4                  1.856µ ±  1%   1.827µ ±   1%  -1.54% (p=0.002 n=6)
PoolContention/workers-1-4          1.037µ ±  2%   1.010µ ±   1%  -2.60% (p=0.002 n=6)
PoolContention/workers-2-4          1.046µ ±  4%   1.006µ ±   1%  -3.87% (p=0.002 n=6)
PoolContention/workers-4-4          1.033µ ±  2%   1.004µ ±   0%  -2.71% (p=0.002 n=6)
PoolContention/workers-8-4          1.027µ ±  1%   1.008µ ±   1%  -1.85% (p=0.009 n=6)
PoolContention/workers-16-4         1.038µ ±  1%   1.012µ ±   2%  -2.51% (p=0.004 n=6)
ComponentLifecycle-4                3.661m ±  2%   3.533m ±   2%  -3.49% (p=0.002 n=6)
SourceValidation-4                  2.106µ ±  1%   2.146µ ±   0%  +1.90% (p=0.002 n=6)
RegistryConcurrent-4                744.4n ±  6%   784.5n ±   4%  +5.39% (p=0.026 n=6)
LoaderLoadFromString-4              3.697m ±  2%   3.557m ±   0%  -3.77% (p=0.002 n=6)
geomean                             17.67µ         17.09µ         -3.30%

                            │ baseline-bench.txt │        benchmark-results.txt         │
                            │        B/op        │     B/op      vs base                │
InterpreterCreation-4               2.027Mi ± 0%   2.027Mi ± 0%       ~ (p=0.812 n=6)
ComponentLoad-4                     2.180Mi ± 0%   2.180Mi ± 0%       ~ (p=0.853 n=6)
ComponentExecute-4                  1.203Ki ± 0%   1.203Ki ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-1-4          1.203Ki ± 0%   1.203Ki ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-2-4          1.203Ki ± 0%   1.203Ki ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-4-4          1.203Ki ± 0%   1.203Ki ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-8-4          1.203Ki ± 0%   1.203Ki ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-16-4         1.203Ki ± 0%   1.203Ki ± 0%       ~ (p=1.000 n=6) ¹
ComponentLifecycle-4                2.183Mi ± 0%   2.183Mi ± 0%  +0.00% (p=0.030 n=6)
SourceValidation-4                  1.984Ki ± 0%   1.984Ki ± 0%       ~ (p=1.000 n=6) ¹
RegistryConcurrent-4                1.133Ki ± 0%   1.133Ki ± 0%       ~ (p=1.000 n=6) ¹
LoaderLoadFromString-4              2.182Mi ± 0%   2.182Mi ± 0%       ~ (p=0.290 n=6)
geomean                             15.25Ki        15.25Ki       -0.00%
¹ all samples are equal

                            │ baseline-bench.txt │        benchmark-results.txt        │
                            │     allocs/op      │  allocs/op   vs base                │
InterpreterCreation-4                15.68k ± 0%   15.68k ± 0%       ~ (p=1.000 n=6)
ComponentLoad-4                      18.02k ± 0%   18.02k ± 0%       ~ (p=1.000 n=6)
ComponentExecute-4                    25.00 ± 0%    25.00 ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-1-4            25.00 ± 0%    25.00 ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-2-4            25.00 ± 0%    25.00 ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-4-4            25.00 ± 0%    25.00 ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-8-4            25.00 ± 0%    25.00 ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-16-4           25.00 ± 0%    25.00 ± 0%       ~ (p=1.000 n=6) ¹
ComponentLifecycle-4                 18.07k ± 0%   18.07k ± 0%       ~ (p=1.000 n=6) ¹
SourceValidation-4                    32.00 ± 0%    32.00 ± 0%       ~ (p=1.000 n=6) ¹
RegistryConcurrent-4                  2.000 ± 0%    2.000 ± 0%       ~ (p=1.000 n=6) ¹
LoaderLoadFromString-4               18.06k ± 0%   18.06k ± 0%       ~ (p=1.000 n=6) ¹
geomean                               183.3         183.3       +0.00%
¹ all samples are equal

pkg: github.com/GoCodeAlone/workflow/middleware
                                  │ baseline-bench.txt │       benchmark-results.txt       │
                                  │       sec/op       │   sec/op     vs base              │
CircuitBreakerDetection-4                 301.3n ± 16%   296.0n ± 5%       ~ (p=0.143 n=6)
CircuitBreakerExecution_Success-4         22.67n ±  0%   22.68n ± 0%       ~ (p=0.139 n=6)
CircuitBreakerExecution_Failure-4         70.98n ±  0%   70.99n ± 0%       ~ (p=0.450 n=6)
geomean                                   78.56n         78.11n       -0.57%

                                  │ baseline-bench.txt │       benchmark-results.txt        │
                                  │        B/op        │    B/op     vs base                │
CircuitBreakerDetection-4                 144.0 ± 0%     144.0 ± 0%       ~ (p=1.000 n=6) ¹
CircuitBreakerExecution_Success-4         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
CircuitBreakerExecution_Failure-4         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                                              ²               +0.00%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

                                  │ baseline-bench.txt │       benchmark-results.txt        │
                                  │     allocs/op      │ allocs/op   vs base                │
CircuitBreakerDetection-4                 1.000 ± 0%     1.000 ± 0%       ~ (p=1.000 n=6) ¹
CircuitBreakerExecution_Success-4         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
CircuitBreakerExecution_Failure-4         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                                              ²               +0.00%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

pkg: github.com/GoCodeAlone/workflow/module
                                 │ baseline-bench.txt │        benchmark-results.txt         │
                                 │       sec/op       │    sec/op      vs base               │
IaCStateBackend_InProcess-4              294.1n ± 15%    287.1n ±  2%   -2.41% (p=0.026 n=6)
IaCStateBackend_GRPC-4                   9.894m ± 11%   10.047m ± 16%        ~ (p=0.937 n=6)
JQTransform_Simple-4                     723.0n ± 39%    655.0n ± 27%        ~ (p=0.093 n=6)
JQTransform_ObjectConstruction-4         1.619µ ±  2%    1.417µ ±  1%  -12.42% (p=0.002 n=6)
JQTransform_ArraySelect-4                3.741µ ±  2%    3.391µ ±  1%   -9.34% (p=0.002 n=6)
JQTransform_Complex-4                    43.39µ ±  1%    40.77µ ±  3%   -6.04% (p=0.002 n=6)
JQTransform_Throughput-4                 1.983µ ±  2%    1.738µ ±  1%  -12.31% (p=0.002 n=6)
SSEPublishDelivery-4                     63.23n ±  1%    63.14n ±  1%        ~ (p=0.699 n=6)
geomean                                  4.028µ          3.768µ         -6.45%

                                 │ baseline-bench.txt │         benchmark-results.txt         │
                                 │        B/op        │     B/op       vs base                │
IaCStateBackend_InProcess-4              416.0 ± 0%       416.0 ±  0%       ~ (p=1.000 n=6) ¹
IaCStateBackend_GRPC-4                 5.722Mi ± 8%     5.785Mi ± 14%       ~ (p=0.699 n=6)
JQTransform_Simple-4                   1.273Ki ± 0%     1.273Ki ±  0%       ~ (p=1.000 n=6) ¹
JQTransform_ObjectConstruction-4       1.773Ki ± 0%     1.773Ki ±  0%       ~ (p=1.000 n=6) ¹
JQTransform_ArraySelect-4              2.625Ki ± 0%     2.625Ki ±  0%       ~ (p=1.000 n=6) ¹
JQTransform_Complex-4                  16.22Ki ± 0%     16.22Ki ±  0%       ~ (p=1.000 n=6) ¹
JQTransform_Throughput-4               1.984Ki ± 0%     1.984Ki ±  0%       ~ (p=1.000 n=6) ¹
SSEPublishDelivery-4                     0.000 ± 0%       0.000 ±  0%       ~ (p=1.000 n=6) ¹
geomean                                             ²                  +0.14%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

                                 │ baseline-bench.txt │        benchmark-results.txt        │
                                 │     allocs/op      │  allocs/op   vs base                │
IaCStateBackend_InProcess-4              2.000 ± 0%      2.000 ± 0%       ~ (p=1.000 n=6) ¹
IaCStateBackend_GRPC-4                  6.869k ± 0%     6.857k ± 0%       ~ (p=0.058 n=6)
JQTransform_Simple-4                     10.00 ± 0%      10.00 ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_ObjectConstruction-4         15.00 ± 0%      15.00 ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_ArraySelect-4                30.00 ± 0%      30.00 ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_Complex-4                    324.0 ± 0%      324.0 ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_Throughput-4                 17.00 ± 0%      17.00 ± 0%       ~ (p=1.000 n=6) ¹
SSEPublishDelivery-4                     0.000 ± 0%      0.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                                             ²                -0.02%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

pkg: github.com/GoCodeAlone/workflow/schema
                                    │ baseline-bench.txt │       benchmark-results.txt        │
                                    │       sec/op       │    sec/op     vs base              │
SchemaValidation_Simple-4                    1.093µ ± 3%   1.080µ ± 17%       ~ (p=0.329 n=6)
SchemaValidation_AllFields-4                 1.636µ ± 6%   1.619µ ±  6%       ~ (p=0.667 n=6)
SchemaValidation_FormatValidation-4          1.573µ ± 1%   1.571µ ±  6%       ~ (p=0.732 n=6)
SchemaValidation_ManySchemas-4               1.581µ ± 3%   1.593µ ±  4%       ~ (p=0.145 n=6)
geomean                                      1.452µ        1.446µ        -0.41%

                                    │ baseline-bench.txt │       benchmark-results.txt        │
                                    │        B/op        │    B/op     vs base                │
SchemaValidation_Simple-4                   0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
SchemaValidation_AllFields-4                0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
SchemaValidation_FormatValidation-4         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
SchemaValidation_ManySchemas-4              0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                                                ²               +0.00%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

                                    │ baseline-bench.txt │       benchmark-results.txt        │
                                    │     allocs/op      │ allocs/op   vs base                │
SchemaValidation_Simple-4                   0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
SchemaValidation_AllFields-4                0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
SchemaValidation_FormatValidation-4         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
SchemaValidation_ManySchemas-4              0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                                                ²               +0.00%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

pkg: github.com/GoCodeAlone/workflow/store
                                   │ baseline-bench.txt │       benchmark-results.txt        │
                                   │       sec/op       │    sec/op     vs base              │
EventStoreAppend_InMemory-4                1.053µ ± 16%   1.046µ ± 11%       ~ (p=0.589 n=6)
EventStoreAppend_SQLite-4                  1.087m ±  4%   1.066m ±  4%       ~ (p=0.093 n=6)
GetTimeline_InMemory/events-10-4           13.13µ ±  2%   12.62µ ±  3%  -3.90% (p=0.002 n=6)
GetTimeline_InMemory/events-50-4           64.86µ ± 16%   55.26µ ± 20%       ~ (p=0.065 n=6)
GetTimeline_InMemory/events-100-4          113.5µ ±  0%   110.6µ ±  1%  -2.53% (p=0.002 n=6)
GetTimeline_InMemory/events-500-4          584.0µ ±  1%   563.0µ ±  3%  -3.59% (p=0.002 n=6)
GetTimeline_InMemory/events-1000-4         1.189m ±  2%   1.193m ±  7%       ~ (p=0.937 n=6)
GetTimeline_SQLite/events-10-4             85.26µ ±  0%   84.65µ ±  2%       ~ (p=0.485 n=6)
GetTimeline_SQLite/events-50-4             223.6µ ±  3%   223.3µ ±  3%       ~ (p=0.240 n=6)
GetTimeline_SQLite/events-100-4            391.5µ ±  1%   384.3µ ±  2%  -1.83% (p=0.009 n=6)
GetTimeline_SQLite/events-500-4            1.702m ±  1%   1.666m ±  1%  -2.11% (p=0.002 n=6)
GetTimeline_SQLite/events-1000-4           3.358m ±  1%   3.288m ±  1%  -2.10% (p=0.002 n=6)
geomean                                    196.3µ         190.6µ        -2.91%

                                   │ baseline-bench.txt │        benchmark-results.txt         │
                                   │        B/op        │     B/op      vs base                │
EventStoreAppend_InMemory-4                  785.0 ± 9%     801.5 ± 8%       ~ (p=1.000 n=6)
EventStoreAppend_SQLite-4                  1.984Ki ± 2%   1.983Ki ± 2%       ~ (p=0.732 n=6)
GetTimeline_InMemory/events-10-4           7.953Ki ± 0%   7.953Ki ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-50-4           46.62Ki ± 0%   46.62Ki ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-100-4          94.48Ki ± 0%   94.48Ki ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-500-4          472.8Ki ± 0%   472.8Ki ± 0%       ~ (p=0.061 n=6)
GetTimeline_InMemory/events-1000-4         944.3Ki ± 0%   944.3Ki ± 0%  +0.00% (p=0.032 n=6)
GetTimeline_SQLite/events-10-4             16.74Ki ± 0%   16.74Ki ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-50-4             87.14Ki ± 0%   87.14Ki ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-100-4            175.4Ki ± 0%   175.4Ki ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-500-4            846.1Ki ± 0%   846.1Ki ± 0%  -0.00% (p=0.022 n=6)
GetTimeline_SQLite/events-1000-4           1.639Mi ± 0%   1.639Mi ± 0%       ~ (p=0.167 n=6)
geomean                                    67.31Ki        67.42Ki       +0.17%
¹ all samples are equal

                                   │ baseline-bench.txt │        benchmark-results.txt        │
                                   │     allocs/op      │  allocs/op   vs base                │
EventStoreAppend_InMemory-4                  7.000 ± 0%    7.000 ± 0%       ~ (p=1.000 n=6) ¹
EventStoreAppend_SQLite-4                    53.00 ± 0%    53.00 ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-10-4             125.0 ± 0%    125.0 ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-50-4             653.0 ± 0%    653.0 ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-100-4           1.306k ± 0%   1.306k ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-500-4           6.514k ± 0%   6.514k ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-1000-4          13.02k ± 0%   13.02k ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-10-4               382.0 ± 0%    382.0 ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-50-4              1.852k ± 0%   1.852k ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-100-4             3.681k ± 0%   3.681k ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-500-4             18.54k ± 0%   18.54k ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-1000-4            37.29k ± 0%   37.29k ± 0%       ~ (p=1.000 n=6) ¹
geomean                                     1.162k        1.162k       +0.00%
¹ all samples are equal

Benchmarks run with go test -bench=. -benchmem -count=6.
Regressions ≥ 20% are flagged. Results compared via benchstat.

@intel352 intel352 force-pushed the fix/wfctl-config-validate branch from 1ac91b4 to 8f3493d Compare May 14, 2026 18:48
@intel352 intel352 merged commit 3baf7b6 into main May 14, 2026
24 checks passed
@intel352 intel352 deleted the fix/wfctl-config-validate branch May 14, 2026 19:01
Sign up for free to 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.

2 participants