Skip to main content
Redhat Developers  Logo
  • Products

    Platforms

    • Red Hat Enterprise Linux
      Red Hat Enterprise Linux Icon
    • Red Hat AI
      Red Hat AI
    • Red Hat OpenShift
      Openshift icon
    • Red Hat Ansible Automation Platform
      Ansible icon
    • See all Red Hat products

    Featured

    • Red Hat build of OpenJDK
    • Red Hat Developer Hub
    • Red Hat JBoss Enterprise Application Platform
    • Red Hat OpenShift Dev Spaces
    • Red Hat OpenShift Local
    • Red Hat Developer Sandbox

      Try Red Hat products and technologies without setup or configuration fees for 30 days with this shared Red Hat OpenShift and Kubernetes cluster.
    • Try at no cost
  • Technologies

    Featured

    • AI/ML
      AI/ML Icon
    • Linux
      Linux Icon
    • Kubernetes
      Cloud icon
    • Automation
      Automation Icon showing arrows moving in a circle around a gear
    • See all technologies
    • Programming languages & frameworks

      • Java
      • Python
      • JavaScript
    • System design & architecture

      • Red Hat architecture and design patterns
      • Microservices
      • Event-Driven Architecture
      • Databases
    • Developer experience

      • Productivity
      • Tools
      • GitOps
    • Automated data processing

      • AI/ML
      • Data science
      • Apache Kafka on Kubernetes
    • Platform engineering

      • DevOps
      • DevSecOps
      • Red Hat Ansible Automation Platform for applications and services
    • Secure development & architectures

      • Security
      • Secure coding
  • Learn

    Featured

    • Kubernetes & cloud native
      Openshift icon
    • Linux
      Rhel icon
    • Automation
      Ansible cloud icon
    • AI/ML
      AI/ML Icon
    • See all learning resources

    E-books

    • GitOps cookbook
    • Podman in action
    • Kubernetes operators
    • The path to GitOps
    • See all e-books

    Cheat sheets

    • Linux commands
    • Bash commands
    • Git
    • systemd commands
    • See all cheat sheets

    Documentation

    • Product documentation
    • API catalog
    • Legacy documentation
  • Developer Sandbox

    Developer Sandbox

    • Access Red Hat’s products and technologies without setup or configuration, and start developing quicker than ever before with our new, no-cost sandbox environments.
    • Explore the Developer Sandbox

    Featured Developer Sandbox activities

    • Get started with your Developer Sandbox
    • OpenShift virtualization and application modernization using the Developer Sandbox
    • Explore all Developer Sandbox activities

    Ready to start developing apps?

    • Try at no cost
  • Blog
  • Events
  • Videos

Build a CI/CD pipeline with OpenShift Dev Spaces and GitOps

