跳到正文
DEV Community· SHIBAM·· 3 小時前AI 評分54

如何在 Harness 從 Git 儲存庫建立 CI 流水線並推送 Docker 映像

From Git Repo to Docker Image: Building Your First CI Pipeline in Harness

AI 導讀

作者以 Java Maven 專案示範在 Harness 建立 CI 流水線,Harness 掃描 GitHub 儲存庫並生成建置、測試設定,作者再加入 DockerHub 推送步驟,全程無須手寫流水線 YAML。首次建置和測試用時 2 分 34 秒,42 項測試通過;加入映像推送後,整條流水線用時 3 分 6 秒,其中 Docker 步驟用時 47 秒。

正文

Connected a GitHub repo, built it, tested it, and pushed a tagged image to DockerHub, in about ten minutes, without writing a line of YAML.

Creating your first CI pipeline usually sounds simple until you actually start doing it.

You connect your repository, figure out what stages you need, configure the build steps, set up the runtime, add caching, testing, credentials, and then hope the first run actually works. With AI coding assistants now generating pull requests faster than most teams can review them, the pressure on CI pipelines is only growing. The 2025 Stack Overflow Developer Survey found that 84% of developers now use AI tools in their workflow, with 51% using them daily. Every AI-generated commit still needs a pipeline to validate it.

I had a Java Maven project that needed a CI pipeline, so I set one up in Harness.

This walkthrough is for developers or platform engineers setting up their first Harness CI pipeline. You need a Harness account (free tier works), a GitHub repository with buildable code, a Dockerfile in that repository (the Docker push step builds from it), and a DockerHub account if you want to follow the push step. I used my ci-intelligence-lab repo, a Java Maven project with 42 unit tests and a working Dockerfile already in the root.

So I started with one simple goal:

Connect my repository, create a working CI pipeline, and then take it one step further by building and pushing the image to DockerHub.

And honestly, most of the work ended up happening for me.

End result: the pipeline itself ran in just over 3 minutes, build, test, and push to DockerHub, without writing a line of pipeline YAML.

Two ways to do this

You can write the pipeline YAML from scratch: pick your container images, define your build and test commands, configure caching, add the Docker push step, wire up connectors. If you already know Harness CI well, that works.

The other option is to let Harness scan the repository and generate the pipeline for you. You review what it creates, run it, and then modify from there.

I went with the second option. I wanted a working pipeline first, not a perfect one.

Starting with a build pipeline

The first screen keeps things straightforward.

Harness asks what you want to do:

  • Create a build pipeline
  • Create a deployment pipeline
  • Get going on your own

Since I was trying out CI, I selected Create a build pipeline.

Let's get you set up screen

The next screen explains what is about to happen.

Harness will scan the repository, determine the stages and steps it needs, generate the pipeline, and store the YAML inside the .harness directory of the repository.

There is also an option to build everything manually.

I just clicked Let's go.

Connecting the repository

The first real step is selecting where the source code lives.

Harness gives you multiple options here, including Harness Code, GitHub, GitLab, and Bitbucket.

Select version control

I use GitHub, so I selected GitHub.

From there, Harness gave me another simple choice.

I could either use an existing connector or create a new one. I created a new one.

For GitHub Cloud, OAuth was already available as the authentication option. I clicked Connect, authorised Harness through GitHub, and that was basically it.

No copying tokens around. No manually setting up a bunch of authentication fields.

GitHub connector creation with OAuth

Once the connector was ready, Harness could access my repositories.

I selected the repository I wanted to build from and moved on. If you have dozens of repositories you may need to scroll to find yours.

This is where Harness started doing the work

After selecting the repository, there was not much left for me to configure.

Harness started checking connectivity, cloning the default branch, indexing the files, detecting the languages, and analysing the repository.

Code analysis in progress

Then it started generating the pipeline YAML. This is where the AI part actually started making sense to me. It was not just an AI button sitting somewhere in the product. Harness was actually looking at my codebase and using that information to put together the pipeline. I was not manually deciding which build image to use, what build command I needed, how the test step should look, or how the basic CI stage should be structured. Harness was putting that together for me.

Generating pipeline YAML via Harness AI

Within a short while, the pipeline was created. Harness asked whether I wanted to start my first build. Of course I clicked Let's go. You generated the pipeline for me, now let's see if it actually works.

The first run actually passed

The pipeline started running immediately.

I could see Harness going through the generated steps:

  • Initialize
  • Clone the codebase
  • Set up Build Intelligence
  • Restore the cache
  • Build
  • Test
  • Save the cache

And then everything turned green.

First run success, cache save

The full run took 2 minutes and 34 seconds. 42 tests passed.

That was probably the point where the whole onboarding flow clicked for me.

I had essentially given Harness access to the repository, selected the codebase, let it analyse what was inside, and then ran the pipeline it created.

And the first run passed.

No manual pipeline assembly before getting to that point.

That is a solid starting point, but I wanted to make the pipeline more real.

Building and testing is useful, but I also wanted the image to actually go somewhere.

So next, I decided to build and push it to DockerHub.

Adding Build and Push to Docker

Inside the pipeline editor, I clicked the + button to add another step.

I searched for Docker.

