Skip to content

GitHub Integration

Overview

GitHub Integration eliminates the need to manage long-lived secrets or tokens in your CI/CD pipelines. It securely links your GitHub repository and a Google Service Account (GSA) that can authenticate to your Kubernetes namespace.

There are two ways to manage these connections:

  • Cloud Console (Recommended) — Use the JetBrains Cloud Console interface to easily connect repositories and automatically provision the necessary GCP identities.
  • Manual Configuration — Define GitHubConnection custom resources directly via kubectl or the IntelliJ K8s Plugin.

How It Works

You can read the detailed description in GHC design documentation. In short, the integration establishes a trust relationship between GitHub and Cloud Provider:

  1. Link Repository — You define which repository and which branches and environments can access your namespace.
  2. Automated Provisioning — The controller creates a GSA and configures the OIDC trust.
  3. OIDC Flow — During a GitHub Action run, GitHub generates a JWT token which GCP verifies to issue temporary credentials.
  4. Deployment — Your workflow uses these credentials to deploy directly to GKE, EKS, or on-premise clusters.

Using the Cloud Console

The Cloud Console provides a visual interface for managing your GitHub connections. This is the recommended method as it automates the complex configuration of identities.

Creating GitHub Connection

  1. Open the GitHub Integration page in the JetBrains Cloud Console.

  1. Click + CONNECT REPOSITORY to open the connection wizard.

  2. Enter repository GitHub url for automatic ID detection or enter GitHub Organization and repository IDs manually.

  1. Configure the Deployment Triggers:

  2. Allowed Branches — Specify which branches (e.g., main, staging).

  3. Allowed Github Environments — Use GitHub Environments (e.g., production) for deployment control.

  4. Click Preview. Review your connection details and proceed further or return back to editing.

  1. Click Set up. It will take up to 30 seconds to provision the resources.

  1. Once the status is Ready, select your deployment strategy, follow the instructions, and use the generated workflow config.


Note: A separate RBAC user with Administrator permissions will be automatically added to your namespace to enable deployments. Learn more.

Managing Connected Repositories

Once a repository is connected, it appears in the GitHub Deployments list. This section provides an overview of all active connections in your current namespace and allows you to monitor and manage them.

Each repository card displays a status indicator:

  • 🟢 Connected — The connection is active and ready for deployment.
  • 🟡 Setting up — Resources are being provisioned (typically takes ~30 seconds).
  • 🔴 Error — There was an error during setup (e.g., repository not found or permission denied).

Viewing Deployment Configuration

Click on a repository card to open the Workflow Config.

There you can access the generated skaffold-based or direct deployment configurations for GitHub Actions. You can read more about deployment types in the following section.

It's available to Copy the snippet directly or Download the file:

From the repository list view, you can navigate directly to the GitHub Actions page of repository to start deploying.

Editing Connected Repositories

Once created, you can edit your connection, by adding new repositories or editing existing ones.

Deployment Strategies

The Cloud Console generates a ready-to-use GitHub Action workflow based on your deployment strategy.

Using Skaffold (Automated Build & Deploy)

This method uses a reusable JetBrains workflow that handles image building, pushing to a registry (GHCR), and deploying to the cluster using Skaffold.

  • When to choose: Recommended for most projects. Handles build, push, and deploy in one step.
  • Permissions required: packages: write (image push to GHCR) and id-token: write (OIDC auth).
  • Reusable workflows: gke-skaffold.yaml (GKE clusters) or skaffold.yaml (other clusters).

Required files in your repository:

skaffold.yaml:

apiVersion: skaffold/v4beta8
kind: Config
metadata:
  name: my-app
build:
  tagPolicy:
    sha256: {}
  artifacts:
    - image: ghcr.io/jetbrains/<your-repo-name>   # GHCR, not registry.jetbrains.team
      docker: {}
  local:
    useDockerCLI: false
    useBuildkit: true
