Skip to content

Commit aa3025d

Browse files
authored
Merge branch 'main' into dependabot/github_actions/actions/setup-go-6.3.0
2 parents 6e49b6a + eb6cd3d commit aa3025d

20 files changed

+1298
-971
lines changed

.github/pull_request_template.md

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,6 @@
99
Fixes #
1010

1111
<!-- This is optional, but if you have a Jira ticket related to this PR, please link it here. -->
12-
## 🚀 Type of Change
13-
14-
<!-- (update the title of the Pull Request accordingly), the lint task checks it -->
15-
16-
- [ ] 🐛 Bug fix (`fix:`)
17-
- [ ] ✨ New feature (`feat:`)
18-
- [ ] 💥 Breaking change (`feat!:`, `fix!:`)
19-
- [ ] 📚 Documentation update (`docs:`)
20-
- [ ] 🎨 Style (`style:`)
21-
- [ ] 💅 Refactor (`refactor:`)
22-
- [ ] ⚡ Performance (`perf:`)
23-
- [ ] ✅ Test (`test:`)
24-
- [ ] 🏗️ Build (`build:`)
25-
- [ ] 👷 CI (`ci:`)
26-
- [ ] ⚙️ Chore (`chore:`)
27-
- [ ] ⏪ Revert (`revert:`)
28-
- [ ] 📦 Dependency update (`deps:`)
2912

3013
## 🧪 Testing Strategy
3114

