Skip to content

Instantly share code, notes, and snippets.

@robandpdx
Last active April 10, 2024 17:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save robandpdx/cc25300a01dafb2d824b1cd7cc295fe3 to your computer and use it in GitHub Desktop.
Save robandpdx/cc25300a01dafb2d824b1cd7cc295fe3 to your computer and use it in GitHub Desktop.

Converting CircleCI workflows to GitHub Actions

Start by using GitHub Actions Importer (GAI) Follow the getting started instructions to install and configure GAI.

Run an audit with GAI

gh actions-importer audit circle-ci --output-dir audit

The audit command will show you what GAI will do during the migration. In the audit directory, you will find a directory for each repo in the org within a directory named for the org. Inside each repo directory, you will find a .github directory with a workflows and possible an actions directory with the workflows and actions GAI has created. Inspect these artifacts to see what GAI will produce during the migration.

Run a migration with GAI

gh actions-importer migrate circle-ci --target-url https://github.com/robandpdx-org/rocksdb.git --output-dir migrate --circle-ci-project rocksdb

The migration command should result in a PR into the target repo. This PR should contain the workflows and actions created by GAI.

Edit the result of the GAI migration

GAI does not get you 100% of the way there. There are things that GAI does not account for. The following are the things I've found that need attention after using GAI to migrate a CircleCI workflow.

Dependencies

Many builds require dependencies be installed on the runner. It is best to look at what dependencies are being installed in the workflow and see what of those might already exist on the runner.

The *.Readme.md files in the following locations show the software pre-intalled on the runners... Ubuntu Macos Windows

In some cases, the workflow uses a container to provide a dependency like node or python. In most cases, it's better to use a setup-* action rather than run the build inside a container. For example, it's better to use the actions/setup-python action than it is to run apt install python or run a series of shell commands that downloads and installs the specific version of python needed.

Workflow triggers

CircleCI does not have the same set of workflow triggers that GitHub actions workflows have. In many cases, you can eliminate complicated logic to run jobs if certain files have chnaged, or if a tag was pushed, simply by changing the triggers to the worklfow. I've seen complicated logic in CircleCI dynamic configuration that can simply be replaced by well crafted workflow triggers. In some cases, you may also want to consider using the changed-files action to potentially skip steps or jobs depending on what types of files changed.

Persist workspace, cache, artifacts

There is no equivalent to the CircleCI persist_to_workspace step in GitHub actions. The only options available are cache and artifacts. While there are actions to save cache and restore cache, it is often easier to simply use the cache action, which provides both functions with less effort.

Many of the setup-* actions have dependency caching built in. These include: setup-python setup-java setup-go setup-node setup-dotnet

Cache keys

CircleCI cache keys often contain ...-{{ checksum ".circleci/config.yml }}-{{ checksum "path/to/another/file" }}-.... GitHub actions provides many functions, one of which is hashFiles, which can be used in a similar way for cache keys.

Passing data between jobs

In CircleCI I often see steps that write a file to the workspace, persists the workspace, then another job will attach the workspace and test for the existence of that file or read that file for it's contents, using the results as a flag to determine behavior within the job, or as part of a cache key. In GitHub actions workflows, the best way to do something similar is by defining outputs for jobs, and using the output in later jobs in the workflow.

Reduce duplication, commands -> composite actions

CircleCI has commands to reduce code duplication. The closest equivalent to this in GitHub actions are composite actions. Not all commands are good candidates for a composite action. For example, if a command is only used once in the CircleCI config, maybe it's easier to just include the steps within it in the GitHub workflow job itself and eliminate the abstraction.

Matrices are another way to reuse jobs within a workflow.

References to CircleCI stuff

References to CircleCI specific paths and environment variables should be replaced with their GitHub Actions equivalent. The tables below shows some of the GitHub Actions equivalents to CircleCI paths and variables.

CircleCI Ref GitHub Actions Context Ref Github Actions Env Var (run steps)
/home/circleci/project ${{ github.workspace }} $GITHUB_WORKSPACE
CIRCLE_BRANCH ${{ github.ref_name }} $GITHUB_REF_NAME
CIRCLE_BUILD_NUM ${{ github.run_number }} $GITHUB_RUN_NUMBER
CIRCLE_JOB ${{ github.job }} $GITHUB_JOB
>> $BASH_ENV >> $GITHUB_ENV
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment