Ruby
You can build and test a Ruby application using a Linux platform on Harness Cloud or a self-managed Kubernetes cluster build infrastructure.
This guide assumes you've created a Harness CI pipeline.
Install dependencies
Run Bundler commands in a Run step to install dependencies in the build environment.
- Harness Cloud
- Self-managed
- step:
    type: Run
    identifier: dependencies
    name: Dependencies
    spec:
      shell: Sh
      command: |-
        bundle check || bundle install
- step:
    type: Run
    identifier: dependencies
    name: Dependencies
    spec:
      connectorRef: YOUR_IMAGE_REGISTRY_CONNECTOR
      image: ruby:latest
      command: |-
        bundle check || bundle install
Cache dependencies
- Cache Intelligence
- Save and Restore Cache steps
You can cache your Ruby dependencies with Cache Intelligence. Add caching.enabled.true to your stage.spec and specify the cache paths (in paths and sharedPaths).
- stage:
    spec:
      caching:
        enabled: true
        key: cache-{{ checksum "Gemfile.lock" }}
        paths:
          - "vendor/bundle"
      sharedPaths:
        - vendor/bundle
You can use built-in steps to:
Here's an example of a pipeline with Save Cache to S3 and Restore Cache from S3 steps.
            steps:
              - step:
                  type: RestoreCacheS3
                  name: Restore Cache From S3
                  identifier: Restore_Cache_From_S3
                  spec:
                    connectorRef: AWS_connector
                    region: us-east-1
                    bucket: some_s3_bucket
                    key: cache-{{ checksum "Gemfile.lock" }}
                    archiveFormat: Tar
              - step:
                  type: Run
                  ...
              - step:
                  type: BuildAndPushDockerRegistry
                  ...
              - step:
                  type: SaveCacheS3
                  name: Save Cache to S3
                  identifier: Save_Cache_to_S3
                  spec:
                    connectorRef: AWS_connector
                    region: us-east-1
                    bucket: some_s3_bucket
                    key: cache-{{ checksum "Gemfile.lock" }}
                    sourcePaths:
                      - vendor/bundle
                    archiveFormat: Tar
Build and run tests
You can use Run and Test steps to run tests in Harness CI.
The following examples run tests in a Run step.
- Harness Cloud
- Self-managed
- step:
    type: Run
    name: Run Ruby Tests
    identifier: run_ruby_tests
    spec:
      shell: Sh
      command: |-
        bundle exec rake test
- step:
    type: Run
    name: Run Ruby Tests
    identifier: run_ruby_tests
    spec:
      connectorRef: YOUR_IMAGE_REGISTRY_CONNECTOR
      image: ruby:latest
      shell: Sh
      command: |-
        bundle exec rake test
Visualize test results
If you want to view test results in Harness, your test reports must be in JUnit XML format.
If you use a Run step to run tests, your Run step must include the reports specification. The reports specification is not required for Test steps (Test Intelligence).
The following examples use the Minitest JUnit Formatter. For more information and an RSpec example, go to Format test reports - Ruby.
- Harness Cloud
- Self-managed
- step:
    type: Run
    name: Run Ruby Tests
    identifier: run_ruby_tests
    spec:
      shell: Sh
      command: |-
        bundle exec rake test --junit
    reports:
      type: JUnit
      spec:
        paths:
          - report.xml
- step:
    type: Run
    name: Run Ruby Tests
    identifier: run_ruby_tests
    spec:
      connectorRef: YOUR_IMAGE_REGISTRY_CONNECTOR
      image: ruby:latest
      shell: Sh
      command: |-
        bundle exec rake test --junit
      reports:
        type: JUnit
        spec:
          paths:
            - report.xml
Run tests with Test Intelligence
Test Intelligence is available for Ruby unit tests.
Test splitting
Harness CI supports test splitting (parallelism) for both Run and Test steps.
Specify version
- Harness Cloud
- Self-managed
Ruby is pre-installed on Harness Cloud runners. For details about all available tools and versions, go to Platforms and image specifications.
If your application requires a specific Ruby version, add a Run or GitHub Action step to install it.
Use the setup-ruby action in a GitHub Action step to install the required Ruby version.
You will need a personal access token, stored as a secret, with read-only access for GitHub authentication.Install one Ruby version
- step:
    type: Action
    name: Install ruby
    identifier: installruby
    spec:
      uses: ruby/setup-ruby@v1
      with:
        ruby-version: 3.0Use multiple Ruby versions
- stage:
    strategy:
      matrix:
        rubyVersion:
          - 3.2.2
          - 2.7.8
- step:
    type: Action
    name: Install ruby
    identifier: installruby
    spec:
      uses: ruby/setup-ruby@v1
      with:
        ruby-version: <+ stage.matrix.rubyVersion >
Specify the desired Ruby Docker image tag in your steps. There is no need for a separate install step when using Docker.Use a specific Ruby version
- step:
    type: Run
    name: Ruby Version
    identifier: rubyversion
    spec:
      connectorRef: YOUR_IMAGE_REGISTRY_CONNECTOR
      image: ruby:latest
      shell: Sh
      command: |-
        ruby --versionUse multiple Ruby versions
- stage:
    strategy:
      matrix:
        rubyVersion:
          - 3.2.2
          - 2.7.8
image field of your steps.- step:
    type: Run
    name: Ruby Version
    identifier: rubyversion
    spec:
      connectorRef: YOUR_IMAGE_REGISTRY_CONNECTOR
      image: ruby:<+ stage.matrix.rubyVersion >
      shell: Sh
      command: |-
        ruby --version
