From 6f69f942cf29a6d26fd244d0d624d067b4bd1d76 Mon Sep 17 00:00:00 2001 From: Mihaela Balutoiu Date: Wed, 26 Jul 2023 19:41:21 +0300 Subject: [PATCH 1/6] Add GitHub workflow for integration tests Signed-off-by: Mihaela Balutoiu --- .github/workflows/integration-tests.yml | 51 ++ test/integration/config/config.toml | 59 ++ test/integration/e2e.go | 1056 +++++++++++++++++++++++ test/integration/scripts/setup-garm.sh | 64 ++ 4 files changed, 1230 insertions(+) create mode 100644 .github/workflows/integration-tests.yml create mode 100644 test/integration/config/config.toml create mode 100644 test/integration/e2e.go create mode 100755 test/integration/scripts/setup-garm.sh diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml new file mode 100644 index 00000000..b52389f1 --- /dev/null +++ b/.github/workflows/integration-tests.yml @@ -0,0 +1,51 @@ +name: Integration Tests +on: + push: + branches: + - main + pull_request: + branches: + - main + +jobs: + integration-tests: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Setup Golang + uses: actions/setup-go@v3 + with: + go-version-file: go.mod + + - name: Setup LXD + uses: canonical/setup-lxd@v0.1.1 + + - name: Build GARM + run: make build + + - name: Setup GARM + run: sudo --preserve-env ./test/integration/scripts/setup-garm.sh + env: + GH_OAUTH_TOKEN: ${{ secrets.GH_OAUTH_TOKEN }} + CREDENTIALS_NAME: test-garm-creds + + - name: Run integration tests + run: go run ./test/integration/e2e.go + env: + GARM_BASE_URL: http://127.0.0.1:9997 + GARM_USERNAME: admin + GARM_PASSWORD: ${{ secrets.GARM_ADMIN_PASSWORD }} + GARM_FULLNAME: Local GARM Admin + GARM_EMAIL: admin@example.com + GARM_NAME: local_garm + CREDENTIALS_NAME: test-garm-creds + REPO_WEBHOOK_SECRET: ${{ secrets.REPO_WEBHOOK_SECRET }} + ORG_WEBHOOK_SECRET: ${{ secrets.ORG_WEBHOOK_SECRET }} + + - name: Show GARM logs + if: always() + run: | + sudo systemctl status garm + sudo journalctl -u garm --no-pager diff --git a/test/integration/config/config.toml b/test/integration/config/config.toml new file mode 100644 index 00000000..29388c11 --- /dev/null +++ b/test/integration/config/config.toml @@ -0,0 +1,59 @@ +[default] +callback_url = "http://${GARM_METADATA_IP}:9997/api/v1/callbacks/status" +metadata_url = "http://${GARM_METADATA_IP}:9997/api/v1/metadata" + +[metrics] +enable = true +disable_auth = false + +[jwt_auth] +secret = "${JWT_AUTH_SECRET}" +time_to_live = "8760h" + +[apiserver] +bind = "0.0.0.0" +port = 9997 +use_tls = false + +[database] +backend = "sqlite3" +passphrase = "${DB_PASSPHRASE}" +[database.sqlite3] + db_file = "/etc/garm/garm.db" + +[[provider]] +name = "lxd_local" +provider_type = "lxd" +description = "Local LXD installation" +[provider.lxd] + unix_socket_path = "/var/snap/lxd/common/lxd/unix.socket" + include_default_profile = false + instance_type = "container" + secure_boot = false + project_name = "default" + [provider.lxd.image_remotes] + [provider.lxd.image_remotes.ubuntu] + addr = "https://cloud-images.ubuntu.com/releases" + public = true + protocol = "simplestreams" + skip_verify = false + [provider.lxd.image_remotes.ubuntu_daily] + addr = "https://cloud-images.ubuntu.com/daily" + public = true + protocol = "simplestreams" + skip_verify = false + [provider.lxd.image_remotes.images] + addr = "https://images.linuxcontainers.org" + public = true + protocol = "simplestreams" + skip_verify = false + +[[github]] +name = "${CREDENTIALS_NAME}" +description = "GARM GitHub OAuth token" +oauth2_token = "${GH_OAUTH_TOKEN}" + +[[github]] +name = "${CREDENTIALS_NAME}-clone" +description = "GARM GitHub OAuth token - clone" +oauth2_token = "${GH_OAUTH_TOKEN}" diff --git a/test/integration/e2e.go b/test/integration/e2e.go new file mode 100644 index 00000000..51553aca --- /dev/null +++ b/test/integration/e2e.go @@ -0,0 +1,1056 @@ +package main + +import ( + "encoding/json" + "fmt" + "log" + "net/url" + "os" + "time" + + commonParams "github.com/cloudbase/garm-provider-common/params" + client "github.com/cloudbase/garm/client" + clientCredentials "github.com/cloudbase/garm/client/credentials" + clientFirstRun "github.com/cloudbase/garm/client/first_run" + clientInstances "github.com/cloudbase/garm/client/instances" + clientJobs "github.com/cloudbase/garm/client/jobs" + clientLogin "github.com/cloudbase/garm/client/login" + clientMetricsToken "github.com/cloudbase/garm/client/metrics_token" + clientOrganizations "github.com/cloudbase/garm/client/organizations" + clientPools "github.com/cloudbase/garm/client/pools" + clientProviders "github.com/cloudbase/garm/client/providers" + clientRepositories "github.com/cloudbase/garm/client/repositories" + "github.com/cloudbase/garm/cmd/garm-cli/config" + "github.com/cloudbase/garm/params" + "github.com/go-openapi/runtime" + openapiRuntimeClient "github.com/go-openapi/runtime/client" +) + +const ( + orgName = "gsamfira" + repoName = "scripts" +) + +var ( + cli *client.GarmAPI + cfg config.Config + authToken runtime.ClientAuthInfoWriter + + credentialsName = os.Getenv("CREDENTIALS_NAME") + + repoID string + repoPoolID string + repoInstanceName string + repoWebhookSecret = os.Getenv("REPO_WEBHOOK_SECRET") + + orgID string + orgPoolID string + orgInstanceName string + orgWebhookSecret = os.Getenv("ORG_WEBHOOK_SECRET") + + username = os.Getenv("GARM_USERNAME") + password = os.Getenv("GARM_PASSWORD") + fullName = os.Getenv("GARM_FULLNAME") + email = os.Getenv("GARM_EMAIL") + name = os.Getenv("GARM_NAME") + baseURL = os.Getenv("GARM_BASE_URL") + + poolID string +) + +// //////////////// // +// helper functions // +// /////////////////// +func handleError(err error) { + if err != nil { + log.Fatalf("error encountered: %v", err) + } +} + +func printResponse(resp interface{}) { + b, err := json.MarshalIndent(resp, "", " ") + handleError(err) + log.Println(string(b)) +} + +// /////////// +// Garm Init / +// /////////// +func firstRun(apiCli *client.GarmAPI, newUser params.NewUserParams) (params.User, error) { + firstRunResponse, err := apiCli.FirstRun.FirstRun( + clientFirstRun.NewFirstRunParams().WithBody(newUser), + authToken) + if err != nil { + return params.User{}, err + } + return firstRunResponse.Payload, nil +} + +func login(apiCli *client.GarmAPI, params params.PasswordLoginParams) (string, error) { + loginResponse, err := apiCli.Login.Login( + clientLogin.NewLoginParams().WithBody(params), + authToken) + if err != nil { + return "", err + } + return loginResponse.Payload.Token, nil +} + +// //////////////////////////// +// Credentials and Providers // +// //////////////////////////// +func listCredentials(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter) (params.Credentials, error) { + listCredentialsResponse, err := apiCli.Credentials.ListCredentials( + clientCredentials.NewListCredentialsParams(), + apiAuthToken) + if err != nil { + return nil, err + } + return listCredentialsResponse.Payload, nil +} + +func listProviders(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter) (params.Providers, error) { + listProvidersResponse, err := apiCli.Providers.ListProviders( + clientProviders.NewListProvidersParams(), + apiAuthToken) + if err != nil { + return nil, err + } + return listProvidersResponse.Payload, nil +} + +// //////// +// Jobs // +// //////// +func listJobs(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter) (params.Jobs, error) { + listJobsResponse, err := apiCli.Jobs.ListJobs( + clientJobs.NewListJobsParams(), + apiAuthToken) + if err != nil { + return nil, err + } + return listJobsResponse.Payload, nil +} + +// ////////////////// +// / Metrics Token // +// ////////////////// +func getMetricsToken(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter) (string, error) { + getMetricsTokenResponse, err := apiCli.MetricsToken.GetMetricsToken( + clientMetricsToken.NewGetMetricsTokenParams(), + apiAuthToken) + if err != nil { + return "", err + } + return getMetricsTokenResponse.Payload.Token, nil +} + +// /////////////// +// Repositories // +// /////////////// +func createRepo(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, repoParams params.CreateRepoParams) (*params.Repository, error) { + createRepoResponse, err := apiCli.Repositories.CreateRepo( + clientRepositories.NewCreateRepoParams().WithBody(repoParams), + apiAuthToken) + if err != nil { + return nil, err + } + return &createRepoResponse.Payload, nil +} + +func listRepos(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter) (params.Repositories, error) { + listReposResponse, err := apiCli.Repositories.ListRepos( + clientRepositories.NewListReposParams(), + apiAuthToken) + if err != nil { + return nil, err + } + return listReposResponse.Payload, nil +} + +func updateRepo(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, repoID string, repoParams params.UpdateEntityParams) (*params.Repository, error) { + updateRepoResponse, err := apiCli.Repositories.UpdateRepo( + clientRepositories.NewUpdateRepoParams().WithRepoID(repoID).WithBody(repoParams), + apiAuthToken) + if err != nil { + return nil, err + } + return &updateRepoResponse.Payload, nil +} + +func getRepo(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, repoID string) (*params.Repository, error) { + getRepoResponse, err := apiCli.Repositories.GetRepo( + clientRepositories.NewGetRepoParams().WithRepoID(repoID), + apiAuthToken) + if err != nil { + return nil, err + } + return &getRepoResponse.Payload, nil +} + +func createRepoPool(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, repoID string, poolParams params.CreatePoolParams) (*params.Pool, error) { + createRepoPoolResponse, err := apiCli.Repositories.CreateRepoPool( + clientRepositories.NewCreateRepoPoolParams().WithRepoID(repoID).WithBody(poolParams), + apiAuthToken) + if err != nil { + return nil, err + } + return &createRepoPoolResponse.Payload, nil +} + +func listRepoPools(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, repoID string) (params.Pools, error) { + listRepoPoolsResponse, err := apiCli.Repositories.ListRepoPools( + clientRepositories.NewListRepoPoolsParams().WithRepoID(repoID), + apiAuthToken) + if err != nil { + return nil, err + } + return listRepoPoolsResponse.Payload, nil +} + +func getRepoPool(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, repoID, poolID string) (*params.Pool, error) { + getRepoPoolResponse, err := apiCli.Repositories.GetRepoPool( + clientRepositories.NewGetRepoPoolParams().WithRepoID(repoID).WithPoolID(poolID), + apiAuthToken) + if err != nil { + return nil, err + } + return &getRepoPoolResponse.Payload, nil +} + +func updateRepoPool(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, repoID, poolID string, poolParams params.UpdatePoolParams) (*params.Pool, error) { + updateRepoPoolResponse, err := apiCli.Repositories.UpdateRepoPool( + clientRepositories.NewUpdateRepoPoolParams().WithRepoID(repoID).WithPoolID(poolID).WithBody(poolParams), + apiAuthToken) + if err != nil { + return nil, err + } + return &updateRepoPoolResponse.Payload, nil +} + +func listRepoInstances(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, repoID string) (params.Instances, error) { + listRepoInstancesResponse, err := apiCli.Repositories.ListRepoInstances( + clientRepositories.NewListRepoInstancesParams().WithRepoID(repoID), + apiAuthToken) + if err != nil { + return nil, err + } + return listRepoInstancesResponse.Payload, nil +} + +func deleteRepo(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, repoID string) error { + return apiCli.Repositories.DeleteRepo( + clientRepositories.NewDeleteRepoParams().WithRepoID(repoID), + apiAuthToken) +} + +func deleteRepoPool(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, repoID, poolID string) error { + return apiCli.Repositories.DeleteRepoPool( + clientRepositories.NewDeleteRepoPoolParams().WithRepoID(repoID).WithPoolID(poolID), + apiAuthToken) +} + +// //////////////// +// Organizations // +// //////////////// +func createOrg(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, orgParams params.CreateOrgParams) (*params.Organization, error) { + createOrgResponse, err := apiCli.Organizations.CreateOrg( + clientOrganizations.NewCreateOrgParams().WithBody(orgParams), + apiAuthToken) + if err != nil { + return nil, err + } + return &createOrgResponse.Payload, nil +} + +func listOrgs(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter) (params.Organizations, error) { + listOrgsResponse, err := apiCli.Organizations.ListOrgs( + clientOrganizations.NewListOrgsParams(), + apiAuthToken) + if err != nil { + return nil, err + } + return listOrgsResponse.Payload, nil +} + +func updateOrg(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, orgID string, orgParams params.UpdateEntityParams) (*params.Organization, error) { + updateOrgResponse, err := apiCli.Organizations.UpdateOrg( + clientOrganizations.NewUpdateOrgParams().WithOrgID(orgID).WithBody(orgParams), + apiAuthToken) + if err != nil { + return nil, err + } + return &updateOrgResponse.Payload, nil +} + +func getOrg(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, orgID string) (*params.Organization, error) { + getOrgResponse, err := apiCli.Organizations.GetOrg( + clientOrganizations.NewGetOrgParams().WithOrgID(orgID), + apiAuthToken) + if err != nil { + return nil, err + } + return &getOrgResponse.Payload, nil +} + +func createOrgPool(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, orgID string, poolParams params.CreatePoolParams) (*params.Pool, error) { + createOrgPoolResponse, err := apiCli.Organizations.CreateOrgPool( + clientOrganizations.NewCreateOrgPoolParams().WithOrgID(orgID).WithBody(poolParams), + apiAuthToken) + if err != nil { + return nil, err + } + return &createOrgPoolResponse.Payload, nil +} + +func listOrgPools(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, orgID string) (params.Pools, error) { + listOrgPoolsResponse, err := apiCli.Organizations.ListOrgPools( + clientOrganizations.NewListOrgPoolsParams().WithOrgID(orgID), + apiAuthToken) + if err != nil { + return nil, err + } + return listOrgPoolsResponse.Payload, nil +} + +func getOrgPool(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, orgID, poolID string) (*params.Pool, error) { + getOrgPoolResponse, err := apiCli.Organizations.GetOrgPool( + clientOrganizations.NewGetOrgPoolParams().WithOrgID(orgID).WithPoolID(poolID), + apiAuthToken) + if err != nil { + return nil, err + } + return &getOrgPoolResponse.Payload, nil +} + +func updateOrgPool(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, orgID, poolID string, poolParams params.UpdatePoolParams) (*params.Pool, error) { + updateOrgPoolResponse, err := apiCli.Organizations.UpdateOrgPool( + clientOrganizations.NewUpdateOrgPoolParams().WithOrgID(orgID).WithPoolID(poolID).WithBody(poolParams), + apiAuthToken) + if err != nil { + return nil, err + } + return &updateOrgPoolResponse.Payload, nil +} + +func listOrgInstances(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, orgID string) (params.Instances, error) { + listOrgInstancesResponse, err := apiCli.Organizations.ListOrgInstances( + clientOrganizations.NewListOrgInstancesParams().WithOrgID(orgID), + apiAuthToken) + if err != nil { + return nil, err + } + return listOrgInstancesResponse.Payload, nil +} + +func deleteOrg(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, orgID string) error { + return apiCli.Organizations.DeleteOrg( + clientOrganizations.NewDeleteOrgParams().WithOrgID(orgID), + apiAuthToken) +} + +func deleteOrgPool(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, orgID, poolID string) error { + return apiCli.Organizations.DeleteOrgPool( + clientOrganizations.NewDeleteOrgPoolParams().WithOrgID(orgID).WithPoolID(poolID), + apiAuthToken) +} + +// //////////// +// Instances // +// //////////// +func listInstances(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter) (params.Instances, error) { + listInstancesResponse, err := apiCli.Instances.ListInstances( + clientInstances.NewListInstancesParams(), + apiAuthToken) + if err != nil { + return nil, err + } + return listInstancesResponse.Payload, nil +} + +func getInstance(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, instanceID string) (*params.Instance, error) { + getInstancesResponse, err := apiCli.Instances.GetInstance( + clientInstances.NewGetInstanceParams().WithInstanceName(instanceID), + apiAuthToken) + if err != nil { + return nil, err + } + return &getInstancesResponse.Payload, nil +} + +func deleteInstance(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, instanceID string) error { + return apiCli.Instances.DeleteInstance( + clientInstances.NewDeleteInstanceParams().WithInstanceName(instanceID), + apiAuthToken) +} + +// //////// +// Pools // +// //////// +func listPools(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter) (params.Pools, error) { + listPoolsResponse, err := apiCli.Pools.ListPools( + clientPools.NewListPoolsParams(), + apiAuthToken) + if err != nil { + return nil, err + } + return listPoolsResponse.Payload, nil +} + +func getPool(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, poolID string) (*params.Pool, error) { + getPoolResponse, err := apiCli.Pools.GetPool( + clientPools.NewGetPoolParams().WithPoolID(poolID), + apiAuthToken) + if err != nil { + return nil, err + } + return &getPoolResponse.Payload, nil +} + +func updatePool(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, poolID string, poolParams params.UpdatePoolParams) (*params.Pool, error) { + updatePoolResponse, err := apiCli.Pools.UpdatePool( + clientPools.NewUpdatePoolParams().WithPoolID(poolID).WithBody(poolParams), + apiAuthToken) + if err != nil { + return nil, err + } + return &updatePoolResponse.Payload, nil +} + +func listPoolInstances(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, poolID string) (params.Instances, error) { + listPoolInstancesResponse, err := apiCli.Instances.ListPoolInstances( + clientInstances.NewListPoolInstancesParams().WithPoolID(poolID), + apiAuthToken) + if err != nil { + return nil, err + } + return listPoolInstancesResponse.Payload, nil +} + +func deletePool(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, poolID string) error { + return apiCli.Pools.DeletePool( + clientPools.NewDeletePoolParams().WithPoolID(poolID), + apiAuthToken) +} + +// ///////////////// +// Main functions // +// ///////////////// +// +// ///////////// +// Garm Init // +// ///////////// +func Login() { + log.Println(">>> Login") + loginParams := params.PasswordLoginParams{ + Username: username, + Password: password, + } + token, err := login(cli, loginParams) + handleError(err) + printResponse(token) + authToken = openapiRuntimeClient.BearerToken(token) + cfg.Managers = []config.Manager{ + { + Name: name, + BaseURL: baseURL, + Token: token, + }, + } + cfg.ActiveManager = name + err = cfg.SaveConfig() + handleError(err) +} + +func FirstRun() { + existingCfg, err := config.LoadConfig() + handleError(err) + if existingCfg != nil { + if existingCfg.HasManager(name) { + log.Println(">>> Already initialized") + return + } + } + + log.Println(">>> First run") + newUser := params.NewUserParams{ + Username: username, + Password: password, + FullName: fullName, + Email: email, + } + user, err := firstRun(cli, newUser) + handleError(err) + printResponse(user) +} + +// //////////////////////////// +// Credentials and Providers // +// //////////////////////////// +func ListCredentials() { + log.Println(">>> List credentials") + credentials, err := listCredentials(cli, authToken) + handleError(err) + printResponse(credentials) +} + +func ListProviders() { + log.Println(">>> List providers") + providers, err := listProviders(cli, authToken) + handleError(err) + printResponse(providers) +} + +// //////// +// Jobs // +// //////// +func ListJobs() { + log.Println(">>> List jobs") + jobs, err := listJobs(cli, authToken) + handleError(err) + printResponse(jobs) +} + +// ////////////////// +// / Metrics Token // +// ////////////////// +func GetMetricsToken() { + log.Println(">>> Get metrics token") + token, err := getMetricsToken(cli, authToken) + handleError(err) + printResponse(token) +} + +// /////////////// +// Repositories // +// /////////////// +func CreateRepo() { + repos, err := listRepos(cli, authToken) + handleError(err) + if len(repos) > 0 { + log.Println(">>> Repo already exists, skipping create") + repoID = repos[0].ID + return + } + log.Println(">>> Create repo") + createParams := params.CreateRepoParams{ + Owner: orgName, + Name: repoName, + CredentialsName: credentialsName, + WebhookSecret: repoWebhookSecret, + } + repo, err := createRepo(cli, authToken, createParams) + handleError(err) + printResponse(repo) + repoID = repo.ID +} + +func ListRepos() { + log.Println(">>> List repos") + repos, err := listRepos(cli, authToken) + handleError(err) + printResponse(repos) +} + +func UpdateRepo() { + log.Println(">>> Update repo") + updateParams := params.UpdateEntityParams{ + CredentialsName: fmt.Sprintf("%s-clone", credentialsName), + } + repo, err := updateRepo(cli, authToken, repoID, updateParams) + handleError(err) + printResponse(repo) +} + +func GetRepo() { + log.Println(">>> Get repo") + repo, err := getRepo(cli, authToken, repoID) + handleError(err) + printResponse(repo) +} + +func CreateRepoPool() { + pools, err := listRepoPools(cli, authToken, repoID) + handleError(err) + if len(pools) > 0 { + log.Println(">>> Repo pool already exists, skipping create") + repoPoolID = pools[0].ID + return + } + log.Println(">>> Create repo pool") + poolParams := params.CreatePoolParams{ + MaxRunners: 2, + MinIdleRunners: 0, + Flavor: "default", + Image: "ubuntu:22.04", + OSType: commonParams.Linux, + OSArch: commonParams.Amd64, + ProviderName: "lxd_local", + Tags: []string{"ubuntu", "simple-runner"}, + Enabled: true, + } + repo, err := createRepoPool(cli, authToken, repoID, poolParams) + handleError(err) + printResponse(repo) + repoPoolID = repo.ID +} + +func ListRepoPools() { + log.Println(">>> List repo pools") + pools, err := listRepoPools(cli, authToken, repoID) + handleError(err) + printResponse(pools) +} + +func GetRepoPool() { + log.Println(">>> Get repo pool") + pool, err := getRepoPool(cli, authToken, repoID, repoPoolID) + handleError(err) + printResponse(pool) +} + +func UpdateRepoPool() { + log.Println(">>> Update repo pool") + var maxRunners uint = 5 + var idleRunners uint = 1 + poolParams := params.UpdatePoolParams{ + MinIdleRunners: &idleRunners, + MaxRunners: &maxRunners, + } + pool, err := updateRepoPool(cli, authToken, repoID, repoPoolID, poolParams) + handleError(err) + printResponse(pool) +} + +func DisableRepoPool() { + enabled := false + _, err := updateRepoPool(cli, authToken, repoID, repoPoolID, params.UpdatePoolParams{Enabled: &enabled}) + handleError(err) + log.Printf("repo pool %s disabled", repoPoolID) +} + +func WaitRepoPoolNoInstances() { + for { + log.Println(">>> Wait until repo pool has no instances") + pool, err := getRepoPool(cli, authToken, repoID, repoPoolID) + handleError(err) + if len(pool.Instances) == 0 { + break + } + time.Sleep(5 * time.Second) + } +} + +func WaitRepoInstance(timeout time.Duration) { + var timeWaited time.Duration = 0 + + for timeWaited < timeout { + instances, err := listRepoInstances(cli, authToken, repoID) + handleError(err) + if len(instances) > 0 { + instance := instances[0] + log.Printf("instance %s status: %s", instance.Name, instance.Status) + if instance.Status == commonParams.InstanceRunning && instance.RunnerStatus == params.RunnerIdle { + repoInstanceName = instance.Name + log.Printf("Repo instance %s is in running state", repoInstanceName) + return + } + } + time.Sleep(5 * time.Second) + timeWaited += 5 + } + log.Fatalf("Failed to wait for repo instance to be ready") +} + +func ListRepoInstances() { + log.Println(">>> List repo instances") + instances, err := listRepoInstances(cli, authToken, repoID) + handleError(err) + printResponse(instances) +} + +func DeleteRepo() { + log.Println(">>> Delete repo") + err := deleteRepo(cli, authToken, repoID) + handleError(err) + log.Printf("repo %s deleted", repoID) +} + +func DeleteRepoPool() { + log.Println(">>> Delete repo pool") + err := deleteRepoPool(cli, authToken, repoID, repoPoolID) + handleError(err) + log.Printf("repo pool %s deleted", repoPoolID) +} + +// //////////////// +// Organizations // +// //////////////// +func CreateOrg() { + orgs, err := listOrgs(cli, authToken) + handleError(err) + if len(orgs) > 0 { + log.Println(">>> Org already exists, skipping create") + orgID = orgs[0].ID + return + } + log.Println(">>> Create org") + orgParams := params.CreateOrgParams{ + Name: orgName, + CredentialsName: credentialsName, + WebhookSecret: orgWebhookSecret, + } + org, err := createOrg(cli, authToken, orgParams) + handleError(err) + printResponse(org) + orgID = org.ID +} + +func ListOrgs() { + log.Println(">>> List orgs") + orgs, err := listOrgs(cli, authToken) + handleError(err) + printResponse(orgs) +} + +func UpdateOrg() { + log.Println(">>> Update org") + updateParams := params.UpdateEntityParams{ + CredentialsName: fmt.Sprintf("%s-clone", credentialsName), + } + org, err := updateOrg(cli, authToken, orgID, updateParams) + handleError(err) + printResponse(org) +} + +func GetOrg() { + log.Println(">>> Get org") + org, err := getOrg(cli, authToken, orgID) + handleError(err) + printResponse(org) +} + +func CreateOrgPool() { + pools, err := listOrgPools(cli, authToken, orgID) + handleError(err) + if len(pools) > 0 { + log.Println(">>> Org pool already exists, skipping create") + orgPoolID = pools[0].ID + return + } + log.Println(">>> Create org pool") + poolParams := params.CreatePoolParams{ + MaxRunners: 2, + MinIdleRunners: 0, + Flavor: "default", + Image: "ubuntu:22.04", + OSType: commonParams.Linux, + OSArch: commonParams.Amd64, + ProviderName: "lxd_local", + Tags: []string{"ubuntu", "simple-runner"}, + Enabled: true, + } + org, err := createOrgPool(cli, authToken, orgID, poolParams) + handleError(err) + printResponse(org) + orgPoolID = org.ID +} + +func ListOrgPools() { + log.Println(">>> List org pools") + pools, err := listOrgPools(cli, authToken, orgID) + handleError(err) + printResponse(pools) +} + +func GetOrgPool() { + log.Println(">>> Get org pool") + pool, err := getOrgPool(cli, authToken, orgID, orgPoolID) + handleError(err) + printResponse(pool) +} + +func UpdateOrgPool() { + log.Println(">>> Update org pool") + var maxRunners uint = 5 + var idleRunners uint = 1 + poolParams := params.UpdatePoolParams{ + MinIdleRunners: &idleRunners, + MaxRunners: &maxRunners, + } + pool, err := updateOrgPool(cli, authToken, orgID, orgPoolID, poolParams) + handleError(err) + printResponse(pool) +} + +func DisableOrgPool() { + enabled := false + _, err := updateOrgPool(cli, authToken, orgID, orgPoolID, params.UpdatePoolParams{Enabled: &enabled}) + handleError(err) + log.Printf("org pool %s disabled", orgPoolID) +} + +func WaitOrgPoolNoInstances() { + for { + log.Println(">>> Wait until org pool has no instances") + pool, err := getOrgPool(cli, authToken, orgID, orgPoolID) + handleError(err) + if len(pool.Instances) == 0 { + break + } + time.Sleep(5 * time.Second) + } +} + +func WaitOrgInstance(timeout time.Duration) { + var timeWaited time.Duration = 0 + + for timeWaited < timeout { + instances, err := listOrgInstances(cli, authToken, orgID) + handleError(err) + if len(instances) > 0 { + instance := instances[0] + log.Printf("instance %s status: %s", instance.Name, instance.Status) + if instance.Status == commonParams.InstanceRunning && instance.RunnerStatus == params.RunnerIdle { + orgInstanceName = instance.Name + log.Printf("Org instance %s is in running state", orgInstanceName) + return + } + } + time.Sleep(5 * time.Second) + timeWaited += 5 + } + log.Fatalf("Failed to wait for org instance to be ready") +} + +func ListOrgInstances() { + log.Println(">>> List org instances") + instances, err := listOrgInstances(cli, authToken, orgID) + handleError(err) + printResponse(instances) +} + +func DeleteOrg() { + log.Println(">>> Delete org") + err := deleteOrg(cli, authToken, orgID) + handleError(err) + log.Printf("org %s deleted", orgID) +} + +func DeleteOrgPool() { + log.Println(">>> Delete org pool") + err := deleteOrgPool(cli, authToken, orgID, orgPoolID) + handleError(err) + log.Printf("org pool %s deleted", orgPoolID) +} + +// //////////// +// Instances // +// //////////// +func ListInstances() { + log.Println(">>> List instances") + instances, err := listInstances(cli, authToken) + handleError(err) + printResponse(instances) +} + +func GetInstance() { + log.Println(">>> Get instance") + instance, err := getInstance(cli, authToken, orgInstanceName) + handleError(err) + printResponse(instance) +} + +func DeleteInstance(name string) { + err := deleteInstance(cli, authToken, name) + for { + log.Printf(">>> Wait until instance %s is deleted", name) + instances, err := listInstances(cli, authToken) + handleError(err) + for _, instance := range instances { + if instance.Name == name { + time.Sleep(5 * time.Second) + + continue + } + } + break + } + handleError(err) + log.Printf("instance %s deleted", name) +} + +// //////// +// Pools // +// //////// +func CreatePool() { + pools, err := listPools(cli, authToken) + handleError(err) + for _, pool := range pools { + if pool.Image == "ubuntu:20.04" { + // this is the extra pool to be deleted, later, via [DELETE] pools dedicated API. + poolID = pool.ID + return + } + } + log.Println(">>> Create pool") + poolParams := params.CreatePoolParams{ + MaxRunners: 2, + MinIdleRunners: 0, + Flavor: "default", + Image: "ubuntu:20.04", + OSType: commonParams.Linux, + OSArch: commonParams.Amd64, + ProviderName: "lxd_local", + Tags: []string{"ubuntu", "simple-runner"}, + Enabled: true, + } + pool, err := createRepoPool(cli, authToken, repoID, poolParams) + handleError(err) + printResponse(pool) + poolID = pool.ID +} + +func ListPools() { + log.Println(">>> List pools") + pools, err := listPools(cli, authToken) + handleError(err) + printResponse(pools) +} + +func UpdatePool() { + log.Println(">>> Update pool") + var maxRunners uint = 5 + var idleRunners uint = 0 + poolParams := params.UpdatePoolParams{ + MinIdleRunners: &idleRunners, + MaxRunners: &maxRunners, + } + pool, err := updatePool(cli, authToken, poolID, poolParams) + handleError(err) + printResponse(pool) +} + +func GetPool() { + log.Println(">>> Get pool") + pool, err := getPool(cli, authToken, poolID) + handleError(err) + printResponse(pool) +} + +func DeletePool() { + log.Println(">>> Delete pool") + err := deletePool(cli, authToken, poolID) + handleError(err) + log.Printf("pool %s deleted", poolID) +} + +func ListPoolInstances() { + log.Println(">>> List pool instances") + instances, err := listPoolInstances(cli, authToken, repoPoolID) + handleError(err) + printResponse(instances) +} + +func main() { + ////////////////// + // initialize cli / + ////////////////// + garmUrl, err := url.Parse(baseURL) + handleError(err) + apiPath, err := url.JoinPath(garmUrl.Path, client.DefaultBasePath) + handleError(err) + transportCfg := client.DefaultTransportConfig(). + WithHost(garmUrl.Host). + WithBasePath(apiPath). + WithSchemes([]string{garmUrl.Scheme}) + cli = client.NewHTTPClientWithConfig(nil, transportCfg) + + ////////////////// + // garm init // + ////////////////// + FirstRun() + Login() + + // //////////////////////////// + // credentials and providers // + // //////////////////////////// + ListCredentials() + ListProviders() + + ////////// + // jobs // + ////////// + ListJobs() + + //////////////////// + /// metrics token // + //////////////////// + GetMetricsToken() + + ////////////////// + // repositories // + ////////////////// + CreateRepo() + ListRepos() + UpdateRepo() + GetRepo() + + CreateRepoPool() + ListRepoPools() + GetRepoPool() + UpdateRepoPool() + + ////////////////// + // organizations // + ////////////////// + CreateOrg() + ListOrgs() + UpdateOrg() + GetOrg() + + CreateOrgPool() + ListOrgPools() + GetOrgPool() + UpdateOrgPool() + + /////////////// + // instances // + /////////////// + WaitRepoInstance(180) + ListRepoInstances() + + WaitOrgInstance(180) + ListOrgInstances() + + ListInstances() + GetInstance() + + /////////////// + // pools // + /////////////// + CreatePool() + ListPools() + UpdatePool() + GetPool() + ListPoolInstances() + + ///////////// + // Cleanup // + ///////////// + DisableRepoPool() + DisableOrgPool() + + DeleteInstance(repoInstanceName) + DeleteInstance(orgInstanceName) + + WaitRepoPoolNoInstances() + WaitOrgPoolNoInstances() + + DeleteRepoPool() + DeleteOrgPool() + DeletePool() + + DeleteRepo() + DeleteOrg() +} diff --git a/test/integration/scripts/setup-garm.sh b/test/integration/scripts/setup-garm.sh new file mode 100755 index 00000000..b4a86aa4 --- /dev/null +++ b/test/integration/scripts/setup-garm.sh @@ -0,0 +1,64 @@ +#!/usr/bin/env bash +set -o errexit + +if [[ $EUID -ne 0 ]]; then + echo "ERROR: Please run $0 script as root" + exit 1 +fi + +DIR="$(dirname $0)" +BINARIES_DIR="$DIR/../../../bin" +CONTRIB_DIR="$DIR/../../../contrib" +CONFIG_DIR="$DIR/../config" + +if [[ ! -f $BINARIES_DIR/garm ]] || [[ ! -f $BINARIES_DIR/garm-cli ]]; then + echo "ERROR: Please build GARM binaries first" + exit 1 +fi + +if [[ -z $GH_OAUTH_TOKEN ]]; then echo "ERROR: The env variable GH_OAUTH_TOKEN is not set"; exit 1; fi +if [[ -z $CREDENTIALS_NAME ]]; then echo "ERROR: The env variable CREDENTIALS_NAME is not set"; exit 1; fi + +# Generate a random 32-char secret for JWT_AUTH_SECRET and DB_PASSPHRASE. +function generate_secret() { + (tr -dc 'a-zA-Z0-9!@#$%^&*()_+?><~\`;' < /dev/urandom | head -c 32) 2>/dev/null +} + +# Wait for a port to open at a given address. +function wait_open_port() { + local ADDRESS="$1" + local PORT="$2" + local TIMEOUT=30 + SECONDS=0 + while true; do + if [[ $SECONDS -gt $TIMEOUT ]]; then + echo "ERROR: Port $PORT didn't open at $ADDRESS within $TIMEOUT seconds" + return 1 + fi + nc -v -w 5 -z "$ADDRESS" "$PORT" &>/dev/null && break || sleep 1 + done + echo "Port $PORT at address $ADDRESS is open" +} + +# Use the LXD bridge IP address as the GARM metadata address. +export GARM_METADATA_IP=$(lxc network ls -f json 2>/dev/null | jq -r '.[] | select(.name=="lxdbr0") | .config."ipv4.address"' | cut -d '/' -f1) + +export JWT_AUTH_SECRET="$(generate_secret)" +export DB_PASSPHRASE="$(generate_secret)" + +# Group "adm" is the LXD daemon group as set by the "canonical/setup-lxd" GitHub action. +useradd --shell /usr/bin/false --system --groups adm --no-create-home garm + +mkdir -p /etc/garm +cat $CONFIG_DIR/config.toml | envsubst > /etc/garm/config.toml +chown -R garm:garm /etc/garm + +mv $BINARIES_DIR/* /usr/local/bin/ +cp $CONTRIB_DIR/garm.service /etc/systemd/system/garm.service + +systemctl daemon-reload +systemctl start garm + +wait_open_port 127.0.0.1 9997 + +echo "GARM is up and running" From d2ffa22204cdb0d81cb9900b60f9b3bdd0f5d2b6 Mon Sep 17 00:00:00 2001 From: Gabriel Adrian Samfira Date: Wed, 2 Aug 2023 17:14:27 +0300 Subject: [PATCH 2/6] Set up ngrok and use sudo Signed-off-by: Gabriel Adrian Samfira --- .github/workflows/integration-tests.yml | 25 ++++++++++++++++++----- test/integration/scripts/setup-garm.sh | 27 ++++++++++--------------- 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index b52389f1..d0209a5c 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -26,23 +26,38 @@ jobs: run: make build - name: Setup GARM - run: sudo --preserve-env ./test/integration/scripts/setup-garm.sh + run: ./test/integration/scripts/setup-garm.sh env: GH_OAUTH_TOKEN: ${{ secrets.GH_OAUTH_TOKEN }} CREDENTIALS_NAME: test-garm-creds + - name: Generate secrets + run: | + function randomStringGenerator() { + tr -dc "a-zA-Z0-9@#$%^&*()_+?><~\`;'" > $GITHUB_ENV + echo "REPO_WEBHOOK_SECRET=$(randomStringGenerator)" >> $GITHUB_ENV + echo "ORG_WEBHOOK_SECRET=$(randomStringGenerator)" >> $GITHUB_ENV + + - name: Set up ngrok + id: ngrok + uses: gabriel-samfira/ngrok-tunnel-action@v1.0 + with: + ngrok_authtoken: ${{ secrets.NGROK_AUTH_TOKEN }} + port: 9997 + tunnel_type: http + + - name: Run integration tests run: go run ./test/integration/e2e.go env: - GARM_BASE_URL: http://127.0.0.1:9997 + GARM_BASE_URL: ${{ steps.ngrok.outputs.tunnel-url }} GARM_USERNAME: admin - GARM_PASSWORD: ${{ secrets.GARM_ADMIN_PASSWORD }} GARM_FULLNAME: Local GARM Admin GARM_EMAIL: admin@example.com GARM_NAME: local_garm CREDENTIALS_NAME: test-garm-creds - REPO_WEBHOOK_SECRET: ${{ secrets.REPO_WEBHOOK_SECRET }} - ORG_WEBHOOK_SECRET: ${{ secrets.ORG_WEBHOOK_SECRET }} - name: Show GARM logs if: always() diff --git a/test/integration/scripts/setup-garm.sh b/test/integration/scripts/setup-garm.sh index b4a86aa4..0811ae0f 100755 --- a/test/integration/scripts/setup-garm.sh +++ b/test/integration/scripts/setup-garm.sh @@ -1,15 +1,10 @@ #!/usr/bin/env bash set -o errexit -if [[ $EUID -ne 0 ]]; then - echo "ERROR: Please run $0 script as root" - exit 1 -fi - DIR="$(dirname $0)" -BINARIES_DIR="$DIR/../../../bin" -CONTRIB_DIR="$DIR/../../../contrib" -CONFIG_DIR="$DIR/../config" +BINARIES_DIR="$PWD/bin" +CONTRIB_DIR="$PWD/contrib" +CONFIG_DIR="$PWD/config" if [[ ! -f $BINARIES_DIR/garm ]] || [[ ! -f $BINARIES_DIR/garm-cli ]]; then echo "ERROR: Please build GARM binaries first" @@ -47,17 +42,17 @@ export JWT_AUTH_SECRET="$(generate_secret)" export DB_PASSPHRASE="$(generate_secret)" # Group "adm" is the LXD daemon group as set by the "canonical/setup-lxd" GitHub action. -useradd --shell /usr/bin/false --system --groups adm --no-create-home garm +sudo useradd --shell /usr/bin/false --system --groups adm --no-create-home garm -mkdir -p /etc/garm -cat $CONFIG_DIR/config.toml | envsubst > /etc/garm/config.toml -chown -R garm:garm /etc/garm +sudo mkdir -p /etc/garm +cat $CONFIG_DIR/config.toml | envsubst | sudo tee /etc/garm/config.toml +sudo chown -R garm:garm /etc/garm -mv $BINARIES_DIR/* /usr/local/bin/ -cp $CONTRIB_DIR/garm.service /etc/systemd/system/garm.service +sudo mv $BINARIES_DIR/* /usr/local/bin/ +sudo cp $CONTRIB_DIR/garm.service /etc/systemd/system/garm.service -systemctl daemon-reload -systemctl start garm +sudo systemctl daemon-reload +sudo systemctl start garm wait_open_port 127.0.0.1 9997 From d02292bd1aa78403cbcb44b17b7f4f874b3f0361 Mon Sep 17 00:00:00 2001 From: Gabriel Adrian Samfira Date: Wed, 2 Aug 2023 17:22:25 +0300 Subject: [PATCH 3/6] Fix config dir location Signed-off-by: Gabriel Adrian Samfira --- .github/workflows/integration-tests.yml | 3 +-- test/integration/scripts/setup-garm.sh | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index d0209a5c..835a4e1c 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -42,12 +42,11 @@ jobs: - name: Set up ngrok id: ngrok - uses: gabriel-samfira/ngrok-tunnel-action@v1.0 + uses: gabriel-samfira/ngrok-tunnel-action@867169320326b49398c565de3b3f0ee75fb1599a with: ngrok_authtoken: ${{ secrets.NGROK_AUTH_TOKEN }} port: 9997 tunnel_type: http - - name: Run integration tests run: go run ./test/integration/e2e.go diff --git a/test/integration/scripts/setup-garm.sh b/test/integration/scripts/setup-garm.sh index 0811ae0f..46f3e51b 100755 --- a/test/integration/scripts/setup-garm.sh +++ b/test/integration/scripts/setup-garm.sh @@ -4,7 +4,7 @@ set -o errexit DIR="$(dirname $0)" BINARIES_DIR="$PWD/bin" CONTRIB_DIR="$PWD/contrib" -CONFIG_DIR="$PWD/config" +CONFIG_DIR="$PWD/test/integration/config" if [[ ! -f $BINARIES_DIR/garm ]] || [[ ! -f $BINARIES_DIR/garm-cli ]]; then echo "ERROR: Please build GARM binaries first" From 9927a18b9aa1dd4547948740679bbe2a7476677a Mon Sep 17 00:00:00 2001 From: Gabriel Adrian Samfira Date: Wed, 2 Aug 2023 17:34:00 +0300 Subject: [PATCH 4/6] Update ngrok action Signed-off-by: Gabriel Adrian Samfira --- .github/workflows/integration-tests.yml | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 835a4e1c..a7283c9b 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -36,13 +36,22 @@ jobs: function randomStringGenerator() { tr -dc "a-zA-Z0-9@#$%^&*()_+?><~\`;'" > $GITHUB_ENV - echo "REPO_WEBHOOK_SECRET=$(randomStringGenerator)" >> $GITHUB_ENV - echo "ORG_WEBHOOK_SECRET=$(randomStringGenerator)" >> $GITHUB_ENV + + GARM_PASSWORD=$(randomStringGenerator) + REPO_WEBHOOK_SECRET=$(randomStringGenerator) + ORG_WEBHOOK_SECRET=$(randomStringGenerator) + + echo "::add-mask::$GARM_PASSWORD" + echo "::add-mask::$REPO_WEBHOOK_SECRET" + echo "::add-mask::$ORG_WEBHOOK_SECRET" + + echo "GARM_PASSWORD=$GARM_PASSWORD" >> $GITHUB_ENV + echo "REPO_WEBHOOK_SECRET=$REPO_WEBHOOK_SECRET" >> $GITHUB_ENV + echo "ORG_WEBHOOK_SECRET=$ORG_WEBHOOK_SECRET" >> $GITHUB_ENV - name: Set up ngrok id: ngrok - uses: gabriel-samfira/ngrok-tunnel-action@867169320326b49398c565de3b3f0ee75fb1599a + uses: gabriel-samfira/ngrok-tunnel-action@v1.1 with: ngrok_authtoken: ${{ secrets.NGROK_AUTH_TOKEN }} port: 9997 From 528f5218970b71c91dbfc933da591ca6dbfeb6f8 Mon Sep 17 00:00:00 2001 From: Mihaela Balutoiu Date: Wed, 2 Aug 2023 19:25:56 +0300 Subject: [PATCH 5/6] Set schedule workflow to run every day at midnight Signed-off-by: Mihaela Balutoiu --- .github/workflows/integration-tests.yml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index a7283c9b..43447c8f 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -1,11 +1,7 @@ name: Integration Tests on: - push: - branches: - - main - pull_request: - branches: - - main + schedule: + - cron: "0 0 * * *" jobs: integration-tests: From cf0c1f188b66e130059bd1af6098fd2b634a5da3 Mon Sep 17 00:00:00 2001 From: Mihaela Balutoiu Date: Wed, 2 Aug 2023 20:23:46 +0300 Subject: [PATCH 6/6] Fix org_name/repo_name Signed-off-by: Mihaela Balutoiu --- .github/workflows/integration-tests.yml | 2 ++ test/integration/e2e.go | 7 ++----- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 43447c8f..3be23581 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -61,6 +61,8 @@ jobs: GARM_FULLNAME: Local GARM Admin GARM_EMAIL: admin@example.com GARM_NAME: local_garm + ORG_NAME: gsamfira + REPO_NAME: garm-testing CREDENTIALS_NAME: test-garm-creds - name: Show GARM logs diff --git a/test/integration/e2e.go b/test/integration/e2e.go index 51553aca..ba173504 100644 --- a/test/integration/e2e.go +++ b/test/integration/e2e.go @@ -26,11 +26,6 @@ import ( openapiRuntimeClient "github.com/go-openapi/runtime/client" ) -const ( - orgName = "gsamfira" - repoName = "scripts" -) - var ( cli *client.GarmAPI cfg config.Config @@ -41,11 +36,13 @@ var ( repoID string repoPoolID string repoInstanceName string + repoName = os.Getenv("REPO_NAME") repoWebhookSecret = os.Getenv("REPO_WEBHOOK_SECRET") orgID string orgPoolID string orgInstanceName string + orgName = os.Getenv("ORG_NAME") orgWebhookSecret = os.Getenv("ORG_WEBHOOK_SECRET") username = os.Getenv("GARM_USERNAME")