Skip to main content
This article demonstrates how to create a custom transformer that converts Jenkins’ withDockerRegistry step into equivalent GitHub Actions steps (Docker login + build/push). In Jenkins, withDockerRegistry provides Docker credentials so the pipeline can log in (e.g., to Docker Hub) and run docker push. When migrating to GitHub Actions, the common equivalent is docker/login-action (authentication) and docker/build-push-action (build + push), or a separate docker build step with a subsequent push. What you’ll learn
  • How withDockerRegistry maps to GitHub Actions.
  • How to extract the docker push command from the imported Jenkins JSON.
  • How to write a concise custom transformer (example in Ruby) that emits Actions steps with proper variable substitution.
  • How to prepare GitHub repository variables and secrets needed by the converted workflow.

Relevant Jenkins pipeline excerpt

What withDockerRegistry does

  • Supplies Docker credentials (from Jenkins credentials store) to allow docker push.
  • For migration, the natural mapping in GitHub Actions is:
    • docker/login-action — to authenticate to a registry.
    • docker/build-push-action — to build and push images (can also be split into docker build + docker push).

Marketplace actions and references

Search the GitHub Actions Marketplace for Docker-related actions. Typical choices:
  • docker/login-action@v3 — login to Docker Hub (or other registries).
  • docker/build-push-action@v6 — build and push images.
A dark-themed screenshot of the GitHub Marketplace Actions page with a search for "docker." The page shows the "Enhance your workflow with extensions" header and multiple Docker-related action cards like "Build and push Docker images" and "Docker Login."
Useful links

Minimal GitHub Actions job example

If you need to both build and push in one job, the typical pattern is:
If your Jenkins pipeline already performed docker build earlier, you can issue only the login and docker push steps (or use build-push-action to only push an already built image).

What the importer produced (problem)

The importer emitted a job with an unrecognized withDockerRegistry node in the Jenkins JSON. The children included an sh step with docker push <image>:$GIT_COMMIT, but no existing transformer handled it — so we create one. Example simplified JSON snippet the transformer receives

Transformer goals

The transformer should:
  1. Extract the docker push command from the child sh step.
  2. Parse the image name and tag from that push command.
  3. Replace Jenkins-specific variables and hardcoded values:
    • $GIT_COMMIT${{ github.sha }}
    • Hardcoded username/image → use GitHub Actions variables like ${{ vars.DOCKERHUB_USERNAME }} and ${{ vars.IMAGE_NAME }}
  4. Emit steps for:
    • Docker login (docker/login-action@v3)
    • Build and push (docker/build-push-action@v6) or a push-only step if the image is already built
Mapping summary (Jenkins → GitHub Actions)
Jenkins stepGitHub Actions equivalentNotes
withDockerRegistry (credentials)docker/login-action@v3Use repository-level vars and secrets to store username and password respectively.
docker build + docker pushdocker/build-push-action@v6Can both build and push. If build already exists, you can run push only.
Jenkins env $GIT_COMMIT${{ github.sha }}Use GitHub predefined contexts.
Hardcoded user/image${{ vars.DOCKERHUB_USERNAME }} / ${{ vars.IMAGE_NAME }}Add as repo variables for reuse.

Example custom transformer (Ruby) — concise

This Ruby transformer (for the importer’s transformer DSL) extracts the push command, rewrites variables, and emits Actions steps for login and build+push:
Notes about the transformer
  • The transformer replaces Jenkins credential references (credentialsId) with GitHub Actions variables and secrets:
    • username${{ vars.DOCKERHUB_USERNAME }}
    • password${{ secrets.DOCKERHUB_PASSWORD }}
    • image name${{ vars.IMAGE_NAME }}
  • If the importer already produced an earlier docker build step, you can emit a push-only action or leave the build step and use build-push-action in push-only mode.

Resulting GitHub Actions job (after transformer)

Run the importer (dry-run and migrate)

Dry-run (inspect generated workflows):
Example dry-run output:
To migrate and create a PR:
Example migrate output:

Add required repository variables and secrets

Before merging the PR and running workflows, create the required repository-level variables and secrets. Recommended repository variables and secrets
NameTypePurposeExample value
DOCKERHUB_USERNAMEvariableDocker Hub username used in tagssiddharth67
IMAGE_NAMEvariableImage repository name used in tagssolar-system
DOCKERHUB_PASSWORDsecretDocker Hub password (or token) for docker/login-action
Add them in the repository Settings → Actions → Secrets and variables. After creation, they will appear in the repository’s Actions > Secrets and variables settings.
A screenshot of a GitHub repository Settings page open to "Actions secrets / New secret," with the Name field filled as "DOCKERHUB_PASSWORD" and the Secret textbox empty. The left sidebar shows repository settings and code/automation options.
Confirm the variables and secrets are visible in Settings:
A dark-themed screenshot of a GitHub repository "Actions secrets and variables" settings page showing environment and repository variables (e.g., DOCKERHUB_USERNAME, IMAGE_NAME, MONGO_USERNAME). The left sidebar shows repository settings sections like Branches, Actions, Webhooks, and Secrets and variables.

Merge the PR and verify the workflow run

  • Merge the pull request created by the importer.
  • The merged workflow should trigger and perform: checkout, build (if configured), Docker login, and push to the registry (depending on the emitted job).
Pipeline run status (example):
A dark-themed CI/CD pipeline dashboard showing completed stages (Installing Dependencies, Unit Testing, Code Coverage, Build Publish Image, Trivy Vulnerability Scanner) with green checkmarks. The run status is "Success" and a Docker Build summary is visible below.
Selected sanitized log excerpts

Key takeaways

  • Jenkins withDockerRegistry cleanly maps to docker/login-action + docker/build-push-action in GitHub Actions.
  • Custom transformers should:
    • Extract docker push (or credential info) from the Jenkins JSON,
    • Substitute Jenkins variables with GitHub contexts and repository variables,
    • Emit the appropriate Actions steps (login and build/push or push-only).
  • Create repository-level variables and secrets prior to running the workflow:
    • DOCKERHUB_USERNAME and IMAGE_NAME (variables).
    • DOCKERHUB_PASSWORD (secret).
  • docker/build-push-action can both build and push—adjust emitted steps if a build is already present.
Remember to create repository variables (DOCKERHUB_USERNAME, IMAGE_NAME) and repository secrets (DOCKERHUB_PASSWORD) before merging; otherwise the workflow will fail at runtime when trying to access those values.
We will cover how to migrate and map the Trivy vulnerability scanner stage into GitHub Actions in a follow-up article. Depending on your preference and requirements, the Trivy step can be implemented as a shell step or via a dedicated action.

Watch Video