Skip to content

Latest commit

 

History

History
418 lines (311 loc) · 13.8 KB

migrating-from-circleci-to-github-actions.md

File metadata and controls

418 lines (311 loc) · 13.8 KB
titleintroredirect_fromversionstypetopicsshortTitle
Migrating from CircleCI to GitHub Actions
GitHub Actions and CircleCI share several similarities in configuration, which makes migration to GitHub Actions relatively straightforward.
/actions/learn-github-actions/migrating-from-circleci-to-github-actions
/actions/migrating-to-github-actions/migrating-from-circleci-to-github-actions
/actions/migrating-to-github-actions/manual-migrations/migrating-from-circleci-to-github-actions
fptghesghec
*
*
*
tutorial
CircleCI
Migration
CI
CD
Migrate from CircleCI

{% data reusables.actions.enterprise-github-hosted-runners %}

Introduction

CircleCI and {% data variables.product.prodname_actions %} both allow you to create workflows that automatically build, test, publish, release, and deploy code. CircleCI and {% data variables.product.prodname_actions %} share some similarities in workflow configuration:

  • Workflow configuration files are written in YAML and stored in the repository.
  • Workflows include one or more jobs.
  • Jobs include one or more steps or individual commands.
  • Steps or tasks can be reused and shared with the community.

For more information, see AUTOTITLE.

Key differences

When migrating from CircleCI, consider the following differences:

  • CircleCI’s automatic test parallelism automatically groups tests according to user-specified rules or historical timing information. This functionality is not built into {% data variables.product.prodname_actions %}.
  • Actions that execute in Docker containers are sensitive to permissions problems since containers have a different mapping of users. You can avoid many of these problems by not using the USER instruction in your Dockerfile. For more information about the Docker filesystem on {% data variables.product.github %}-hosted runners, see AUTOTITLE.

Migrating workflows and jobs

CircleCI defines workflows in the config.yml file, which allows you to configure more than one workflow. {% data variables.product.github %} requires one workflow file per workflow, and as a consequence, does not require you to declare workflows. You'll need to create a new workflow file for each workflow configured in config.yml.

Both CircleCI and {% data variables.product.prodname_actions %} configure jobs in the configuration file using similar syntax. If you configure any dependencies between jobs using requires in your CircleCI workflow, you can use the equivalent {% data variables.product.prodname_actions %} needs syntax. For more information, see AUTOTITLE.

Migrating orbs to actions

Both CircleCI and {% data variables.product.prodname_actions %} provide a mechanism to reuse and share tasks in a workflow. CircleCI uses a concept called orbs, written in YAML, to provide tasks that people can reuse in a workflow. {% data variables.product.prodname_actions %} has powerful and flexible reusable components called actions, which you build with either JavaScript files or Docker images. You can create actions by writing custom code that interacts with your repository in any way you'd like, including integrating with {% data variables.product.github %}'s APIs and any publicly available third-party API. For example, an action can publish npm modules, send SMS alerts when urgent issues are created, or deploy production-ready code. For more information, see AUTOTITLE.

CircleCI can reuse pieces of workflows with YAML anchors and aliases. {% data variables.product.prodname_actions %} supports the most common need for reusability using matrices. For more information about matrices, see AUTOTITLE.

Using Docker images

Both CircleCI and {% data variables.product.prodname_actions %} support running steps inside of a Docker image.

CircleCI provides a set of pre-built images with common dependencies. These images have the USER set to circleci, which causes permissions to conflict with {% data variables.product.prodname_actions %}.

We recommend that you move away from CircleCI's pre-built images when you migrate to {% data variables.product.prodname_actions %}. In many cases, you can use actions to install the additional dependencies you need.

For more information about the Docker filesystem, see AUTOTITLE.

For more information about the tools and packages available on {% data variables.product.prodname_dotcom %}-hosted runner images, see AUTOTITLE.

Using variables and secrets

CircleCI and {% data variables.product.prodname_actions %} support setting variables in the configuration file and creating secrets using the CircleCI or {% data variables.product.github %} UI.

For more information, see AUTOTITLE and AUTOTITLE.

Caching

CircleCI and {% data variables.product.prodname_actions %} provide a method to manually cache files in the configuration file.

Below is an example of the syntax for each system.

CircleCI syntax for caching

{% raw %}

- restore_cache: keys: - v1-npm-deps-{{ checksum "package-lock.json" }} - v1-npm-deps-

{% endraw %}

GitHub Actions syntax for caching

- name: Cache node modulesuses: {% data reusables.actions.action-cache %}with: path: ~/.npmkey: {% raw %}v1-npm-deps-${{ hashFiles('**/package-lock.json') }}{% endraw %}restore-keys: v1-npm-deps-

{% data variables.product.prodname_actions %} does not have an equivalent of CircleCI’s Docker Layer Caching (or DLC).

Persisting data between jobs

Both CircleCI and {% data variables.product.prodname_actions %} provide mechanisms to persist data between jobs.

Below is an example in CircleCI and {% data variables.product.prodname_actions %} configuration syntax.

CircleCI syntax for persisting data between jobs

{% raw %}

- persist_to_workspace: root: workspacepaths: - math-homework.txt ... - attach_workspace: at: /tmp/workspace

{% endraw %}

GitHub Actions syntax for persisting data between jobs

- name: Upload math result for job 1uses: {% data reusables.actions.action-upload-artifact %}with: name: homeworkpath: math-homework.txt ... - name: Download math result for job 1uses: {% data reusables.actions.action-download-artifact %}with: name: homework

For more information, see AUTOTITLE.

Using databases and service containers

Both systems enable you to include additional containers for databases, caching, or other dependencies.

