DEV Community

Query Filter
Query Filter

Posted on

docker9

The "Relay Race" Pattern: Syncing Gradle Builds with Ansible in Tekton

In a modern CI/CD pipeline, passing a dynamic build number from a Gradle build to an Ansible deployment is like a relay race. The "baton" is your version string (e.g., 1.2.345), and if it’s dropped between the build stage and the deploy stage, the whole race stops.

Since you are running this inside Tekton, you have a structured way to hand off this data. Here is the architectural "story" of how to bridge that gap.


Step 1: The Producer (Gradle)

First, your Gradle build needs to "vocalize" the version it just created. Since your RPM task already knows the ${version}, we add a small helper task to write that specific string to a dedicated file in the workspace.

In your build.gradle:

// Create a simple task to 'announce' the version
task exportBuildMetadata {
    doLast {
        def versionFile = new File(projectDir, "build_metadata.txt")
        versionFile.text = project.version.toString()
        println ">>> Exported Version: ${project.version}"
    }
}

// Ensure this runs automatically after your RPM is ready
buildRpm.finalizedBy exportBuildMetadata
Enter fullscreen mode Exit fullscreen mode

Step 2: The Hand-Off (Tekton Results)

In Tekton, containers are ephemeral—they vanish after they finish. To keep the version string alive for the next step, we use Tekton Results. This acts as a "global variable" for the entire pipeline.

In your Tekton Task YAML:

spec:
  results:
    - name: rpm-version
      description: "The dynamic build number generated by Gradle"
  steps:
    - name: run-gradle-build
      image: gradle:jdk17
      script: |
        gradle buildRpm exportBuildMetadata
        # 'cat' the file content into the special Tekton results path
        cat build_metadata.txt > $(results.rpm-version.path)
Enter fullscreen mode Exit fullscreen mode

Step 3: The Consumer (Ansible)

Now that the version is saved in the Pipeline's memory, we pass it into the Ansible task as a parameter. This removes the need for Ansible to "guess" the filename.

In your Tekton Pipeline YAML:

tasks:
  - name: deploy-to-env
    taskRef:
      name: ansible-deploy-task
    params:
      - name: build_number
        value: $(tasks.run-gradle-build.results.rpm-version)
      - name: rpm_prefix
        value: "comet-bridge"
Enter fullscreen mode Exit fullscreen mode

In your Ansible Playbook (deploy.yml):
Inside Ansible, you can now construct the exact filename using the variable passed from Tekton.

- name: Deploy the COMET RPM
  hosts: target_servers
  vars:
    # Construct the full name using the prefix and the build_number from Tekton
    rpm_filename: "{{ rpm_prefix }}-{{ build_number }}.rpm"
    rpm_source_path: "/workspace/source/build/distributions/{{ rpm_filename }}"

  tasks:
    - name: Ensure RPM is present on the target
      ansible.builtin.copy:
        src: "{{ rpm_source_path }}"
        dest: "/tmp/{{ rpm_filename }}"

    - name: Install the specific build
      ansible.builtin.yum:
        name: "/tmp/{{ rpm_filename }}"
        state: present
Enter fullscreen mode Exit fullscreen mode

Why This is the "Gold Standard" for LightSpeed

  1. Single Source of Truth: The version is defined in one place (Gradle) and pushed forward. You never have to update your Ansible code when the version increments.
  2. Audit Trail: Because you used a Tekton Result, you can look at the Tekton Dashboard and see exactly which version was passed between tasks without opening logs.
  3. Loose Coupling: Ansible doesn't need to know how Gradle built the file; it just needs to know the "ID" of the result.

Pro-Tip for the "Picking" Alternative

If you cannot change your Tekton YAML, you can make Ansible "find" the file by looking for the prefix. In your Playbook, use the find module:

- name: Locate the newest RPM
  ansible.builtin.find:
    paths: "/workspace/source/build/distributions"
    patterns: "comet-bridge-*.rpm"
  register: rpm_files

- name: Identify the latest file
  set_fact:
    latest_rpm: "{{ rpm_files.files | sort(attribute='mtime') | last }}"

- name: Install discovered RPM
  ansible.builtin.yum:
    name: "{{ latest_rpm.path }}"
    state: present
Enter fullscreen mode Exit fullscreen mode

This "Picking" method is a great safety net if your build numbers aren't perfectly sequential or if you are running manual tests!

Top comments (0)