deploy:
  helm:
    releases:
      - name: my-app
        remoteChart: oci://ghcr.io/jetbrains/sre-helm-charts/simple-app
        version: 0.3.4
        namespace: <your-namespace>       # must match your Cloud Console namespace
        upgradeOnChange: true
        setValueTemplates:
          image: "{{.IMAGE_FULLY_QUALIFIED}}"
          imagePullSecret: "{{.IMAGE_PULL_SECRET}}"
          applicationName: "{{.APPLICATION_NAME}}"
        valuesFiles:
          - values.yaml
profiles:
  - name: prod

values.yaml:

containerPort: 8080
imagePullSecret: null   # required when using GHCR — chart default expects Space registry secret

Multi-module projects: If your repo has sub-projects (e.g., /front and /back), set context: in the GitHub Actions workflow to point to the correct subdirectory.

Direct Kubernetes Manifests (Manual)

This method gives you full control over the deployment steps, manually running kubectl apply with your own manifests.

  • When to choose: Ideal if you don't use Skaffold or need custom logic between authentication and deployment.
  • Key Features:
  • Granular Control: Explicitly define each step of the authentication and deployment process.
  • Flexibility: Easily integrate custom scripts or third-party tools.
  • Permissions: Requires id-token: write for OIDC authentication.
  • Steps Breakdown:
  • Authenticate to GCP: Uses the Identity Provider and Service Account from the Cloud Console.
  • Set up Cloud SDK: Installs the gcloud CLI and kubectl.
  • Get cluster credentials: Configures kubectl using the --dns-endpoint flag for secure cluster access.
  • Deploy: Runs kubectl apply -f k8s/ to apply manifests from your repository's k8s/ folder.

Common Issues

unauthorized: authentication required when pushing image

You're using registry.jetbrains.team (Space registry) as your image destination. The GitHub Actions workflow does not have credentials for Space registry.

Fix: Use GitHub Container Registry instead:

# skaffold.yaml
build:
  artifacts:
    - image: ghcr.io/jetbrains/<your-repo-name>

The gke-skaffold.yaml reusable workflow handles GHCR authentication automatically via GITHUB_TOKEN.


403 Forbidden when pulling Helm chart from Space

The Helm chart registry.jetbrains.team/p/cb/helm-charts/simple-app is hosted in Space and is not accessible from GitHub Actions.

Fix: Use the chart from GHCR instead:

# skaffold.yaml
deploy:
  helm:
    releases:
      - remoteChart: oci://ghcr.io/jetbrains/sre-helm-charts/simple-app
        version: 0.3.4

resource name may not be empty / deploys to default namespace

Missing namespace: in skaffold.yaml. Without it, Helm tries to install into the default namespace which has no ServiceAccount set up.

Fix: Add namespace: explicitly to every Helm release, and set imagePullSecret: null in values.yaml (the chart defaults expect a Space registry secret which doesn't exist with GHCR):

# skaffold.yaml
apiVersion: skaffold/v4beta8
kind: Config
metadata:
  name: my-app
build:
  tagPolicy:
    sha256: {}
  artifacts:
    - image: ghcr.io/jetbrains/<your-repo-name>
      docker: {}
  local:
    useDockerCLI: false
    useBuildkit: true
deploy:
  helm:
    releases:
      - name: my-app
        remoteChart: oci://ghcr.io/jetbrains/sre-helm-charts/simple-app
        version: 0.3.4
        namespace: <your-namespace>        # ← required
        upgradeOnChange: true
        setValueTemplates:
          image: "{{.IMAGE_FULLY_QUALIFIED}}"
          imagePullSecret: "{{.IMAGE_PULL_SECRET}}"
          applicationName: "{{.APPLICATION_NAME}}"
        valuesFiles:
          - values.yaml
profiles:
  - name: prod
# values.yaml
containerPort: 8080
imagePullSecret: null   # ← required when using GHCR instead of Space registry