diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 57faf626..eb521f88 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -38,6 +38,14 @@ jobs: run: | go build -v . + - name: Run integration test (devel) + timeout-minutes: 10 + env: + CODER_IMAGE: "ghcr.io/coder/coder-preview" + CODER_VERSION: "latest" + run: | + go test -v ./integration + - name: Run integration test (mainline) timeout-minutes: 10 env: @@ -54,6 +62,14 @@ jobs: source <(go run ./scripts/coderversion) CODER_VERSION="${CODER_STABLE_VERSION}" go test -v ./integration + - name: Run integration test (oldstable) + timeout-minutes: 10 + env: + CODER_IMAGE: "ghcr.io/coder/coder" + run: | + source <(go run ./scripts/coderversion) + CODER_VERSION="${CODER_OLDSTABLE_VERSION}" go test -v ./integration + # run acceptance tests in a matrix with Terraform core versions test: name: Matrix Test diff --git a/README.md b/README.md index 2bceb73a..6f13efef 100644 --- a/README.md +++ b/README.md @@ -70,10 +70,10 @@ To run these integration tests locally: 1. Pull the version of the Coder image you wish to test: ```console - docker pull ghcr.io/coder/coder:main-x.y.z-devel-abcd1234 + docker pull ghcr.io/coder/coder-preview:main-x.y.z-devel-abcd1234 ``` -1. Run `CODER_VERSION=main-x.y.z-devel-abcd1234 make test-integration`. +1. Run `CODER_IMAGE=ghcr.io/coder/coder-preview CODER_VERSION=main-x.y.z-devel-abcd1234 make test-integration`. > **Note:** you can specify `CODER_IMAGE` if the Coder image you wish to test is hosted somewhere other than `ghcr.io/coder/coder`. > For example, `CODER_IMAGE=example.com/repo/coder CODER_VERSION=foobar make test-integration`. diff --git a/integration/integration_test.go b/integration/integration_test.go index dc3d5c98..f1596eee 100644 --- a/integration/integration_test.go +++ b/integration/integration_test.go @@ -115,6 +115,34 @@ func TestIntegration(t *testing.T) { "workspace_owner.login_type": ``, }, }, + { + name: "workspace-owner-filled", + minVersion: "v2.18.0", + expectedOutput: map[string]string{ + "provisioner.arch": runtime.GOARCH, + "provisioner.id": `[a-zA-Z0-9-]+`, + "provisioner.os": runtime.GOOS, + "workspace.access_port": `\d+`, + "workspace.access_url": `https?://\D+:\d+`, + "workspace.id": `[a-zA-z0-9-]+`, + "workspace.name": ``, + "workspace.start_count": `1`, + "workspace.template_id": `[a-zA-Z0-9-]+`, + "workspace.template_name": `workspace-owner`, + "workspace.template_version": `.+`, + "workspace.transition": `start`, + "workspace_owner.email": `testing@coder\.com`, + "workspace_owner.full_name": `default`, + "workspace_owner.groups": `\[(\"Everyone\")?\]`, + "workspace_owner.id": `[a-zA-Z0-9-]+`, + "workspace_owner.name": `testing`, + "workspace_owner.oidc_access_token": `^$`, // TODO: test OIDC integration + "workspace_owner.session_token": `.+`, + "workspace_owner.ssh_private_key": `(?s)^.+?BEGIN OPENSSH PRIVATE KEY.+?END OPENSSH PRIVATE KEY.+?$`, + "workspace_owner.ssh_public_key": `(?s)^ssh-ed25519.+$`, + "workspace_owner.login_type": `password`, + }, + }, { name: "coder-app-hidden", minVersion: "v0.0.0", diff --git a/integration/workspace-owner-filled/main.tf b/integration/workspace-owner-filled/main.tf new file mode 100644 index 00000000..fd923a3d --- /dev/null +++ b/integration/workspace-owner-filled/main.tf @@ -0,0 +1,58 @@ +terraform { + required_providers { + coder = { + source = "coder/coder" + } + local = { + source = "hashicorp/local" + } + } +} + +// TODO: test coder_external_auth +// data coder_external_auth "me" {} +data "coder_provisioner" "me" {} +data "coder_workspace" "me" {} +data "coder_workspace_owner" "me" {} + +locals { + # NOTE: these must all be strings in the output + output = { + "provisioner.arch" : data.coder_provisioner.me.arch, + "provisioner.id" : data.coder_provisioner.me.id, + "provisioner.os" : data.coder_provisioner.me.os, + "workspace.access_port" : tostring(data.coder_workspace.me.access_port), + "workspace.access_url" : data.coder_workspace.me.access_url, + "workspace.id" : data.coder_workspace.me.id, + "workspace.name" : data.coder_workspace.me.name, + "workspace.start_count" : tostring(data.coder_workspace.me.start_count), + "workspace.template_id" : data.coder_workspace.me.template_id, + "workspace.template_name" : data.coder_workspace.me.template_name, + "workspace.template_version" : data.coder_workspace.me.template_version, + "workspace.transition" : data.coder_workspace.me.transition, + "workspace_owner.email" : data.coder_workspace_owner.me.email, + "workspace_owner.full_name" : data.coder_workspace_owner.me.full_name, + "workspace_owner.groups" : jsonencode(data.coder_workspace_owner.me.groups), + "workspace_owner.id" : data.coder_workspace_owner.me.id, + "workspace_owner.name" : data.coder_workspace_owner.me.name, + "workspace_owner.oidc_access_token" : data.coder_workspace_owner.me.oidc_access_token, + "workspace_owner.session_token" : data.coder_workspace_owner.me.session_token, + "workspace_owner.ssh_private_key" : data.coder_workspace_owner.me.ssh_private_key, + "workspace_owner.ssh_public_key" : data.coder_workspace_owner.me.ssh_public_key, + "workspace_owner.login_type" : data.coder_workspace_owner.me.login_type, + } +} + +variable "output_path" { + type = string +} + +resource "local_file" "output" { + filename = var.output_path + content = jsonencode(local.output) +} + +output "output" { + value = local.output + sensitive = true +} diff --git a/scripts/coderversion/main.go b/scripts/coderversion/main.go index b6f57d4b..9b5f4c06 100644 --- a/scripts/coderversion/main.go +++ b/scripts/coderversion/main.go @@ -64,6 +64,38 @@ func main() { stable := fmt.Sprintf("v%d.%d.%d", stableVer.Major(), stableVer.Minor(), stableVer.Patch()) _, _ = fmt.Fprintf(os.Stdout, "CODER_STABLE_VERSION=%q\n", stable) + + expectedOldStableMinor := mainlineVer.Minor() - 2 + if expectedOldStableMinor < 0 { + expectedOldStableMinor = 0 + } + debug("expected old stable minor: %d\n", expectedStableMinor) + oldStableVer := semver.MustParse("v0.0.0") + for _, rel := range releases { + debug("check version %s\n", rel) + if rel == "" { + debug("ignoring untagged version %s\n", rel) + continue + } + + ver, err := semver.NewVersion(rel) + if err != nil { + debug("skipping invalid version %s\n", rel) + } + + if ver.Minor() != expectedOldStableMinor { + debug("skipping version %s\n", rel) + continue + } + + if ver.Compare(oldStableVer) > 0 { + oldStableVer = ver + continue + } + } + + oldStable := fmt.Sprintf("v%d.%d.%d", oldStableVer.Major(), oldStableVer.Minor(), oldStableVer.Patch()) + _, _ = fmt.Fprintf(os.Stdout, "CODER_OLDSTABLE_VERSION=%q\n", oldStable) } type release struct {