In CircleCI, the first image listed in the config.yaml is the primary image used to run commands. {% data variables.product.prodname_actions %} uses explicit sections: use container for the primary container, and list additional containers in services.

Below is an example in CircleCI and {% data variables.product.prodname_actions %} configuration syntax.

CircleCI syntax for using databases and service containers

{% raw %}

--- version: 2.1jobs: ruby-26: docker: - image: circleci/ruby:2.6.3-node-browsers-legacyenvironment: PGHOST: localhostPGUSER: administrateRAILS_ENV: test - image: postgres:10.1-alpineenvironment: POSTGRES_USER: administratePOSTGRES_DB: ruby26POSTGRES_PASSWORD: ""working_directory: ~/administratesteps: - checkout# Bundle install dependencies - run: bundle install --path vendor/bundle# Wait for DB - run: dockerize -wait tcp://localhost:5432 -timeout 1m# Setup the environment - run: cp .sample.env .env# Setup the database - run: bundle exec rake db:setup# Run the tests - run: bundle exec rakeworkflows: version: 2build: jobs: - ruby-26 ... - attach_workspace: at: /tmp/workspace

{% endraw %}

GitHub Actions syntax for using databases and service containers

name: Containerson: [push]jobs: build: runs-on: ubuntu-latestcontainer: circleci/ruby:2.6.3-node-browsers-legacyenv: PGHOST: postgresPGUSER: administrateRAILS_ENV: testservices: postgres: image: postgres:10.1-alpineenv: POSTGRES_USER: administratePOSTGRES_DB: ruby25POSTGRES_PASSWORD: ""ports: - 5432:5432# Add a health checkoptions: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5steps: # This Docker file changes sets USER to circleci instead of using the default user, so we need to update file permissions for this image to work on GH Actions.# See https://docs.github.com/actions/using-github-hosted-runners/about-github-hosted-runners#docker-container-filesystem - name: Setup file system permissionsrun: sudo chmod -R 777 $GITHUB_WORKSPACE /github /__w/_temp - uses: {% data reusables.actions.action-checkout %} - name: Install dependenciesrun: bundle install --path vendor/bundle - name: Setup environment configurationrun: cp .sample.env .env - name: Setup databaserun: bundle exec rake db:setup - name: Run testsrun: bundle exec rake

For more information, see AUTOTITLE.

Complete Example

Below is a real-world example. The left shows the actual CircleCI config.yml for the thoughtbot/administrator repository. The right shows the {% data variables.product.prodname_actions %} equivalent.

Complete example for CircleCI

{% raw %}

--- version: 2.1commands: shared_steps: steps: - checkout# Restore Cached Dependencies - restore_cache: name: Restore bundle cachekey: administrate-{{ checksum "Gemfile.lock" }}# Bundle install dependencies - run: bundle install --path vendor/bundle# Cache Dependencies - save_cache: name: Store bundle cachekey: administrate-{{ checksum "Gemfile.lock" }}paths: - vendor/bundle# Wait for DB - run: dockerize -wait tcp://localhost:5432 -timeout 1m# Setup the environment - run: cp .sample.env .env# Setup the database - run: bundle exec rake db:setup# Run the tests - run: bundle exec rakedefault_job: &default_jobworking_directory: ~/administratesteps: - shared_steps# Run the tests against multiple versions of Rails - run: bundle exec appraisal install - run: bundle exec appraisal rakejobs: ruby-25: <<: *default_jobdocker: - image: circleci/ruby:2.5.0-node-browsersenvironment: PGHOST: localhostPGUSER: administrateRAILS_ENV: test - image: postgres:10.1-alpineenvironment: POSTGRES_USER: administratePOSTGRES_DB: ruby25POSTGRES_PASSWORD: ""ruby-26: <<: *default_jobdocker: - image: circleci/ruby:2.6.3-node-browsers-legacyenvironment: PGHOST: localhostPGUSER: administrateRAILS_ENV: test - image: postgres:10.1-alpineenvironment: POSTGRES_USER: administratePOSTGRES_DB: ruby26POSTGRES_PASSWORD: ""workflows: version: 2multiple-rubies: jobs: - ruby-26 - ruby-25

{% endraw %}

Complete example for GitHub Actions

{% data reusables.actions.actions-not-certified-by-github-comment %}{% data reusables.actions.actions-use-sha-pinning-comment %}name: Containerson: [push]jobs: build: strategy: matrix: ruby: ['2.5', '2.6.3']runs-on: ubuntu-latestenv: PGHOST: localhostPGUSER: administrateRAILS_ENV: testservices: postgres: image: postgres:10.1-alpineenv: POSTGRES_USER: administratePOSTGRES_DB: ruby25POSTGRES_PASSWORD: ""ports: - 5432:5432# Add a health checkoptions: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5steps: - uses: {% data reusables.actions.action-checkout %} - name: Setup Rubyuses: eregon/use-ruby-action@ec02537da5712d66d4d50a0f33b7eb52773b5ed1with: ruby-version: {% raw %}${{ matrix.ruby }}{% endraw %} - name: Cache dependenciesuses: {% data reusables.actions.action-cache %}with: path: vendor/bundlekey: administrate-{% raw %}${{ matrix.image }}-${{ hashFiles('Gemfile.lock') }}{% endraw %} - name: Install postgres headersrun: | sudo apt-get update sudo apt-get install libpq-dev - name: Install dependenciesrun: bundle install --path vendor/bundle - name: Setup environment configurationrun: cp .sample.env .env - name: Setup databaserun: bundle exec rake db:setup - name: Run testsrun: bundle exec rake - name: Install appraisalrun: bundle exec appraisal install - name: Run appraisalrun: bundle exec appraisal rake
close