.github/workflows/e2e.yaml

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,6 @@ jobs:
8888
TEST_GITHUB_SECOND_REPO_OWNER_GITHUBAPP: pipelines-as-code/e2e
8989
TEST_GITHUB_SECOND_TOKEN: ${{ secrets.TEST_GITHUB_SECOND_TOKEN }}
9090
TEST_GITHUB_TOKEN: ${{ secrets.GH_APPS_TOKEN }}
91-
TEST_GITLAB_PROJECT_ID: ${{ vars.TEST_GITLAB_PROJECT_ID }}
9291
TEST_GITLAB_TOKEN: ${{ secrets.GITLAB_TOKEN }}
9392
steps:
9493
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
@@ -320,6 +319,20 @@ jobs:
320319
run: |
321320
nohup gosmee client --saveDir /tmp/gosmee-replay "${TEST_GITEA_SMEEURL}" "https://${CONTROLLER_DOMAIN_URL}" >> /tmp/gosmee-main.log 2>&1 &
322321
322+
- name: Generate unique gosmee URL for GitLab tests
323+
if: matrix.provider == 'gitlab_bitbucket'
324+
id: gosmee-gitlab-url
325+
run: |
326+
SMEE_URL=$(curl -s https://hook.pipelinesascode.com -o /dev/null -w '%{redirect_url}')
327+
echo "Generated unique GitLab smee URL: ${SMEE_URL}"
328+
echo "url=${SMEE_URL}" >> "$GITHUB_OUTPUT"
329+
echo "TEST_GITLAB_SMEEURL=${SMEE_URL}" >> "$GITHUB_ENV"
330+
331+
- name: Run gosmee for GitLab tests
332+
if: matrix.provider == 'gitlab_bitbucket'
333+
run: |
334+
nohup gosmee client --saveDir /tmp/gosmee-replay-gitlab "${TEST_GITLAB_SMEEURL}" "https://${CONTROLLER_DOMAIN_URL}" >> /tmp/gosmee-gitlab.log 2>&1 &
335+
323336
- name: Run gosmee for second controller (GHE)
324337
if: startsWith(matrix.provider, 'github_ghe') || matrix.provider == 'concurrency'
325338
run: |
@@ -366,7 +379,8 @@ jobs:
366379
TEST_GITHUB_SECOND_WEBHOOK_SECRET: ${{ secrets.TEST_GITHUB_SECOND_WEBHOOK_SECRET }}
367380
TEST_GITHUB_TOKEN: ${{ secrets.GH_APPS_TOKEN }}
368381
TEST_GITLAB_API_URL: https://gitlab.com
369-
TEST_GITLAB_PROJECT_ID: ${{ vars.TEST_GITLAB_PROJECT_ID }}
382+
TEST_GITLAB_GROUP: pac-e2e-tests
383+
TEST_GITLAB_SMEEURL: ${{ env.TEST_GITLAB_SMEEURL }}
370384
TEST_GITLAB_TOKEN: ${{ secrets.GITLAB_TOKEN }}
371385
TEST_PROVIDER: ${{ matrix.provider }}
372386
if: ${{ github.event_name == 'workflow_dispatch' && inputs.debug_enabled }}
@@ -466,6 +480,7 @@ jobs:
466480
if: ${{ always() }}
467481
env:
468482
TEST_GITHUB_SECOND_SMEE_URL: ${{ secrets.TEST_GITHUB_SECOND_SMEE_URL }}
483+
TEST_GITLAB_SMEEURL: ${{ steps.gosmee-gitlab-url.outputs.url }}
469484
run: |
470485
./hack/gh-workflow-ci.sh collect_logs
471486

hack/check-e2e-test-naming.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ if [[ ${#testfiles[@]} -eq 0 ]]; then
1717
exit 0
1818
fi
1919

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

2323
# Valid patterns: TestGithub*, TestGitea*, TestGitlab*, TestBitbucket*, TestOthers*, or *Concurrency*
2424
valid_pattern='^Test(Github|Gitea|Gitlab|Bitbucket|Others)|Concurrency'

hack/cleanup-gitlab-projects.py

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
#!/usr/bin/env -S uv --quiet run --script
2+
# /// script
3+
# requires-python = ">=3.12"
4+
# dependencies = [
5+
# "requests",
6+
# ]
7+
# ///
8+
"""Clean up GitLab projects older than a given number of days in a group.
9+
10+
Uses TEST_GITLAB_API_URL, TEST_GITLAB_TOKEN, and TEST_GITLAB_GROUP environment
11+
variables by default (same as the E2E test suite), but all values can be
12+
overridden via CLI flags.
13+
14+
Examples:
15+
# Dry-run (default) — show what would be deleted:
16+
./hack/cleanup-gitlab-projects.py
17+
18+
# Actually delete:
19+
./hack/cleanup-gitlab-projects.py --force
20+
21+
# Custom age threshold:
22+
./hack/cleanup-gitlab-projects.py --days 3 --force
23+
"""
24+
25+
import argparse
26+
import os
27+
import sys
28+
from datetime import datetime, timezone
29+
30+
import requests
31+
32+
33+
def get_projects(base_url: str, token: str, group: str) -> list[dict]:
34+
"""Return all projects in the given group, handling pagination."""
35+
headers = {"PRIVATE-TOKEN": token}
36+
url = f"{base_url}/api/v4/groups/{requests.utils.quote(group, safe='')}/projects"
37+
params: dict = {"per_page": 100, "page": 1, "include_subgroups": False}
38+
projects: list[dict] = []
39+
while True:
40+
resp = requests.get(url, headers=headers, params=params, timeout=30)
41+
resp.raise_for_status()
42+
batch = resp.json()
43+
if not batch:
44+
break
45+
projects.extend(batch)
46+
params["page"] += 1
47+
return projects
48+
49+
50+
def delete_project(base_url: str, token: str, project_id: int) -> None:
51+
headers = {"PRIVATE-TOKEN": token}
52+
url = f"{base_url}/api/v4/projects/{project_id}"
53+
resp = requests.delete(url, headers=headers, timeout=30)
54+
resp.raise_for_status()
55+
56+
57+
def main() -> None:
58+
parser = argparse.ArgumentParser(
59+
description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter
60+
)
61+
parser.add_argument(
62+
"--api-url",
63+
default=os.getenv("TEST_GITLAB_API_URL", "https://gitlab.pipelinesascode.com"),
64+
help="GitLab API base URL (default: $TEST_GITLAB_API_URL)",
65+
)
66+
parser.add_argument(
67+
"--token",
68+
default=os.getenv("TEST_GITLAB_TOKEN", ""),
69+
help="GitLab private token (default: $TEST_GITLAB_TOKEN)",
70+
)
71+
parser.add_argument(
72+
"--group",
73+
default=os.getenv("TEST_GITLAB_GROUP", "pac-e2e-tests"),
74+
help="GitLab group path (default: $TEST_GITLAB_GROUP)",
75+
)
76+
parser.add_argument(
77+
"--days",
78+
type=int,
79+
default=7,
80+
help="Delete projects older than this many days (default: 7)",
81+
)
82+
parser.add_argument(
83+
"--force",
84+
action="store_true",
85+
help="Actually delete projects (default is dry-run)",
86+
)
87+
args = parser.parse_args()
88+
89+
if not args.token:
90+
print(
91+
"ERROR: GitLab token is required. Set TEST_GITLAB_TOKEN or pass --token.",
92+
file=sys.stderr,
93+
)
94+
sys.exit(1)
95+
96+
base_url = args.api_url.rstrip("/")
97+
now = datetime.now(tz=timezone.utc)
98+
99+
print(f"Listing projects in group '{args.group}' on {base_url} ...")
100+
projects = get_projects(base_url, args.token, args.group)
101+
print(f"Found {len(projects)} project(s).")
102+
103+
to_delete = []
104+
for proj in projects:
105+
created = datetime.fromisoformat(proj["created_at"])
106+
age = now - created
107+
if age.days >= args.days:
108+
to_delete.append((proj, age))
109+
110+
if not to_delete:
111+
print(f"No projects older than {args.days} day(s). Nothing to do.")
112+
return
113+
114+
print(f"\n{len(to_delete)} project(s) older than {args.days} day(s):\n")
115+
for proj, age in to_delete:
116+
print(
117+
f" {proj['path_with_namespace']} (ID {proj['id']}, created {proj['created_at']}, {age.days}d old)"
118+
)
119+
120+
if not args.force:
121+
print("\nDry-run mode. Pass --force to delete these projects.")
122+
return
123+
124+
print()
125+
errors = 0
126+
for proj, age in to_delete:
127+
name = proj["path_with_namespace"]
128+
try:
129+
delete_project(base_url, args.token, proj["id"])
130+
print(f" Deleted {name} (ID {proj['id']})")
131+
except requests.HTTPError as exc:
132+
print(f" ERROR deleting {name}: {exc}", file=sys.stderr)
133+
errors += 1
134+
135+
deleted = len(to_delete) - errors
136+
print(f"\nDone. Deleted {deleted} project(s).", end="")
137+
if errors:
138+
print(f" {errors} error(s).", end="")
139+
print()
140+
141+
142+
if __name__ == "__main__":
143+
main()

hack/gh-workflow-ci.sh

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ set -exufo pipefail
55

66
export PAC_API_INSTRUMENTATION_DIR=/tmp/api-instrumentation
77
export TEST_GITLAB_API_URL=https://gitlab.pipelinesascode.com
8+
export TEST_GITLAB_GROUP=pac-e2e-tests
89

910
create_pac_github_app_secret() {
1011
# Read from environment variables instead of arguments
@@ -231,6 +232,7 @@ collect_logs() {
231232
# Read from environment variables (use default empty value for optional vars)
232233
local test_gitea_smee_url="${TEST_GITEA_SMEEURL:-}"
233234
local github_ghe_smee_url="${TEST_GITHUB_SECOND_SMEE_URL:-}"
235+
local test_gitlab_smee_url="${TEST_GITLAB_SMEEURL:-}"
234236

235237
mkdir -p /tmp/logs
236238
# Output logs to stdout so we can see via the web interface directly
@@ -244,6 +246,8 @@ collect_logs() {
244246
[[ -d /tmp/gosmee-replay-ghe ]] && cp -a /tmp/gosmee-replay-ghe /tmp/logs/gosmee/replay-ghe
245247
[[ -f /tmp/gosmee-main.log ]] && cp /tmp/gosmee-main.log /tmp/logs/gosmee/main.log
246248
[[ -f /tmp/gosmee-ghe.log ]] && cp /tmp/gosmee-ghe.log /tmp/logs/gosmee/ghe.log
249+
[[ -d /tmp/gosmee-replay-gitlab ]] && cp -a /tmp/gosmee-replay-gitlab /tmp/logs/gosmee/replay-gitlab
250+
[[ -f /tmp/gosmee-gitlab.log ]] && cp /tmp/gosmee-gitlab.log /tmp/logs/gosmee/gitlab.log
247251

248252
kubectl get pipelineruns -A -o yaml >/tmp/logs/pac-pipelineruns.yaml
249253
kubectl get repositories.pipelinesascode.tekton.dev -A -o yaml >/tmp/logs/pac-repositories.yaml
@@ -264,7 +268,7 @@ collect_logs() {
264268
cp -a ${PAC_API_INSTRUMENTATION_DIR} /tmp/logs/$(basename ${PAC_API_INSTRUMENTATION_DIR})
265269
fi
266270

267-
for url in "${test_gitea_smee_url}" "${github_ghe_smee_url}"; do
271+
for url in "${test_gitea_smee_url}" "${github_ghe_smee_url}" "${test_gitlab_smee_url}"; do
268272
[[ -z "${url}" ]] && continue
269273
find /tmp/logs -type f -exec grep -l "${url}" {} \; | xargs -r sed -i "s|${url}|SMEE_URL|g"
270274
done

test/README.md

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,9 @@ this repo should differ from the one which is configured as part of `TEST_GITHUB
4545
- `TEST_BITBUCKET_CLOUD_E2E_REPOSITORY` - Bitbucket Cloud repository (i.e. `project/repo`)
4646
- `TEST_BITBUCKET_CLOUD_TOKEN` - Bitbucket Cloud token
4747
- `TEST_GITLAB_API_URL` - Gitlab API URL i.e: `https://gitlab.com`
48-
- `TEST_GITLAB_PROJECT_ID` - Gitlab project ID (you can get it in the repo details/settings)
48+
- `TEST_GITLAB_GROUP` - Gitlab group/namespace where test projects will be created and deleted
4949
- `TEST_GITLAB_TOKEN` - Gitlab Token
50+
- `TEST_GITLAB_SMEEURL` - Smee URL for forwarding GitLab webhooks to the controller
5051
- `TEST_GITEA_API_URL` - URL where GITEA is running (i.e: [GITEA_HOST](http://localhost:3000))
5152
- `TEST_GITEA_SMEEURL` - URL of smee
5253
- `TEST_GITEA_PASSWORD` - set password as **pac**
@@ -62,6 +63,31 @@ this repo should differ from the one which is configured as part of `TEST_GITHUB
6263

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

66+
### YAML Configuration File
67+
68+
Instead of setting individual environment variables, you can use a YAML
69+
configuration file. Set `PAC_E2E_CONFIG` to the path of your config file:
70+
71+
```shell
72+
PAC_E2E_CONFIG=./test/e2e-config.yaml make test-e2e
73+
```
74+
75+
Copy the example file and fill in the values for the providers you want to test:
76+
77+
```shell
78+
cp test/e2e-config.yaml.example test/e2e-config.yaml
79+
# edit test/e2e-config.yaml with your values
80+
```
81+
82+
The YAML file groups settings by provider section (`common`, `github`,
83+
`github_enterprise`, `gitlab`, `gitea`, `bitbucket_cloud`,
84+
`bitbucket_server`). See `test/e2e-config.yaml.example` for the full list of
85+
fields.
86+
87+
Environment variables always take precedence over YAML values, so you can use
88+
the config file for base settings and override specific values via env vars
89+
(useful for CI secrets).
90+
6591
## Running
6692

6793
As long you have env variables set, you can just do a :
@@ -78,6 +104,52 @@ You can specify only a subsets of test to run with :
78104

79105
same goes for `TestGitlab` or other methods.
80106

107+
### Running GitLab tests manually
108+
109+
GitLab tests require a smee URL to forward webhooks from the external GitLab
110+
instance to your local controller (the same pattern as Gitea tests).
111+
112+
1. Create your own group on the GitLab instance
113+
(e.g. `https://gitlab.pipelinesascode.com`) to hold the temporary test
114+
projects. Each test run creates a project inside this group and deletes it
115+
on cleanup. Use `TEST_GITLAB_GROUP` to point to your group.
116+
117+
2. Generate a smee channel and start the gosmee client to forward webhooks to
118+
your controller:
119+
120+
```shell
121+
# Generate a new smee channel URL
122+
SMEE_URL=$(curl -s https://hook.pipelinesascode.com -o /dev/null -w '%{redirect_url}')
123+
124+
# Start forwarding webhooks to your controller
125+
gosmee client "${SMEE_URL}" "https://your-controller-url"
126+
```
127+
128+
3. Set the required environment variables (or use a
129+
[YAML config file](#yaml-configuration-file)):
130+
131+
```shell
132+
export TEST_GITLAB_API_URL=https://gitlab.pipelinesascode.com
133+
export TEST_GITLAB_TOKEN=<your-token>
134+
export TEST_GITLAB_GROUP=<your-group>
135+
export TEST_GITLAB_SMEEURL="${SMEE_URL}"
136+
export TEST_EL_URL=https://your-controller-url
137+
export TEST_EL_WEBHOOK_SECRET=<your-webhook-secret>
138+
```
139+
140+
4. Run the tests:
141+
142+
```shell
143+
cd test/; go test -tags=e2e -v -run TestGitlab .
144+
```
145+
146+
To clean up stale test projects (older than 7 days) left from previous runs:
147+
148+
```shell
149+
./hack/cleanup-gitlab-projects.py # dry-run
150+
./hack/cleanup-gitlab-projects.py --force # actually delete
151+
```
152+
81153
If you need to update the golden files in the end-to-end test, add the `-update` flag to the [go test](https://pkg.go.dev/cmd/go#hdr-Test_packages) command to refresh those files. First, run it if you expect the test output to change (or for a new test), then run it again without the flag to ensure everything is correct.
82154

83155
## Running nightly tests

0 commit comments

Comments
 (0)