-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP] Generic provider template #1140
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Direction & progress looks good. It would probably be worth writing down a design for the required makefile targets and artifacts while doing this work - perhaps in a README somewhere in this repo - which can serve as a design doc too.
- name: Download schema-embed.json | ||
uses: #{{ .Config.ActionVersions.DownloadArtifact }}# | ||
with: | ||
# Use a pattern to avoid failing if the artifact doesn't exist | ||
pattern: schema-embed.* | ||
# Avoid creating directories for each artifact | ||
merge-multiple: true | ||
path: provider/cmd/pulumi-resource-#{{ .Config.Provider }}#/schema-embed.json |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not all providers use schema-embed right now. It's only realy a performance optimisation which could be implemented internally within the provider rather than needing CI to have insight of.
We mostly still have the original schema commited (though this has been taken out Azure Native due to the file being too big for GitHub, and LFS causing a load of other problems) but I think it would be more correct to treat the schema like a build artifact as you're doing here, though it would be nicer to not assume the Go provider directory structure if possible within the CI job. I think this could be abstracted by the makefile if needed.
- Prerequisites writes all artifacts to the bin directory including the embeddable schema if it needs it.
- Restore the bin directory in this subsequent job.
- Within the provider_dist target, copy the embeddable schema into the provider directory before building.
merge-multiple: true | ||
path: provider/cmd/pulumi-resource-#{{ .Config.Provider }}#/schema-embed.json | ||
- name: Build & package provider | ||
run: make provider_dist-${{ matrix.platform.os }}-${{ matrix.platform.arch }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps we should use the file target here to match the path we're going to upload rather than having the assumption of the path this phony target will write to:
make dist/pulumi-resource-#{{ .Config.Provider }}#-v${{ inputs.version }}-${{ matrix.platform.os }}-${{ matrix.platform.arch }}.tar.gz
- name: Install plugins | ||
run: make install_plugins |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a bit of an odd step. I know for TF providers it's related to installing other bridged TF providers which the bridge will use for examples generation, but for a generic template we might want something a little more generic such as make prepare
or something that allways runs at the start of the job before restoring any targets or doing make --touch ...
etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I was also wondering about this because the CLI should automatically download these plugins anyway. Related - these plugins eat a ton of space! pulumi/pulumi#17718
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think for bridged providers, if they're opted into using the converter plugin, then it explicitly disables auto-download because we need to have the provider version pinned, so failing fast is good. For generic providers, perhaps we can just let the provider figure out what it needs and how it will install them internally within the makefile.
# otherwise use the current SHA for any other type of build. | ||
sha: ${{ github.event.pull_request.head.sha || github.sha }} | ||
|
||
# TODO: Extract into shared action. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
@@ -0,0 +1,48 @@ | |||
# WARNING: This file is autogenerated - changes will be overwritten if not made via https://github.com/pulumi/ci-mgmt | |||
|
|||
name: license_check |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should already be included from the provider
template .. unless there's something subtle we're tweaking here I didn't spot?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yeah, I duplicated it here because of #1133
case "generic": | ||
return []string{"provider", "pulumi-provider", "generic"}, nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When we use this template for the native boilerplate, we'll probably add external-generic
which will exclude the pulumi-provider
sub-template.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or maybe "third-party"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just above is the external-bridged-provider
template which is like bridged-provider
but with bits removed for third parties. Whatever name we use should aim to keep these consistent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Love the design in the README. That's super helpful 💜
Sharding is interesting, but doesn't feel it's quite there yet.
Relying on phony targets vs files is worth a quick think, but the phony targets work fine if in doubt.
* `make install_plugins`: (TODO: Use a more generic `make prepare` or just drop | ||
this.) | ||
* `make schema`: Ensures generated schema is in place. | ||
* `make provider`: Builds the provider binary. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* `make provider`: Builds the provider binary. | |
* `make provider`: Builds the provider binary for the purpose of local testing. The final distributable binary is built using `make provider_dist-*`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could also be a file target, though slightly more tricky because the name of the binary changes per provider, so perhaps just documenting it's in the bin directory is enough.
|
||
* `make install_plugins`: (TODO: Use a more generic `make prepare` or just drop | ||
this.) | ||
* `make schema`: Ensures generated schema is in place. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be a file target of bin/schema.json
which can then be expected to be in place and included as a publishable artifact along with the provider binaries for reference (and perhaps integration with the registry in the future). This could still also output the schema to any other required locations as needed.
* `make shard`: This target takes two environment variables -- `$SHARD_TOTAL` | ||
and `$SHARD_INDEX` -- and is responsible for determining tests to run for | ||
this shard. It will probably mutate the environment in some way, for example | ||
by appending to `$GITHUB_ENV`, in order to inform the `test_shard` target. | ||
* `make test_shard`: This target is responsible for executing tests identified | ||
in the `shard` target. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a little confused why we have two targets here. It feels like we shouldn't need make shard
at all .. and we don't want to have to tell the provider author to know how to interact with github env.
Perhaps we should be just using make test
or make integration_test
with variables for SHARD_TOTAL
and SHARD_INDEX
e.g. make integration_test SHARD_TOTAL=5 SHARD_INDEX=3
.
It would also be nice to link from here to an example of how to do sharding with go test
.
Done a bit more experimenting around the test sharding and am pretty sure we can do this with a single target with optional make variables. Here's how we can adapt our current bridge makefile to support sharding (or runing specific tests locally):
Using make -n test TEST_RUN="Things"
cd examples && go test -v -tags=all -parallel 10 -timeout 2h -run "Things"
make -n test_provider TEST_RUN="Things"
cd provider && go test -v -short ./... -parallel 10 -run "Things"
make -n test TEST_SHARD_INDEX=2 TEST_SHARD_TOTAL=5
cd examples && go test -v -tags=all -parallel 10 -timeout 2h -run "$(go run github.com/blampe/shard@9d1f3b21786e18caa1989e19502595143985d61b --total "5" --index "2" --output env)"
make -n test_provider TEST_SHARD_INDEX=2 TEST_SHARD_TOTAL=5
cd provider && go test -v -short ./... -parallel 10 -run "$(go run github.com/blampe/shard@9d1f3b21786e18caa1989e19502595143985d61b --total "5" --index "2" --output env)" |
Next thoughts on the sharding ... I think we should roll it out as a smallish change to bridged providers first to solidify the design.
|
This onboards the provider to new workflows consistent with pulumi/ci-mgmt#1140. This doesn't change anything with regard to the release process, but it does bring the provider up-to-speed with current best practices and it will make it easier to automatically manage with `ci-mgmt` in the future. Notable changes: * Java publishing * Embedding versioning (`respectSchemaVersion`) * Sharded tests * Goreleaser replaced by `pulumi/pulumi-package-publisher`
This is a very WIP fork of our bridged workflows which is intended to be used by native, component, or other miscellaneous providers not currently managed by ci-mgmt.
There are two primary design principles which deviate from the bridged template:
make
targets define the entire contract between a provider andci-mgmt
. We do not assume anything about the provider, e.g. it could be implemented in a language other than Go.ci-mgmt
is responsible for exposing the appropriate hooks (Allowmake
target customization #1131).For example, if the provider needs some additional tooling then it is responsible for ensuring the tool is installed. Historically these sorts of customizations have been handled as one-offs in
ci-mgmt
, but we want to push this down to themake
target or into the test itself. Not only does this makeci-mgmt
easier to maintain and refactor, but it also forces us to write tests that are more easily reproducible in local environments. The SSH key handling between the docker and docker-build providers is illustrative.I've been testing this in EKS and haven't gotten tests passing reliably yet. I was planning on consolidating the test into a shared action once I got that far, but also feel free to do that sooner than later!
EKS was already sharding tests so I've opted to keep that behavior here -- a provider just needs to implement a
test_shard
target which takes aTESTS
andTAG
env var. I've tweaked it somewhat so the sharding is totally arbitrary, which in practice just means we need to install all the SDKs instead of one at a time.Other differences:
TODO: