Commit edec7642 authored by Pierre Smeyers's avatar Pierre Smeyers
Browse files

ci: support custom TBC group as an alternative CI/CD configuration

This change restores the working build for basic forking workflow on gitlab.com.
parent 57e9b667
Loading
Loading
Loading
Loading
Loading
+212 −0
Original line number Diff line number Diff line
# Alternative CI/CD configuration file when using TBC in a self-managed GitLab with a custom TBC root group (different from the default "to-be-continuous")
# ℹ️ The CI/CD configuration file can be selected in your project: Settings > CI/CD > General Pipelines > CI/CD Configuration File.
# ⚠️ Requires that the TBC_NAMESPACE variable be set as a server instance variable (recommended), group variable, or project variable.
include:
  # $TBC_NAMESPACE is a group variable; can be globally overridden
  # Docker template
  - component: "$CI_SERVER_FQDN/$TBC_NAMESPACE/docker/gitlab-ci-docker@8"
    inputs:
      healthcheck-disabled: true
      build-args: "--cache-ttl=6h"
      prod-publish-strategy: "auto"
      release-extra-tags: "latest \\g<major>.\\g<minor>\\g<build> \\g<major>\\g<build>"
  # Python template
  - component: "$CI_SERVER_FQDN/$TBC_NAMESPACE/python/gitlab-ci-python@9"
    inputs:
      image: "docker.io/library/python:3.13-slim"
      ruff-enabled: true
      publish-enabled: true
      semgrep-disabled: true
  # semantic-release template
  - component: $CI_SERVER_FQDN/$TBC_NAMESPACE/semantic-release/gitlab-ci-semrel@4
    inputs:
      # disable semrel for all synch'd repositories
      release-disabled: true
      auto-release-enabled: true

variables:
  VALID_GCP_OIDC_PROVIDER: $GCP_OIDC_PROVIDER
  VALID_GCP_OIDC_ACCOUNT: $GCP_OIDC_ACCOUNT
  PROXYPY_IMAGE: "docker.io/abhinavsingh/proxy.py:v2.4.3"

.test-scripts: &test-scripts |
  # BEGSCRIPT
  set -e

  function log_info() {
      echo -e "[\\e[1;94mINFO\\e[0m] $*"
  }

  function log_warn() {
      echo -e "[\\e[1;93mWARN\\e[0m] $*"
  }

  function log_error() {
      echo -e "[\\e[1;91mERROR\\e[0m] $*"
  }

  function fail() {
    log_error "$*"
    exit 1
  }

  function assert_eq() {
    local expected="$1"
    local actual="$2"
    local error_msg="$3"

    if [ "$expected" == "$actual" ]; then
      log_info "$expected == $actual"
      return 0
    else
      if [ -z "$error_msg" ]; then
        fail "$expected == $actual"
      else
        fail "$expected == $actual  msg: $error_msg"
      fi
      return 1
    fi
  }

  # ENDSCRIPT

.test-base:
  image: "docker.io/badouralix/curl-jq"
  stage: package-test
  variables:
    GCP_OIDC_AUD: $CI_SERVER_URL
  id_tokens:
    CI_JOB_JWT_V2:
      aud: "$CI_SERVER_URL"
  services:
    - name: "$DOCKER_SNAPSHOT_IMAGE"
      alias: "gcp-auth-provider"
  before_script:
    - !reference [.test-scripts]

test-ping:
  extends: .test-base
  script:
    # test: ping responds pong
    - |
      response_status=`curl -s -o "resp.txt" -w "%{http_code}" http://gcp-auth-provider/ping`
      assert_eq "200" $response_status
      assert_eq "pong" $(cat resp.txt)


# test: get token with implicit TBC env detection fails if no TBC variables are set (error 400)
test-token-no-tbc-vars-fails:
  extends: .test-base
  variables:
    GCP_OIDC_ACCOUNT: ""
    GCP_OIDC_PROVIDER: ""
  script:
    - |
      response_status=$(curl -s -o "resp.txt" -w "%{http_code}" "http://gcp-auth-provider/token")
      assert_eq "400" $response_status

# test: get token with implicit TBC env detection fails if missing CI_JOB_JWT_2 (error 401)
test-token-no-jwt-fails:
  extends: .test-base
  variables:
    GCP_OIDC_ACCOUNT: "invalid"
    GCP_OIDC_PROVIDER: "invalid"
  script:
    - |
      response_status=$(curl -s -o "resp.txt" -w "%{http_code}" "http://gcp-auth-provider/token")
      assert_eq "401" $response_status

# test: get token with invalid OIDC account fails with 500
test-token-invalid-oidc-fails:
  extends: .test-base
  variables:
    GCP_OIDC_ACCOUNT: "invalid"
    GCP_OIDC_PROVIDER: "invalid"
    CI_JOB_JWT_V2: $CI_JOB_JWT_V2
  script:
    - |
      response_status=$(curl -s -o "resp.txt" -w "%{http_code}" "http://gcp-auth-provider/token")
      assert_eq "500" $response_status

# test: get token with valid OIDC account and provider shall succeed
test-token-succeeds:
  extends: .test-base
  variables:
    CI_JOB_JWT_V2: $CI_JOB_JWT_V2
    FF_NETWORK_PER_BUILD: 1
  services:
    - name: "$DOCKER_SNAPSHOT_IMAGE"
      alias: "gcp-auth-provider"
      variables:
        GCP_OIDC_PROVIDER: $VALID_GCP_OIDC_PROVIDER
        GCP_OIDC_ACCOUNT: $VALID_GCP_OIDC_ACCOUNT
  script:
    - |
      response_status=$(curl -s -o "resp.txt" -w "%{http_code}" "http://gcp-auth-provider/token")
      assert_eq "200" $response_status "$(cat resp.txt)"
      token=$(cat resp.txt)

      response_status=$(curl -s -o resp.txt -w "%{http_code}" -H "Authorization: Bearer $token" "https://cloudresourcemanager.googleapis.com/v1/projects/$GCP_PROJECT")
      assert_eq "200" $response_status
      project_id_result=$(cat resp.txt | jq -r .projectId)
      assert_eq "$GCP_PROJECT" $project_id_result
  rules:
    - if: $CI_SERVER_HOST != "gitlab.com"
      when: never
    - if: '$GCP_OIDC_ACCOUNT && $GCP_OIDC_PROVIDER'

# test: get token with valid OIDC account and provider through proxy shall succeed
test-token-with-proxy-succeeds:
  extends: test-token-succeeds
  services:
    - name: "$DOCKER_SNAPSHOT_IMAGE"
      alias: "gcp-auth-provider"
      variables:
        GCP_OIDC_PROVIDER: $VALID_GCP_OIDC_PROVIDER
        GCP_OIDC_ACCOUNT: $VALID_GCP_OIDC_ACCOUNT
        https_proxy: "http://proxy:8899"
    - name: "$PROXYPY_IMAGE"
      alias: "proxy"

# test: get token with valid OIDC with proxy not available should fail
test-token-with-proxy-unavail-fails:
  extends: test-token-succeeds
  services:
    - name: "$DOCKER_SNAPSHOT_IMAGE"
      alias: "gcp-auth-provider"
      variables:
        GCP_OIDC_PROVIDER: $VALID_GCP_OIDC_PROVIDER
        GCP_OIDC_ACCOUNT: $VALID_GCP_OIDC_ACCOUNT
        https_proxy: "http://no-proxy-host"
  script:
    - |
      response_status=$(curl -s -o "resp.txt" -w "%{http_code}" "http://gcp-auth-provider/token")
      assert_eq "500" $response_status "$(cat resp.txt)"

# test: get token without serviceaccount (direct resource access) account and provider shall succeed
test-token-without-serviceaccount-succeeds:
  extends: .test-base
  variables:
    CI_JOB_JWT_V2: $CI_JOB_JWT_V2
    FF_NETWORK_PER_BUILD: 1
  id_tokens:
    CI_JOB_JWT_V2:
      aud: https://iam.googleapis.com/projects/${GCP_PROJECT_NUMBER_WO_SA}/locations/global/workloadIdentityPools/gitlab/providers/gitlab
  services:
    - name: "$DOCKER_SNAPSHOT_IMAGE"
      alias: "gcp-auth-provider"
      variables:
        GCP_OIDC_PROVIDER: projects/${GCP_PROJECT_NUMBER_WO_SA}/locations/global/workloadIdentityPools/gitlab/providers/gitlab
        GCP_OIDC_ACCOUNT: ""
  script:
    - |
      response_status=$(curl -s -o "resp.txt" -w "%{http_code}" "http://gcp-auth-provider/token")
      assert_eq "200" $response_status "$(cat resp.txt)"
      token=$(cat resp.txt)

      response_status=$(curl -s -o resp.txt -w "%{http_code}" -H "Authorization: Bearer $token" "https://cloudresourcemanager.googleapis.com/v1/projects/$GCP_PROJECT_WO_SA")
      assert_eq "200" $response_status
      project_id_result=$(cat resp.txt | jq -r .projectId)
      assert_eq "$GCP_PROJECT_WO_SA" $project_id_result
  rules:
    - if: '$GCP_PROJECT_WO_SA && $GCP_PROJECT_NUMBER_WO_SA'
+5 −6
Original line number Diff line number Diff line
# Default CI/CD configuration file
# ℹ️ If you're using TBC in a self-managed GitLab with a custom TBC root group, use .gitlab-ci-namespaced.yml instead
include:
  # $TBC_NAMESPACE is a group variable; can be globally overridden
  # Docker template
  - component: "$CI_SERVER_FQDN/$TBC_NAMESPACE/docker/gitlab-ci-docker@8"
  - component: "$CI_SERVER_FQDN/to-be-continuous/docker/gitlab-ci-docker@8"
    inputs:
      healthcheck-disabled: true
      build-args: "--cache-ttl=6h"
      prod-publish-strategy: "auto"
      release-extra-tags: "latest \\g<major>.\\g<minor>\\g<build> \\g<major>\\g<build>"
  # Python template
  - component: "$CI_SERVER_FQDN/$TBC_NAMESPACE/python/gitlab-ci-python@9"
  - component: "$CI_SERVER_FQDN/to-be-continuous/python/gitlab-ci-python@9"
    inputs:
      image: "docker.io/library/python:3.13-slim"
      ruff-enabled: true
      publish-enabled: true
      semgrep-disabled: true
  # semantic-release template
  - component: $CI_SERVER_FQDN/$TBC_NAMESPACE/semantic-release/gitlab-ci-semrel@4
  - component: $CI_SERVER_FQDN/to-be-continuous/semantic-release/gitlab-ci-semrel@4
    inputs:
      # disable semrel for all synch'd repositories
      release-disabled: true
      auto-release-enabled: true

variables:
  # Default value; can be globally overridden
  TBC_NAMESPACE: "to-be-continuous"
  VALID_GCP_OIDC_PROVIDER: $GCP_OIDC_PROVIDER
  VALID_GCP_OIDC_ACCOUNT: $GCP_OIDC_ACCOUNT
  PROXYPY_IMAGE: "docker.io/abhinavsingh/proxy.py:v2.4.3"