February 16, 2026
Rishabh Singh
Related topics:
CI/CDContainersDeveloper productivityDevOpsGitOpsGoIDEsOperators
Related products:
Developer ToolsRed Hat OpenShift Dev SpacesRed Hat OpenShift GitOps

    In this article, we will set up a CI/CD pipeline. This integrated CI/CD workflow leverages Red Hat OpenShift Dev Spaces to provide developers with a consistent, containerized environment defined by a devfile.yaml. Then using a pipelines-as-code approach, the CI pipeline will initiate directly from Git events, which builds the Go binary, packages it using Buildah, and updates the deployment manifest with the new image tag. Red Hat OpenShift GitOps (ArgoCD) monitors that manifest, automatically reconciling the cluster state whenever the pipeline commits a change.

    Set up the workflow

    This workflow is seamless. First, you will load a Git project in Red Hat OpenShift Dev Spaces, then make a change via the IDE, and trigger a PipelineRun (Red Hat Openshift Pipelines). Upon success, OpenShift GitOps syncs the application, updating the latest application image.

    Prerequisites:

    • Golang project: We will use the linked golang project to work through this use case.
    • Tekton Pipeline: We will use pipeline as code, where the pipeline is stored with the code.
    • Dev file: To start a workspace, we will use following devfile.yaml.

    Note: Fork the Git repository to follow along and create your own CI/CD pipeline. In case you have forked the repository, then you will have to change the GitHub URL with your own GitHub URL.

    OpenShift Dev Spaces configuration

    OpenShift Dev Spaces provides a consistent, containerized development environment defined by a devfile. Configure OpenShift Dev Spaces with the following steps.

    Step 1. Install OpenShift Dev Spaces

    First, install the OpenShift Dev Spaces operator on your cluster. You can install it via the OpenShift web console using the OperatorHub. Create the CheCluster (with default values) after installing OpenShift Dev Spaces.

    Step 2. Define the dev environment

    We will utilize a devfile.yaml to define the workspace. This file specifies the projects to clone, container components (i.e., runtime and tooling), and commands (i.e., build, run, test) available to the developer.

    You can review the example Devfile configuration used for this article.

    Step 3. Configure Git OAuth for workspace access

    To ensure the workspace has the necessary permissions to interact with your Git provider (e.g., to push changes that trigger the pipeline), you must configure Git OAuth. This loads a personal access token (PAT) into the workspace upon startup.

    You must register an OAuth application with your Git provider (e.g., GitHub) and create a Kubernetes secret containing the client ID and client secret in the namespace where the CheCluster was created.

    1. Navigate to GitHub Settings: Open your browser and go directly to the GitHub New OAuth Application page.
    2. Define the Application Name: In the Application name field, enter a name that helps you identify this connection (e.g., OpenShift-Dev-Spaces).
    3. Set the Homepage URL: Enter your specific OpenShift Dev Spaces address: https://<openshift_dev_spaces_fqdn>/
    4. Set the Authorization Callback URL: This is the most critical step for the handshake to work. Enter: https://<openshift_dev_spaces_fqdn>/api/oauth/callback
    5. Finalize Registration: Click the green Register application button at the bottom of the form.

    Secure your credentials as follows:

    1. Create a secret: On the application's general settings page, look for the Client secrets section and click Generate a new client secret.
    2. Record the ID: Locate the client ID (a string of alphanumeric characters). Copy this and save it securely; you’ll need it for your OpenShift configuration.
    3. Secure the Secret: Copy the client secret immediately.

    Apply the secret in the OpenShift cluster:

    Create the secret by adding the client ID, client secret created in the previous section, and the GitHub URL.

    kind: Secret
    apiVersion: v1
    metadata:
      name: github-oauth-config
      namespace: openshift-operators 
      labels:
        app.kubernetes.io/part-of: che.eclipse.org
        app.kubernetes.io/component: oauth-scm-configuration
      annotations:
        che.eclipse.org/oauth-scm-server: github
        che.eclipse.org/scm-server-endpoint: https://github.com
        che.eclipse.org/scm-github-disable-subdomain-isolation: 'false' 
    type: Opaque
    stringData:
      id: CLIENT_ID_FROM_GIT_OAUTH_APP
      secret: CLIENT_SECRET_FROM_GIT_OAUTH_APP

    Apply the secret in OpenShift cluster as follows.

    $ oc apply -f - <<EOF
    <Secret_prepared_in_the_previous_step>
    EOF

    ArgoCD and application creation

    We use Red Hat OpenShift GitOps (ArgoCD) to manage the deployment of the application. It continuously reconciles the state in the Git repository to the OpenShift cluster. In this article, we will update the image tag to the latest version and allow OpenShift GitOps to reconcile the updated deployment to the OpenShift cluster.

    Step 1. Install and configure the namespace

    Install the Red Hat OpenShift GitOps Operator. For this POC, we will use a specific namespace for our application testing.

    Create the namespace pipeline-test.

    $ oc new-project pipeline-test

    Next, label the namespace. To allow the default ArgoCD instance (running in openshift-gitops) to manage resources in this new namespace, you must apply a specific label.

    $ oc label namespace pipeline-test argocd.argoproj.io/managed-by=openshift-gitops

    This enables the ArgoCD instance to manage your namespace.

    Step 2. Create and apply the ArgoCD application

    You can create the application using the ArgoCD dashboard or CLI.

    • Source: Point to your Git repository URL and the specific path (e.g., app).
    • Destination: Set the server to https://kubernetes.default.svc and the namespace to pipeline-test.
    • Sync policy: Set it to Automatic to ensure changes reflected in the Git repository are immediately synced to the cluster.

    The following is the sample application which deploys the application manifest in pipelines-test namespace. This will create the list of objects in the OpenShift cluster and continue to track the manifests in the Git repository with live state in the OpenShift cluster.

    apiVersion: argoproj.io/v1alpha1
    kind: Application
    metadata:
     name: simple-go
     namespace: openshift-gitops
    spec:
     destination:
       namespace: pipeline-test
       server: https://kubernetes.default.svc
     project: default
     source:
       path: manifests
       repoURL: https://github.com/rishabhsvats/devspaces-pipeline-examples.git
       targetRevision: HEAD
     syncPolicy:
       syncOptions:
       - CreateNamespace=true
       ignoreDifferences:
       - group: route.openshift.io
         jsonPointers:
         - /spec/host
         kind: Route

    Once the application is ready, we can apply the application in openshift-gitops namespace.

    $ oc apply -f application.yaml

     Figure 1 shows the ArgoCD application status.

    ArgoCD application status
    Figure 1: This displays the ArgoCD application status.

    Pipeline configuration

    We use OpenShift Pipelines (based on Tekton) to handle the CI process. This involves configuring pipelines-as-code to listen for Git events. In OpenShift Pipelines, pipeline-as-code refers to the practice of defining your CI/CD workflows using YAML manifests that are stored and versioned directly within your Git repository. Instead of configuring builds manually in a UI, you use the pipelines-as-code (PaC) controller to automatically trigger, manage, and report the status of these pipelines based on Git events like pull requests or pushes.

    In this article, we will use the PipelineRun object placed in ./tekton/push.yaml.This PipelineRun is a pipelines-as-code definition that automates the end-to-end CI/CD lifecycle for a Go application whenever code is pushed or a pull request is opened on the main branch.

    It sequentially executes four tasks: cloning the source code, building the Go binary, creating a container image via Buildah, and committing the updated image tag back to the Git deployment manifest. Once the deployment manifest updates, the OpenShift GitOps controller will reconcile the updated manifest in the OpenShift cluster.

    Step 1. Install OpenShift Pipelines

    Install the OpenShift Pipelines operator from the OperatorHub. This will automatically install pipelines-as-code in the openshift-pipelines namespace.

    Step 2. Configure secrets and service accounts

    Pipelines require credentials to interact with Git and image registries. Create a secret to hold the Git user credentials. This is required for the pipeline to clone private repositories or push tags.

    • Type: kubernetes.io/basic-auth or kubernetes.io/ssh-auth.
    • Annotation: Annotate the secret (e.g., tekton.dev/git-0: github.com) to ensure Tekton uses it for the specific Git host.
    • The username will be the GitHub username, and the password will be the password access token (PAT).
    apiVersion: v1
    kind: Secret
    metadata:
     name: git-credentials
     annotations:
       tekton.dev/git-0: https://github.com   # match your git host
    type: kubernetes.io/basic-auth
    stringData:
     username: GIT_USERNAME
     password: GIT_PERSONAL_ACCESS_TOKEN

    Apply the secret in pipeline-test namespace.

    $ oc apply -f - <<EOF
    <Secret_prepared_in_the_previous_step>
    EOF

    Create a secret to allow the pipeline to push the built image to your container registry.

    apiVersion: v1
    kind: Secret
    metadata:
     name: regcred
     annotations:
       tekton.dev/docker-0: https://index.docker.io/v1/   # replace with quay.io or registry URL
    type: kubernetes.io/basic-auth
    stringData:
     username: DOCKER_USERNAME
     password: DOCKER_PASSWORD

    Apply the secret in pipeline-test namespace.

    $ oc apply -f - <<EOF
    <Secret_prepared_in_the_previous_step>
    EOF

    The Docker secret stores the docker config.json. This will be required to pull images from the Docker Registry. Extract the docker config.json from your local machine. This file will be generated as per the runtime you are using for Podman. You can find his file under ${XDG_RUNTIME_DIR}/containers/auth.json. The config.json/auth.json has been renamed to dockerconfig.json in the current use case.  

    $ oc create secret generic registry-credentials  --from-file=.dockerconfigjson=dockerconfig.json --type=kubernetes.io/dockerconfigjson -n pipeline-test

    Create a service account (pipeline-sa) and link the secrets previously created. This allows the TaskRuns associated with this service account to access the credentials automatically.

    apiVersion: v1
    kind: ServiceAccount
    metadata:
     name: pipeline-sa
    secrets:
     - name: regcred
     - name: git-credentials
    imagePullSecrets:
     - name: registry-credentials

    Apply the service account in the pipeline-test namespace. This will create a pipeline-sa service account.

    $ oc apply -f - <<EOF
    <service_account_prepared_in_the_previous_step>
    EOF

    Step 3. Security context constraints

    To ensure the pipeline has the necessary permissions to build images (e.g., using Buildah) and manage resources, you must grant the service account appropriate security context constraints (SCC). The pipeline-sa is created in pipeline-test namespace, hence the following command has to execute in same namespace.

    oc adm policy add-scc-to-user pipelines-scc -z pipeline-sa -n pipeline-test

    The pipelines-scc is designed specifically for pipeline workloads.

    Step 4. Git configuration: pipelines-as-code

    To trigger pipelines via Git events (pull requests/push), you must configure a GitHub App as follows.

    1. Create GitHub app: Create a GitHub app manually in your organization settings.
    2. Permissions: Grant read & write access to checks, contents, and pull requests.
    3. Events: Subscribe to check run, commit comment, issue comment, pull request, and push events.
    4. Connect to cluster: Create a secret in the openshift-pipelines namespace containing the GitHub app's private key, app ID, and webhook secret.

    To set up a GitHub app for OpenShift Pipelines as code, follow these steps.

    Register the GitHub app:

    1. Navigate to Settings > Developer settings > GitHub Apps > New GitHub App.
    2. Name: OpenShift Pipelines
    3. Homepage URL: OpenShift console URL.
    4. Webhook URL: Pipelines as code route URL.
    5. Webhook Secret: Generate a random string (e.g., via openssl rand -hex 20).

    Configure permissions and events:

    Set the following permissions to ensure the app can interact with your code:

    Category

    Permission

    Level

    Repository

    Checks, Contents, Issues, Pull requests

    Read & Write

    Repository

    Metadata

    Read-only

    Organization

    Members

    Read-only

    Subscribe to events: check run, check suite, commit comment, issue comment, pull request, and push.

    Finalize and secure:

    1. Click Create GitHub App.
    2. Note the App ID displayed on the app's general page.
    3. In the Private keys section, click Generate Private key and download the .pem file.
    4. Install the app on your desired repositories.

    Connect OpenShift to the Github app:

    Create the secret for pipelines-as-code to access the newly created GitHub app.

    $ oc -n openshift-pipelines create secret generic pipelines-as-code-secret \ 
    --from-literal github-private-key="$(cat <PATH_TO_PRIVATE_KEY>)" \ 
    --from-literal github-application-id="<APP_ID>" \ 
    --from-literal webhook-secret="<WEBHOOK_SECRET>"
    

    Step 5. Create a repository

    Now let's define a repository custom resource (CR) in your target namespace. This CR links your specific Git repository URL to the namespace where the pipeline will run.

    This informs pipelines-as-code to process events coming from that specific URL and execute the pipeline defined in the.tekton/ directory of your project.

    $ oc -n pipeline-test create secret generic github-webhook-config \
      --from-literal provider.token="<GITHUB_PERSONAL_ACCESS_TOKEN>" \
      --from-literal webhook.secret="<WEBHOOK_SECRET_CREATED_IN_PREVIOUS_STEP>"
    

    Once we create the secret, we can create the repository object as follows:

    apiVersion: pipelinesascode.tekton.dev/v1alpha1
    kind: Repository
    metadata:
      name: git-devspaces-pipeline-examples
      namespace: pipeline-test
    spec:
      git_provider:
        secret:
          key: provider.token
          name: github-webhook-config
        webhook_secret:
          key: webhook.secret
          name: github-webhook-config
      url: 'https://github.com/rishabhsvats/devspaces-pipeline-examples'

    By following this configuration, you establish a closed loop: Code Change (DevSpaces) -> CI Build (OpenShift Pipelines) -> CD Sync (OpenShift GitOps).

    Pipeline execution

    Now we will execute the pipeline. First, log in into the OpenShift Dev Spaces dashboard (Figure 2). 

    Dev Spaces dashboard
    Figure 2: This is the OpenShift Dev Spaces dashboard.

    Next launch the workspace by passing the URL of the Git repository that contains the devfile (Figure 3).

    Starting the workspace
    Figure 3: Starting the workspace.

    Figure 4 shows the application project opened in Visual Studio Code.

    Application project opened in Visual studio code
    Figure 4: The application project opened in Visual Studio Code.

    Make changes in the application code and push it to the Git repository. Figure 5 shows the application change (updated line 20) committed and pushed to the Git repository.

    Committing changes and pushing to Git repository
    Figure 5: The application source code change committed to Git.

    When you push code to the main branch, the pipelines-as-code controller detects the event and automatically executes this PipelineRun to clone your repo, compile the Go binary, and build a new container image.

    Once the image is ready, the pipeline updates your manifests/deployment.yaml with the new image tag and pushes that change back to your Git repository to complete the deployment cycle (Figure 6).

    Successful PipelineRun
    Figure 6: This shows a successful PipelineRun execution.

    Upon successful PipelineRun, observe the ArgoCD application status. If the status is not synced, refresh the application. Sync the application once the application status changes to OutofSync (Figure 7).

    OutOfSync Application Status
    Figure 7: This shows the OutOfSync application status.

    Access the application and observe if the change is effective, as shown in Figure 8.

    Updated application output
    Figure 8: Updated application output.

    Final thoughts

    This guide demonstrated the power of integrating Red Hat OpenShift Dev Spaces, OpenShift Pipelines (Tekton), and OpenShift GitOps (ArgoCD) to forge a truly modern, end-to-end CI/CD solution. By leveraging the principles of GitOps, where Git is the single source of truth, the architecture ensures that every code change made in an OpenShift Dev Spaces workspace automatically triggers the pipeline, which builds, tags, and updates the deployment manifest. This seamless, closed-loop system—Code Change -> CI Build -> CD Sync—establishes a repeatable, reliable, and automated path from commit to production, ultimately enabling faster and more consistent application delivery.

    Related Posts

    • Building modern CI/CD workflows for serverless applications with Red Hat OpenShift Pipelines and Argo CD, Part 2

    • Building modern CI/CD workflows for serverless applications with Red Hat OpenShift Pipelines and Argo CD, Part 1

    • A guide to AI code assistants with Red Hat OpenShift Dev Spaces

    • DevOps with OpenShift Pipelines and OpenShift GitOps

    Recent Posts

    • Build a CI/CD pipeline with OpenShift Dev Spaces and GitOps

    • Performance and load testing in Identity Management (IdM) systems using encrypted DNS (eDNS) and CoreDNS in OpenShift clusters

    • New LibSSH connection plug-in for Ansible replaces Paramiko

    • How to build an image mode pipeline with GitLab

    • Build a zero trust environment with Red Hat Connectivity Link

    What’s up next?

    The Modern DevOps Lifecycle:

    The Modern DevOps Lifecycle: Shifting CI/CD and Application Architectures

    G. Ryan Spain
    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Platforms

    • Red Hat AI
    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform
    • See all products

    Build

    • Developer Sandbox
    • Developer tools
    • Interactive tutorials
    • API catalog

    Quicklinks

    • Learning resources
    • E-books
    • Cheat sheets
    • Blog
    • Events
    • Newsletter

    Communicate

    • About us
    • Contact sales
    • Find a partner
    • Report a website issue
    • Site status dashboard
    • Report a security problem

    RED HAT DEVELOPER

    Build here. Go anywhere.

    We serve the builders. The problem solvers who create careers with code.

    Join us if you’re a developer, software engineer, web designer, front-end designer, UX designer, computer scientist, architect, tester, product manager, project manager or team lead.

    Sign me up

    Red Hat legal and privacy links

    • About Red Hat
    • Jobs
    • Events
    • Locations
    • Contact Red Hat
    • Red Hat Blog
    • Inclusion at Red Hat
    • Cool Stuff Store
    • Red Hat Summit
    © 2025 Red Hat

    Red Hat legal and privacy links

    • Privacy statement
    • Terms of use
    • All policies and guidelines
    • Digital accessibility

    Report a website issue