Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions hack/check-e2e-test-naming.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ if [[ ${#testfiles[@]} -eq 0 ]]; then
exit 0
fi

# Extract all Test* function names
all_tests=$(grep -hE '^func[[:space:]]+Test[[:alnum:]_]+' "${testfiles[@]}" | sed -E 's/^func[[:space:]]+([[:alnum:]_]+).*/\1/')
# Extract all Test* function names (excluding TestMain which is a Go test harness, not a test)
all_tests=$(grep -hE '^func[[:space:]]+Test[[:alnum:]_]+' "${testfiles[@]}" | sed -E 's/^func[[:space:]]+([[:alnum:]_]+).*/\1/' | grep -v '^TestMain$')

# Valid patterns: TestGithub*, TestGitea*, TestGitlab*, TestBitbucket*, TestOthers*, or *Concurrency*
valid_pattern='^Test(Github|Gitea|Gitlab|Bitbucket|Others)|Concurrency'
Expand Down
25 changes: 25 additions & 0 deletions test/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,31 @@ this repo should differ from the one which is configured as part of `TEST_GITHUB

You don't need to configure all of those if you restrict running your e2e tests to a subset.

### YAML Configuration File

Instead of setting individual environment variables, you can use a YAML
configuration file. Set `PAC_E2E_CONFIG` to the path of your config file:

```shell
PAC_E2E_CONFIG=./test/e2e-config.yaml make test-e2e
```

Copy the example file and fill in the values for the providers you want to test:

```shell
cp test/e2e-config.yaml.example test/e2e-config.yaml
# edit test/e2e-config.yaml with your values
```

The YAML file groups settings by provider section (`common`, `github`,
`github_enterprise`, `gitlab`, `gitea`, `bitbucket_cloud`,
`bitbucket_server`). See `test/e2e-config.yaml.example` for the full list of
fields.

Environment variables always take precedence over YAML values, so you can use
the config file for base settings and override specific values via env vars
(useful for CI secrets).

## Running

As long you have env variables set, you can just do a :
Expand Down
76 changes: 76 additions & 0 deletions test/e2e-config.yaml.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Pipelines-as-Code E2E Test Configuration
#
# Copy this file and fill in the values for the providers you want to test:
# cp e2e-config.yaml.example e2e-config.yaml
#
# Then run tests with:
# PAC_E2E_CONFIG=./test/e2e-config.yaml make test-e2e
#
# You only need to fill in the sections for the providers you are testing.
# Environment variables always take precedence over values in this file.

# Common settings shared across providers
common:
# The controller public URL (ingress or OpenShift route)
controller_url: "https://pac-controller.example.com"
# Webhook secret configured on the controller
webhook_secret: ""
# Set to "true" to skip cleanup after tests (useful for debugging)
# no_cleanup: "true"

# GitHub (public)
github:
api_url: "https://api.github.com"
token: ""
# Repository configured with GitHub Apps (format: org/repo)
repo_owner_githubapp: ""
# Repository configured with webhooks (format: org/repo, must differ from githubapp repo)
repo_owner_webhook: ""
# Installation ID from GitHub App webhook deliveries
repo_installation_id: ""
# Private remote task for scoped token tests (optional)
# private_task_name: "task-remote"
# private_task_url: "https://github.com/org/private-repo/blob/main/task.yaml"

# GitHub Enterprise (second controller)
github_enterprise:
api_url: ""
token: ""
controller_url: ""
repo_owner_githubapp: ""
repo_installation_id: ""

# GitLab
gitlab:
api_url: "https://gitlab.com"
token: ""
# Project ID (find in repo Settings > General)
project_id: ""

# Gitea / Forgejo
gitea:
api_url: "http://localhost:3000"
# Internal URL for in-cluster access (optional)
# internal_url: "http://forgejo-http.forgejo.svc.cluster.local:3000"
password: "pac"
username: "pac"
repo_owner: "pac/pac"
smee_url: ""

# Bitbucket Cloud
bitbucket_cloud:
api_url: "https://api.bitbucket.org/2.0"
# Username from "Personal Bitbucket settings"
user: ""
token: ""
# Format: workspace/repo
e2e_repository: ""

# Bitbucket Data Center (Server)
bitbucket_server:
api_url: ""
user: ""
token: ""
# Format: project/repo
e2e_repository: ""
webhook_secret: ""
21 changes: 21 additions & 0 deletions test/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//go:build e2e

package test

import (
"fmt"
"os"
"testing"

"github.com/openshift-pipelines/pipelines-as-code/test/pkg/configfile"
)

func TestMain(m *testing.M) {
if configPath := os.Getenv("PAC_E2E_CONFIG"); configPath != "" {
if err := configfile.LoadConfig(configPath); err != nil {
fmt.Fprintf(os.Stderr, "Error loading E2E config %s: %v\n", configPath, err)
os.Exit(1)
}
}
os.Exit(m.Run())
}
124 changes: 124 additions & 0 deletions test/pkg/configfile/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package configfile

import (
"fmt"
"os"
"reflect"

"sigs.k8s.io/yaml"
)

type E2EConfig struct {
Common CommonConfig `json:"common" yaml:"common"`
GitHub GitHubConfig `json:"github" yaml:"github"`
GitHubEnterprise GitHubEnterpriseConfig `json:"github_enterprise" yaml:"github_enterprise"`
GitLab GitLabConfig `json:"gitlab" yaml:"gitlab"`
Gitea GiteaConfig `json:"gitea" yaml:"gitea"`
BitbucketCloud BitbucketCloudConfig `json:"bitbucket_cloud" yaml:"bitbucket_cloud"`
BitbucketServer BitbucketServerConfig `json:"bitbucket_server" yaml:"bitbucket_server"`
}

type CommonConfig struct {
ControllerURL string `env:"TEST_EL_URL" json:"controller_url" yaml:"controller_url"`
WebhookSecret string `env:"TEST_EL_WEBHOOK_SECRET" json:"webhook_secret" yaml:"webhook_secret"`
NoCleanup string `env:"TEST_NOCLEANUP" json:"no_cleanup" yaml:"no_cleanup"`
}

type GitHubConfig struct {
APIURL string `env:"TEST_GITHUB_API_URL" json:"api_url" yaml:"api_url"`
Token string `env:"TEST_GITHUB_TOKEN" json:"token" yaml:"token"`
RepoOwnerGithubApp string `env:"TEST_GITHUB_REPO_OWNER_GITHUBAPP" json:"repo_owner_githubapp" yaml:"repo_owner_githubapp"`
RepoOwnerWebhook string `env:"TEST_GITHUB_REPO_OWNER_WEBHOOK" json:"repo_owner_webhook" yaml:"repo_owner_webhook"`
RepoInstallationID string `env:"TEST_GITHUB_REPO_INSTALLATION_ID" json:"repo_installation_id" yaml:"repo_installation_id"`
PrivateTaskName string `env:"TEST_GITHUB_PRIVATE_TASK_NAME" json:"private_task_name" yaml:"private_task_name"`
PrivateTaskURL string `env:"TEST_GITHUB_PRIVATE_TASK_URL" json:"private_task_url" yaml:"private_task_url"`
}

type GitHubEnterpriseConfig struct {
APIURL string `env:"TEST_GITHUB_SECOND_API_URL" json:"api_url" yaml:"api_url"`
Token string `env:"TEST_GITHUB_SECOND_TOKEN" json:"token" yaml:"token"`
ControllerURL string `env:"TEST_GITHUB_SECOND_EL_URL" json:"controller_url" yaml:"controller_url"`
RepoOwnerGithubApp string `env:"TEST_GITHUB_SECOND_REPO_OWNER_GITHUBAPP" json:"repo_owner_githubapp" yaml:"repo_owner_githubapp"`
RepoInstallationID string `env:"TEST_GITHUB_SECOND_REPO_INSTALLATION_ID" json:"repo_installation_id" yaml:"repo_installation_id"`
}

type GitLabConfig struct {
APIURL string `env:"TEST_GITLAB_API_URL" json:"api_url" yaml:"api_url"`
Token string `env:"TEST_GITLAB_TOKEN" json:"token" yaml:"token"`
ProjectID string `env:"TEST_GITLAB_PROJECT_ID" json:"project_id" yaml:"project_id"`
}

type GiteaConfig struct {
APIURL string `env:"TEST_GITEA_API_URL" json:"api_url" yaml:"api_url"`
InternalURL string `env:"TEST_GITEA_INTERNAL_URL" json:"internal_url" yaml:"internal_url"`
Password string `env:"TEST_GITEA_PASSWORD" json:"password" yaml:"password"`
Username string `env:"TEST_GITEA_USERNAME" json:"username" yaml:"username"`
RepoOwner string `env:"TEST_GITEA_REPO_OWNER" json:"repo_owner" yaml:"repo_owner"`
SmeeURL string `env:"TEST_GITEA_SMEEURL" json:"smee_url" yaml:"smee_url"`
}

type BitbucketCloudConfig struct {
APIURL string `env:"TEST_BITBUCKET_CLOUD_API_URL" json:"api_url" yaml:"api_url"`
User string `env:"TEST_BITBUCKET_CLOUD_USER" json:"user" yaml:"user"`
Token string `env:"TEST_BITBUCKET_CLOUD_TOKEN" json:"token" yaml:"token"`
E2ERepository string `env:"TEST_BITBUCKET_CLOUD_E2E_REPOSITORY" json:"e2e_repository" yaml:"e2e_repository"`
}

type BitbucketServerConfig struct {
APIURL string `env:"TEST_BITBUCKET_SERVER_API_URL" json:"api_url" yaml:"api_url"`
User string `env:"TEST_BITBUCKET_SERVER_USER" json:"user" yaml:"user"`
Token string `env:"TEST_BITBUCKET_SERVER_TOKEN" json:"token" yaml:"token"`
E2ERepository string `env:"TEST_BITBUCKET_SERVER_E2E_REPOSITORY" json:"e2e_repository" yaml:"e2e_repository"`
WebhookSecret string `env:"TEST_BITBUCKET_SERVER_WEBHOOK_SECRET" json:"webhook_secret" yaml:"webhook_secret"`
}

// LoadConfig reads a YAML config file and sets environment variables for any
// field that has an `env` struct tag. Existing environment variables take
// precedence over values from the config file.
func LoadConfig(path string) error {
data, err := os.ReadFile(path)
if err != nil {
return fmt.Errorf("reading config file %s: %w", path, err)
}

var cfg E2EConfig
if err := yaml.Unmarshal(data, &cfg); err != nil {
return fmt.Errorf("parsing config file %s: %w", path, err)
}

setEnvsFromStruct(reflect.ValueOf(cfg))
return nil
}

// setEnvsFromStruct walks all fields of a struct (recursing into nested
// structs) and calls os.Setenv for each field that has an `env` tag, but only
// when the environment variable is not already set and the YAML value is
// non-empty.
func setEnvsFromStruct(v reflect.Value) {
t := v.Type()
for i := range t.NumField() {
field := t.Field(i)
value := v.Field(i)

if field.Type.Kind() == reflect.Struct {
setEnvsFromStruct(value)
continue
}

envKey := field.Tag.Get("env")
if envKey == "" {
continue
}

yamlVal := value.String()
if yamlVal == "" {
continue
}

if _, exists := os.LookupEnv(envKey); exists {
continue
}

os.Setenv(envKey, yamlVal)
}
}
Loading