Harness immediately showed several Docker-related options, including Build and Push Docker.

Add step, searching for Docker

I selected it and, once again, Harness gave me the option to use an existing connector or create a new one.

I created a new Docker connector.

For DockerHub, the connector setup was straightforward: select DockerHub as the provider, enter the credentials, done.

Once the connector was available, I selected it in the Build and Push Docker step.

Then I configured the repository I wanted to push to.

For the image tags, I used the pipeline sequence ID and also added latest.

I also kept Docker layer caching enabled.

Build and Push Docker configuration

Build, test, push

I ran the pipeline again. This time it went through the original CI steps and then continued into the Docker push step.

Clone → Build → Test → Build and Push Docker → Save Cache

Full pipeline with Docker push step

The pipeline passed, but I wanted to confirm outside of Harness. I opened DockerHub and the newly pushed image was there, including the latest tag and the tag from the pipeline run.

DockerHub repository showing pushed tags

This time the full pipeline, including the Docker push, finished in 3 minutes and 6 seconds. The Docker step itself took 47 seconds.

So the end state: code in GitHub, a CI pipeline that builds and tests it, and the resulting image pushed to DockerHub. One extra step on top of what Harness generated.

What I configured vs what Harness handled

Here is the split:

I did Harness did
Connected my GitHub account (OAuth) Detected Java + Maven from the repo
Selected the repository Chose the container image (maven:3.9-eclipse-temurin-17)
Clicked "Let's go" Generated the build and test steps
Added the Docker push step Configured Cache Intelligence and Build Intelligence
Created the DockerHub connector Set up test reporting with JUnit XML paths
Set the image tags Structured the stage, clone, and runtime config

Six decisions on my side. Six things I did not have to figure out.

If I had written this pipeline from scratch, I would have needed to know which Maven image version to use, how Harness structures its YAML stages, where to put the cache config, and how to format the test report paths. Instead, I started with a working baseline and added the Docker push step on top.

That difference matters. Starting with a blank pipeline means you have to understand the product before you can get value from it. Here, the order was reversed: get something running, then customise.

And if your team is using AI coding assistants, every one of those AI-generated PRs still needs to pass through a pipeline like this before it ships. The faster you can stand one up, the less it bottlenecks the rest of the delivery chain.

Test Intelligence can skip tests that are not affected by your code change, and Cache Intelligence handles dependency caching automatically (yours is already enabled in the generated pipeline). If you want to see how those features perform at scale, Harness CI benchmarks show up to 4x faster builds with both enabled. I will walk through both of those in a follow-up post. The Harness CI documentation covers advanced Docker push options including multi-architecture builds and custom Dockerfile paths.


Here is the pipeline YAML that Harness generated and that I extended with the Docker push step:

pipeline:
  name: pipeline_shibam17_ci_intelligence_lab_build_cf9f
  clone:
    enabled: true
  stages:
    - id: build_and_test
      name: build-and-test
      runtime: cloud
      clone:
        enabled: true
      cache:
        enabled: true
      build-intelligence:
        enabled: true
      steps:
        - id: build
          name: Build
          run:
            container:
              image: maven:3.9-eclipse-temurin-17
            shell: bash
            script: mvn -B -Dmaven.repo.local=/harness/.m2/repository -DskipTests clean compile
        - id: test
          name: Test
          run:
            container:
              image: maven:3.9-eclipse-temurin-17
            shell: bash
            script: mvn -B -Dmaven.repo.local=/harness/.m2/repository test
            report:
              type: junit
              paths:
                - target/surefire-reports/*.xml
        - name: docker-push-sdrepo
          id: docker_push_sdrepo
          build:
            uses: buildAndPushToDocker
            with:
              connector: shibam_dockerhub
              repo: shibam17/sd-devrel-easybuggy
              tags:
                - ${{ pipeline.sequenceId }}
                - latest
              caching: true

Fork the ci-intelligence-lab repository and try the onboarding flow against it, or point Harness at your own repo and see what it generates. Budget about ten minutes for the full setup: creating connectors, letting Harness generate the pipeline, and running your first build. The Harness CI getting started guide covers the full configuration reference.


Frequently asked questions

How does Harness know what build steps to generate?

Harness clones your repository, indexes the files, and detects the languages and build tools present. It uses that information to select the right container image, build commands, and test reporting configuration. For a Java Maven project, it picked maven:3.9-eclipse-temurin-17 and configured mvn commands automatically.

Do I need a Dockerfile in my repository for the Docker push step?

Yes. The Build and Push Docker step builds the image from the Dockerfile in your repository root (or a path you specify). If your project does not have a Dockerfile yet, add one before enabling the push step.

Can I use a registry other than DockerHub?

Yes. Harness supports Docker Hub, AWS ECR, Google GAR, Azure ACR, and Harness Artifact Registry. The connector setup is the same: create a connector for your provider and reference it in the Build and Push step.

What does Build Intelligence do in the generated pipeline?

Build Intelligence caches compiled build outputs. If the inputs for a module have not changed since the last run, Harness retrieves the previously compiled output instead of recompiling. This stacks on top of Cache Intelligence, which handles dependency downloads.


來源:DEV Community · dev.to