Full pipeline examples
The following YAML examples describe pipelines that install dependencies, run tests, use caching, and build and push images to Docker Hub.
- Harness Cloud
- Self-managed
This pipeline uses Harness Cloud build infrastructure and Cache Intelligence.
If you copy this example, replace the placeholder values with appropriate values for your connector IDs, account/user names, and repo names. Depending on your project and organization, you may also need to replace projectIdentifier and orgIdentifier.
pipeline:
  name: ruby
  identifier: ruby
  projectIdentifier: default
  orgIdentifier: default
  tags: {}
  properties:
    ci:
      codebase:
        connectorRef: YOUR_CODE_REPO_CONNECTOR_ID
        repoName: YOUR_REPO_NAME
        build: <+input>
  stages:
    - stage:
        name: build
        identifier: build
        description: ""
        type: CI
        spec:
          cloneCodebase: true
          caching:
            enabled: true
            key: cache-{{ checksum "Gemfile.lock" }}
            paths:
              - vendor/bundle
          sharedPaths:
            - vendor/bundle
          platform:
            os: Linux
            arch: Amd64
          runtime:
            type: Cloud
            spec: {}
          execution:
            steps:
              - step:
                  type: Run
                  identifier: dependencies
                  name: Dependencies
                  spec:
                    shell: Sh
                    command: bundle install --path vendor/bundle
              - step:
                  type: Run
                  name: Run Ruby Tests
                  identifier: run_ruby_tests
                  spec:
                    shell: Sh
                    command: bundle exec rake test --junit
                  reports:
                    type: JUnit
                    spec:
                      paths:
                        - report.xml
              - step:
                  type: BuildAndPushDockerRegistry
                  name: BuildAndPushDockerRegistry_1
                  identifier: BuildAndPushDockerRegistry_1
                  spec:
                    connectorRef: YOUR_DOCKER_CONNECTOR_ID
                    repo: YOUR_DOCKER_HUB_USERNAME/YOUR_DOCKER_REPO_NAME
                    tags:
                      - <+pipeline.sequenceId>
This pipeline uses self-managed Kubernetes cluster build infrastructure and Save and Restore Cache from S3 steps.
If you copy this example, replace the placeholder values with appropriate values for your connector IDs, account/user names, repo names, and other settings. Depending on your project and organization, you may also need to replace projectIdentifier and orgIdentifier.
pipeline:
  name: ruby-k8s
  identifier: ruby_k8s
  projectIdentifier: default
  orgIdentifier: default
  tags: {}
  properties:
    ci:
      codebase:
        connectorRef: YOUR_CODE_REPO_CONNECTOR_ID
        repoName: YOUR_REPO_NAME
        build: <+input>
  stages:
    - stage:
        name: build
        identifier: build
        description: ""
        type: CI
        spec:
          cloneCodebase: true
          execution:
            steps:
              - step:
                  type: RestoreCacheS3
                  name: Restore Cache From S3
                  identifier: Restore_Cache_From_S3
                  spec:
                    connectorRef: YOUR_AWS_CONNECTOR_ID
                    region: us-east-1 ## Set to your bucket's AWS region
                    bucket: YOUR_AWS_BUCKET_NAME
                    key: cache-{{ checksum "Gemfile.lock" }}
                    archiveFormat: Tar
              - step:
                  type: Run
                  identifier: dependencies
                  name: Dependencies
                  spec:
                    shell: Sh
                    command: bundle install --path vendor/bundle
                    connectorRef: YOUR_IMAGE_REGISTRY_CONNECTOR
                    image: ruby:latest
              - step:
                  type: Run
                  name: Run Ruby Tests
                  identifier: run_ruby_tests
                  spec:
                    shell: Sh
                    command: bundle exec rake test --junit
                    connectorRef: YOUR_IMAGE_REGISTRY_CONNECTOR
                    image: ruby:latest
                  reports:
                    type: JUnit
                    spec:
                      paths:
                        - report.xml
              - step:
                  type: BuildAndPushDockerRegistry
                  name: BuildAndPushDockerRegistry_1
                  identifier: BuildAndPushDockerRegistry_1
                  spec:
                    connectorRef: YOUR_DOCKER_CONNECTOR_ID
                    repo: YOUR_DOCKER_HUB_USERNAME/YOUR_DOCKER_REPO_NAME
                    tags:
                      - <+pipeline.sequenceId>
              - step:
                  type: SaveCacheS3
                  name: Save Cache to S3
                  identifier: Save_Cache_to_S3
                  spec:
                    connectorRef: YOUR_AWS_CONNECTOR_ID
                    region: us-east-1 ## Set to your bucket's AWS region
                    bucket: YOUR_AWS_BUCKET_NAME
                    key: cache-{{ checksum "Gemfile.lock" }}
                    sourcePaths:
                      - vendor/bundle
                    archiveFormat: Tar
          infrastructure:
            type: KubernetesDirect
            spec:
              connectorRef: YOUR_KUBERNETES_CLUSTER_CONNECTOR_ID
              namespace: YOUR_KUBERNETES_NAMESPACE
              automountServiceAccountToken: true
              nodeSelector: {}
              os: Linux
Next steps
Now that you have created a pipeline that builds and tests a Ruby app, you could:
- Create triggers to automatically run your pipeline.
- Add steps to build and upload artifacts.
- Add a step to build and push an image to a Docker registry.