Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
dc70565
fix(e2e): restore readiness gates for runtime, auth, and localization
schultzp2020 Jul 10, 2026
1e24cec
fix(e2e): satisfy oxlint and regenerate rulesync outputs
schultzp2020 Jul 10, 2026
09252c3
style(e2e): oxfmt instance-readiness unit test
schultzp2020 Jul 10, 2026
64937f5
fix(e2e): repair auth yaml paths and operator runtime readiness
schultzp2020 Jul 10, 2026
e4d0a0c
fix(e2e): allow auth config updates before first deploy
schultzp2020 Jul 10, 2026
782e62d
refactor(e2e): rename continue param to continueToken
schultzp2020 Jul 10, 2026
b280702
fix(e2e): poll for auth deployment until operator creates it
schultzp2020 Jul 10, 2026
2d08fba
refactor(e2e): share operator install profiles for auth readiness
schultzp2020 Jul 10, 2026
a5f2199
fix(e2e): harden auth readiness after architecture review
schultzp2020 Jul 10, 2026
7235b18
fix(e2e): bind auth harness URL into worker-scoped Playwright context
schultzp2020 Jul 11, 2026
7056fde
fix(e2e): deepen route identity, readiness, auth shell, and tunnels
schultzp2020 Jul 13, 2026
276eac5
fix(e2e): harden auth-provider sync, cookies, and IdP flows
schultzp2020 Jul 13, 2026
698d22f
fix(e2e): prove auth config is live after reconcile
schultzp2020 Jul 13, 2026
443eae5
fix(e2e): harden auth reconcile liveness and login outcomes
schultzp2020 Jul 13, 2026
53d25d9
fix(e2e): keep healthcheck polling through Route timeouts
schultzp2020 Jul 14, 2026
8ba127c
fix(e2e): fix auth negative asserts and cut worker-redeploy cost
schultzp2020 Jul 14, 2026
3024fe9
fix(e2e): isolate sessionDuration resolvers and upsert reuse secrets
schultzp2020 Jul 14, 2026
fd638a6
fix(e2e): drop hard main gate and retry aborted post-reconcile naviga…
schultzp2020 Jul 15, 2026
8034de6
fix(e2e): settle role=progressbar, narrow abort retries, wrap ConfigM…
schultzp2020 Jul 15, 2026
649c386
fix(e2e): harden OIDC autologout isolation and reconcile k8s errors
schultzp2020 Jul 15, 2026
383c3e0
fix(ci): pin empty flavours and wait out S2I whitespace images
schultzp2020 Jul 15, 2026
764c80b
fix(ci): disable lightspeed inherit and poll catalog ingestion
schultzp2020 Jul 16, 2026
ba327e0
fix(e2e): fail-fast catalog polls and use enabled:false for lightspeed
schultzp2020 Jul 16, 2026
f88a569
test(e2e): add opt-in Cloud SQL Auth Proxy runtime coverage
zdrapela Jul 23, 2026
63e36b6
test(e2e): drop Cloud SQL DB CA PEM usage
zdrapela Jul 23, 2026
c9be607
fix(e2e): harden Cloud SQL Helm overlay and release targeting
zdrapela Jul 23, 2026
140b82e
fix(e2e): apply Cloud SQL Helm overlay without --wait
zdrapela Jul 23, 2026
74d9bce
fix(e2e): enable Helm runtime homepage for Welcome verify
zdrapela Jul 24, 2026
1741ead
fix(e2e): keep Helm default dynamic includes with homepage
zdrapela Jul 24, 2026
ded21b7
chore(e2e): rebuild PR image after hermetic PyPI timeout
zdrapela Jul 24, 2026
ba499e3
test(e2e): scope Cloud SQL Auth Proxy coverage to Helm
zdrapela Jul 27, 2026
7cac6ea
merge(main): resolve conflicts for Cloud SQL Helm PR
zdrapela Jul 27, 2026
fae7ec0
test(e2e): use Cloud SQL server CA for clearDatabase like RDS/Azure
zdrapela Jul 27, 2026
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
15 changes: 15 additions & 0 deletions .ci/pipelines/env_variables.sh
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,21 @@ AZURE_DB_4_HOST=$(cat /tmp/secrets/AZURE_DB_4_HOST)
# Store paths instead of content to avoid "Argument list too long" shell errors
RDS_DB_CERTIFICATES_PATH="/tmp/secrets/rds-db-certificates.pem"
AZURE_DB_CERTIFICATES_PATH="/tmp/secrets/azure-db-certificates.pem"
## Google Cloud SQL credentials (Vault-populated in CI)
## Auth Proxy sidecar uses instance connection names (project:region:instance).
## Public hosts + server CA PEM are used for clearDatabase (same as RDS/Azure).
CLOUDSQL_USER=$(cat /tmp/secrets/CLOUDSQL_USER 2> /dev/null || true)
CLOUDSQL_PASSWORD=$(cat /tmp/secrets/CLOUDSQL_PASSWORD 2> /dev/null || true)
CLOUDSQL_INSTANCE_1=$(cat /tmp/secrets/CLOUDSQL_INSTANCE_1 2> /dev/null || true)
CLOUDSQL_INSTANCE_2=$(cat /tmp/secrets/CLOUDSQL_INSTANCE_2 2> /dev/null || true)
CLOUDSQL_INSTANCE_3=$(cat /tmp/secrets/CLOUDSQL_INSTANCE_3 2> /dev/null || true)
CLOUDSQL_INSTANCE_4=$(cat /tmp/secrets/CLOUDSQL_INSTANCE_4 2> /dev/null || true)
CLOUDSQL_1_HOST=$(cat /tmp/secrets/CLOUDSQL_1_HOST 2> /dev/null || true)
CLOUDSQL_2_HOST=$(cat /tmp/secrets/CLOUDSQL_2_HOST 2> /dev/null || true)
CLOUDSQL_3_HOST=$(cat /tmp/secrets/CLOUDSQL_3_HOST 2> /dev/null || true)
CLOUDSQL_4_HOST=$(cat /tmp/secrets/CLOUDSQL_4_HOST 2> /dev/null || true)
CLOUDSQL_DB_CERTIFICATES_PATH="/tmp/secrets/cloudsql-db-certificates.pem"
CLOUDSQL_SERVICE_ACCOUNT_JSON_PATH="/tmp/secrets/cloudsql-service-account.json"

JUNIT_RESULTS="junit-results.xml"

Expand Down
4 changes: 3 additions & 1 deletion .ci/pipelines/jobs/auth-providers.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,7 @@ handle_auth_providers() {
export LOGS_FOLDER

log::info "Running tests ${AUTH_PROVIDERS_RELEASE} in ${AUTH_PROVIDERS_NAMESPACE}"
testing::run_tests "${AUTH_PROVIDERS_RELEASE}" "${AUTH_PROVIDERS_NAMESPACE}" "${PW_PROJECT_SHOWCASE_AUTH_PROVIDERS}" "https://${K8S_CLUSTER_ROUTER_BASE}" || true
# The auth-provider harness deploys its own test instance, so leave BASE_URL
# unset and let Playwright global setup no-op instead of probing the router.
testing::run_tests "${AUTH_PROVIDERS_RELEASE}" "${AUTH_PROVIDERS_NAMESPACE}" "${PW_PROJECT_SHOWCASE_AUTH_PROVIDERS}" "" || true
}
16 changes: 9 additions & 7 deletions .ci/pipelines/jobs/ocp-nightly.sh
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,11 @@ run_standard_deployment_tests() {
}

run_runtime_config_change_tests() {
# Runtime tests handle their own deployment via TypeScript (runtime-deploy.ts).
# The first test file (config-map.spec.ts) calls ensureRuntimeDeployed() which:
# - Creates the namespace
# - Deploys RHDH with Helm + internal PostgreSQL sub-chart
# - Configures schema-mode env vars for port-forwarding
# Runtime tests self-deploy from Playwright global setup when
# RUNTIME_AUTO_DEPLOY=true. Pass the predicted route as BASE_URL so
# playwright.config.ts freezes a usable use.baseURL before globalSetup
# (Playwright resolves config before globalSetup runs). globalSetup then
# deploys via ensureRuntimeDeployed() and healthchecks that URL.
# Subsequent test files reuse the existing deployment (workers: 1).
#
# The CI wrapper only needs to set environment variables and invoke Playwright.
Expand All @@ -62,9 +62,11 @@ run_runtime_config_change_tests() {
# deploy branch was skipped and global-setup instead polled a route that
# nothing had created yet - failing after 120s before any test could run.
# ensureRuntimeDeployed() sets BASE_URL itself once the route exists.
#
# Scope RUNTIME_AUTO_DEPLOY to this invocation only — a lasting export would
# leak into later projects (e.g. sanity-plugins) and stomp BASE_URL.
export INSTALL_METHOD="helm"
export RUNTIME_AUTO_DEPLOY="true"
testing::run_tests "${RELEASE_NAME}" "${NAME_SPACE_RUNTIME}" "${PW_PROJECT_SHOWCASE_RUNTIME}" || true
RUNTIME_AUTO_DEPLOY=true testing::run_tests "${RELEASE_NAME}" "${NAME_SPACE_RUNTIME}" "${PW_PROJECT_SHOWCASE_RUNTIME}" || true
}

run_sanity_plugins_check() {
Expand Down
15 changes: 8 additions & 7 deletions .ci/pipelines/jobs/ocp-operator.sh
Original file line number Diff line number Diff line change
Expand Up @@ -68,20 +68,21 @@ initiate_operator_deployments_osd_gcp() {
}

run_operator_runtime_config_change_tests() {
# Runtime tests handle their own deployment via TypeScript (runtime-deploy.ts).
# The first test file (config-map.spec.ts) calls ensureRuntimeDeployed() which:
# - Creates the namespace
# - Deploys RHDH via the operator with internal PostgreSQL
# - Configures schema-mode env vars for port-forwarding
# Runtime tests self-deploy from Playwright global setup when
# RUNTIME_AUTO_DEPLOY=true. Pass the predicted route as BASE_URL so
# playwright.config.ts freezes a usable use.baseURL before globalSetup.
# globalSetup then deploys via ensureRuntimeDeployed() and healthchecks.
# Subsequent test files reuse the existing deployment (workers: 1).
#
# INSTALL_METHOD=operator is already exported in handle_ocp_operator().
#
# No URL is passed on purpose - see the same note in jobs/ocp-nightly.sh.
# A pre-set BASE_URL makes global-setup.ts skip the deploy branch and poll a
# route nothing has created yet; ensureRuntimeDeployed() sets BASE_URL itself.
export RUNTIME_AUTO_DEPLOY="true"
testing::run_tests "${RELEASE_NAME}" "${NAME_SPACE_RUNTIME}" "${PW_PROJECT_SHOWCASE_RUNTIME}" || true
#
# Scope RUNTIME_AUTO_DEPLOY to this invocation only — a lasting export would
# leak into later jobs and stomp BASE_URL.
RUNTIME_AUTO_DEPLOY=true testing::run_tests "${RELEASE_NAME}" "${NAME_SPACE_RUNTIME}" "${PW_PROJECT_SHOWCASE_RUNTIME}" || true
}

handle_ocp_operator() {
Expand Down
4 changes: 4 additions & 0 deletions .ci/pipelines/resources/rhdh-operator/rhdh-start-rbac.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,7 @@ spec:
configMaps:
- name: rbac-policy
mountPath: /opt/app-root/src/rbac
# Disable default flavours (e.g. lightspeed) so install-dynamic-plugins
# cannot CrashLoop on operator-injected OCI pulls — same invariant as
# OperatorInstallProfile for Playwright-generated CRs.
flavours: []
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,7 @@ spec:
configMaps:
- name: rbac-policy
mountPath: /opt/app-root/src/rbac
# Disable default flavours (e.g. lightspeed) so install-dynamic-plugins
# cannot CrashLoop on operator-injected OCI pulls — same invariant as
# OperatorInstallProfile for Playwright-generated CRs.
flavours: []
4 changes: 4 additions & 0 deletions .ci/pipelines/resources/rhdh-operator/rhdh-start.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,7 @@ spec:
secrets:
- name: rhdh-secrets
- name: redis-secret
# Disable default flavours (e.g. lightspeed) so install-dynamic-plugins
# cannot CrashLoop on operator-injected OCI pulls — same invariant as
# OperatorInstallProfile for Playwright-generated CRs.
flavours: []
4 changes: 4 additions & 0 deletions .ci/pipelines/resources/rhdh-operator/rhdh-start_K8s.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,7 @@ spec:
secrets:
- name: rhdh-secrets
- name: redis-secret
# Disable default flavours (e.g. lightspeed) so install-dynamic-plugins
# cannot CrashLoop on operator-injected OCI pulls — same invariant as
# OperatorInstallProfile for Playwright-generated CRs.
flavours: []
78 changes: 72 additions & 6 deletions .ci/pipelines/utils.sh
Original file line number Diff line number Diff line change
Expand Up @@ -357,23 +357,89 @@ apply_yaml_files() {

deploy_test_backstage_customization_provider() {
local project=$1
log::info "Deploying test-backstage-customization-provider in namespace ${project}"
local app_name="test-backstage-customization-provider"
log::info "Deploying ${app_name} in namespace ${project}"

# Check if the buildconfig already exists
if ! oc get buildconfig test-backstage-customization-provider -n "${project}" > /dev/null 2>&1; then
if ! oc get buildconfig "${app_name}" -n "${project}" > /dev/null 2>&1; then
# Get latest nodejs UBI9 tag from cluster, fallback to 18-ubi8
local nodejs_tag
nodejs_tag=$(oc get imagestream nodejs -n openshift -o jsonpath='{.spec.tags[*].name}' 2> /dev/null \
| tr ' ' '\n' | grep -E '^[0-9]+-ubi9$' | sort -t'-' -k1 -n | tail -1)
nodejs_tag="${nodejs_tag:-18-ubi8}"
log::info "Creating new app for test-backstage-customization-provider using nodejs:${nodejs_tag}"
log::info "Creating new app for ${app_name} using nodejs:${nodejs_tag}"
oc new-app "openshift/nodejs:${nodejs_tag}~https://github.com/janus-qe/test-backstage-customization-provider" --namespace="${project}"
else
log::warn "BuildConfig for test-backstage-customization-provider already exists in ${project}. Skipping new-app creation."
log::warn "BuildConfig for ${app_name} already exists in ${project}. Skipping new-app creation."
fi

log::info "Exposing service for test-backstage-customization-provider"
oc expose svc/test-backstage-customization-provider --namespace="${project}"
# oc new-app creates a Deployment whose first ReplicaSet often has image " "
# until the S2I build finishes. Fail closed until a Complete build exists and
# the Deployment image is non-whitespace. Skip the build wait when a prior
# successful deploy already left a real image (builds may have been pruned).
local image image_trimmed
image=$(oc get "deployment/${app_name}" -n "${project}" \
-o jsonpath='{.spec.template.spec.containers[0].image}' 2> /dev/null || true)
image_trimmed="${image//[[:space:]]/}"
if [[ -n "${image_trimmed}" ]]; then
log::info "${app_name} already has image '${image_trimmed}'; waiting for rollout only"
oc rollout status "deployment/${app_name}" -n "${project}" --timeout=300s
else
log::info "Waiting for ${app_name} build to appear in ${project}"
local latest_build=""
local attempt
for ((attempt = 1; attempt <= 60; attempt++)); do
latest_build=$(oc get builds -n "${project}" -l "buildconfig=${app_name}" \
--sort-by=.metadata.creationTimestamp \
-o jsonpath='{.items[-1:].metadata.name}' 2> /dev/null || true)
if [[ -n "${latest_build}" ]]; then
break
fi
sleep 5
done
if [[ -z "${latest_build}" ]]; then
log::error "No ${app_name} build appeared in ${project} within 300s"
return 1
fi

log::info "Waiting for build/${latest_build} to Complete in ${project}"
local build_phase=""
for ((attempt = 1; attempt <= 120; attempt++)); do
build_phase=$(oc get "build/${latest_build}" -n "${project}" \
-o jsonpath='{.status.phase}' 2> /dev/null || echo "")
if [[ "${build_phase}" == "Complete" ]]; then
break
fi
if [[ "${build_phase}" == "Failed" || "${build_phase}" == "Error" || "${build_phase}" == "Cancelled" ]]; then
log::error "Build ${latest_build} ended in phase ${build_phase}"
oc logs "build/${latest_build}" -n "${project}" --tail=50 || true
return 1
fi
sleep 5
done
if [[ "${build_phase}" != "Complete" ]]; then
log::error "Timed out waiting for build/${latest_build} (last phase: ${build_phase:-unknown})"
return 1
fi

log::info "Waiting for ${app_name} deployment to roll out in ${project}"
oc rollout status "deployment/${app_name}" -n "${project}" --timeout=300s

image=$(oc get "deployment/${app_name}" -n "${project}" \
-o jsonpath='{.spec.template.spec.containers[0].image}' 2> /dev/null || true)
image_trimmed="${image//[[:space:]]/}"
if [[ -z "${image_trimmed}" ]]; then
log::error "${app_name} deployment still has empty/whitespace image: '${image}'"
return 1
fi
fi

if ! oc get route "${app_name}" -n "${project}" > /dev/null 2>&1; then
log::info "Exposing service for ${app_name}"
oc expose svc/"${app_name}" --namespace="${project}"
else
log::info "Route for ${app_name} already exists in ${project}"
fi
}

deploy_redis_cache() {
Expand Down
8 changes: 8 additions & 0 deletions .ci/pipelines/value_files/values_showcase-rbac.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,14 @@ global:
rbac:
parent: default.admin
icon: rbacIcon

# Disable chart/operator-injected lightspeed plugins ({{inherit}} cannot resolve
# against the catalog index). Restores #4791 after it was dropped in #4869.
- package: 'oci://registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-lightspeed:{{ "{{" }}inherit{{ "}}" }}'
enabled: false
- package: 'oci://registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-lightspeed-backend:{{ "{{" }}inherit{{ "}}" }}'
enabled: false

# -- Upstream Backstage [chart configuration](https://github.com/backstage/charts/blob/main/charts/backstage/values.yaml)
# @default -- Use Openshift compatible settings
upstream:
Expand Down
8 changes: 8 additions & 0 deletions .ci/pipelines/value_files/values_showcase.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,14 @@ global:
- package: "@backstage-community/plugin-todo@0.2.42"
enabled: true
integrity: sha512-agmfwxHkZPy0zaXzjMKY9Us9l7J2og+z7p2lDWQBmlJ1KZRo6OBQdnlG1mTEryfEEl/bx5Ko+f1PhFj2/BmiIQ==

# Disable chart/operator-injected lightspeed plugins ({{inherit}} cannot resolve
# against the catalog index). Restores #4791 after it was dropped in #4869.
- package: 'oci://registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-lightspeed:{{ "{{" }}inherit{{ "}}" }}'
enabled: false
- package: 'oci://registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-lightspeed-backend:{{ "{{" }}inherit{{ "}}" }}'
enabled: false

# -- Upstream Backstage [chart configuration](https://github.com/backstage/charts/blob/main/charts/backstage/values.yaml)
upstream:
nameOverride: developer-hub
Expand Down
Loading
Loading