{"meta":{"title":"Migrating from Travis CI to GitHub Actions","intro":"GitHub Actions and Travis CI share multiple similarities, which helps make it relatively straightforward to migrate to GitHub Actions.","product":"GitHub Actions","breadcrumbs":[{"href":"/en/actions","title":"GitHub Actions"},{"href":"/en/actions/tutorials","title":"Tutorials"},{"href":"/en/actions/tutorials/migrate-to-github-actions","title":"Migrate to GitHub Actions"},{"href":"/en/actions/tutorials/migrate-to-github-actions/manual-migrations","title":"Manual migrations"},{"href":"/en/actions/tutorials/migrate-to-github-actions/manual-migrations/migrate-from-travis-ci","title":"Migrate from Travis CI"}],"documentType":"article"},"body":"# Migrating from Travis CI to GitHub Actions\n\nGitHub Actions and Travis CI share multiple similarities, which helps make it relatively straightforward to migrate to GitHub Actions.\n\n## Introduction\n\nThis guide helps you migrate from Travis CI to GitHub Actions. It compares their concepts and syntax, describes the similarities, and demonstrates their different approaches to common tasks.\n\n## Before you start\n\nBefore starting your migration to GitHub Actions, it would be useful to become familiar with how it works:\n\n* For a quick example that demonstrates a GitHub Actions job, see [Quickstart for GitHub Actions](/en/actions/quickstart).\n* To learn the essential GitHub Actions concepts, see [Understanding GitHub Actions](/en/actions/learn-github-actions/understanding-github-actions).\n\n## Comparing job execution\n\nTo give you control over when CI tasks are executed, a GitHub Actions *workflow* uses *jobs* that run in parallel by default. Each job contains *steps* that are executed in a sequence that you define. If you need to run setup and cleanup actions for a job, you can define steps in each job to perform these.\n\n## Key similarities\n\nGitHub Actions and Travis CI share certain similarities, and understanding these ahead of time can help smooth the migration process.\n\n### Using YAML syntax\n\nTravis CI and GitHub Actions both use YAML to create jobs and workflows, and these files are stored in the code's repository. For more information on how GitHub Actions uses YAML, see [Understanding GitHub Actions](/en/actions/learn-github-actions/understanding-github-actions#create-an-example-workflow).\n\n### Custom variables\n\nTravis CI lets you set variables and share them between stages. Similarly, GitHub Actions lets you define variables for a workflow. For more information, see [Store information in variables](/en/actions/learn-github-actions/variables).\n\n### Default variables\n\nTravis CI and GitHub Actions both include default environment variables that you can use in your YAML files. For GitHub Actions, you can see these listed in [Variables reference](/en/actions/reference/variables-reference#default-environment-variables).\n\n### Parallel job processing\n\nTravis CI can use `stages` to run jobs in parallel. Similarly, GitHub Actions runs `jobs` in parallel. For more information, see [Workflows](/en/actions/using-workflows/about-workflows#creating-dependent-jobs).\n\n### Status badges\n\nTravis CI and GitHub Actions both support status badges, which let you indicate whether a build is passing or failing.\nFor more information, see [Adding a workflow status badge](/en/actions/monitoring-and-troubleshooting-workflows/adding-a-workflow-status-badge).\n\n### Using a matrix\n\nTravis CI and GitHub Actions both support a matrix, allowing you to perform testing using combinations of operating systems and software packages. For more information, see [Running variations of jobs in a workflow](/en/actions/using-jobs/using-a-matrix-for-your-jobs).\n\nBelow is an example comparing the syntax for each system.\n\n#### Travis CI syntax for a matrix\n\n```yaml\nmatrix:\n  include:\n    - rvm: '2.5'\n    - rvm: '2.6.3'\n```\n\n#### GitHub Actions syntax for a matrix\n\n```yaml\njobs:\n  build:\n    strategy:\n      matrix:\n        ruby: ['2.5', '2.6.3']\n```\n\n### Targeting specific branches\n\nTravis CI and GitHub Actions both allow you to target your CI to a specific branch. For more information, see [Workflow syntax for GitHub Actions](/en/actions/using-workflows/workflow-syntax-for-github-actions#onpushbranchestagsbranches-ignoretags-ignore).\n\nBelow is an example of the syntax for each system.\n\n#### Travis CI syntax for targeting specific branches\n\n```yaml\nbranches:\n  only:\n    - main\n    - 'mona/octocat'\n```\n\n#### GitHub Actions syntax for targeting specific branches\n\n```yaml\non:\n  push:\n    branches:\n      - main\n      - 'mona/octocat'\n```\n\n### Checking out submodules\n\nTravis CI and GitHub Actions both allow you to control whether submodules are included in the repository clone.\n\nBelow is an example of the syntax for each system.\n\n#### Travis CI syntax for checking out submodules\n\n```yaml\ngit:\n  submodules: false\n```\n\n#### GitHub Actions syntax for checking out submodules\n\n```yaml\n- uses: actions/checkout@v6\n  with:\n    submodules: false\n```\n\n### Using environment variables in a matrix\n\nTravis CI and GitHub Actions can both add custom variables to a test matrix, which allows you to refer to the variable in a later step.\n\nIn GitHub Actions, you can use the `include` key to add custom environment variables to a matrix. In this example, the matrix entries for `node-version` are each configured to use different values for the `site` and `datacenter` environment variables. The `Echo site details` step then uses `env: ${{ matrix.env }}` to refer to the custom variables:\n\n```yaml\nname: Node.js CI\non: [push]\njobs:\n  build:\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n       include:\n         - node-version: '14.x'\n           site: \"prod\"\n           datacenter: \"site-a\"\n         - node-version: '16.x'\n           site: \"dev\"\n           datacenter: \"site-b\"\n    steps:\n      - name: Echo site details\n        env:\n          SITE: ${{ matrix.site }}\n          DATACENTER: ${{ matrix.datacenter }}\n        run: echo $SITE $DATACENTER\n```\n\n## Key features in GitHub Actions\n\nWhen migrating from Travis CI, consider the following key features in GitHub Actions:\n\n### Storing secrets\n\nGitHub Actions allows you to store secrets and reference them in your jobs. GitHub Actions organizations can limit which repositories can access organization secrets. Deployment protection rules can require manual approval for a workflow to access environment secrets. For more information, see [Secrets](/en/actions/security-for-github-actions/security-guides/about-secrets).\n\n### Sharing files between jobs and workflows\n\nGitHub Actions includes integrated support for artifact storage, allowing you to share files between jobs in a workflow. You can also save the resulting files and share them with other workflows. For more information, see [Understanding GitHub Actions](/en/actions/learn-github-actions/essential-features-of-github-actions#sharing-data-between-jobs).\n\n### Hosting your own runners\n\nIf your jobs require specific hardware or software, GitHub Actions allows you to host your own runners and send your jobs to them for processing. GitHub Actions also lets you use policies to control how these runners are accessed, granting access at the organization or repository level. For more information, see [Managing self-hosted runners](/en/actions/how-tos/managing-self-hosted-runners).\n\n### Concurrent jobs and execution time\n\nThe concurrent jobs and workflow execution times in GitHub Actions can vary depending on your GitHub plan. For more information, see [Billing and usage](/en/actions/learn-github-actions/usage-limits-billing-and-administration).\n\n### Using different languages in GitHub Actions\n\nWhen working with different languages in GitHub Actions, you can create a step in your job to set up your language dependencies. For more information about working with a particular language, see [Building and testing your code](/en/actions/use-cases-and-examples/building-and-testing).\n\n## Executing scripts\n\nGitHub Actions can use `run` steps to run scripts or shell commands. To use a particular shell, you can specify the `shell` type when providing the path to the script. For more information, see [Workflow syntax for GitHub Actions](/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun).\n\nFor example:\n\n```yaml\nsteps:\n  - name: Run build script\n    run: ./.github/scripts/build.sh\n    shell: bash\n```\n\n## Error handling in GitHub Actions\n\nWhen migrating to GitHub Actions, there are different approaches to error handling that you might need to be aware of.\n\n### Script error handling\n\nGitHub Actions stops a job immediately if one of the steps returns an error code. For more information, see [Workflow syntax for GitHub Actions](/en/actions/using-workflows/workflow-syntax-for-github-actions#exit-codes-and-error-action-preference).\n\n### Job error handling\n\nGitHub Actions uses `if` conditionals to execute jobs or steps in certain situations. For example, you can run a step when another step results in a `failure()`. For more information, see [Workflow syntax for GitHub Actions](/en/actions/using-workflows/workflow-syntax-for-github-actions#example-using-status-check-functions). You can also use [`continue-on-error`](/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idcontinue-on-error) to prevent a workflow run from stopping when a job fails.\n\n## Migrating syntax for conditionals and expressions\n\nTo run jobs under conditional expressions, Travis CI and GitHub Actions share a similar `if` condition syntax. GitHub Actions lets you use the `if` conditional to prevent a job or step from running unless a condition is met. For more information, see [Evaluate expressions in workflows and actions](/en/actions/learn-github-actions/expressions).\n\nThis example demonstrates how an `if` conditional can control whether a step is executed:\n\n```yaml\njobs:\n  conditional:\n    runs-on: ubuntu-latest\n    steps:\n      - run: echo \"This step runs with str equals 'ABC' and num equals 123\"\n        if: env.str == 'ABC' && env.num == 123\n```\n\n## Migrating phases to steps\n\nWhere Travis CI uses *phases* to run *steps*, GitHub Actions has *steps* which execute *actions*. You can find prebuilt actions in the [GitHub Marketplace](https://github.com/marketplace?type=actions), or you can create your own actions. For more information, see [Reusing automations](/en/actions/creating-actions).\n\nBelow is an example of the syntax for each system.\n\n### Travis CI syntax for phases and steps\n\n```yaml\nlanguage: python\npython:\n  - \"3.7\"\n\nscript:\n  - python script.py\n```\n\n### GitHub Actions syntax for steps and actions\n\n```yaml\njobs:\n  run_python:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/setup-python@v5\n        with:\n          python-version: '3.7'\n          architecture: 'x64'\n      - run: python script.py\n```\n\n## Caching dependencies\n\nTravis CI and GitHub Actions let you manually cache dependencies for later reuse.\n\nThese examples demonstrate the cache syntax for each system.\n\n### Travis CI syntax for caching\n\n```yaml\nlanguage: node_js\ncache: npm\n```\n\n### GitHub Actions syntax for caching\n\n```yaml\n- name: Cache node modules\n  uses: actions/cache@v4\n  with:\n    path: ~/.npm\n    key: v1-npm-deps-${{ hashFiles('**/package-lock.json') }}\n    restore-keys: v1-npm-deps-\n```\n\n## Examples of common tasks\n\nThis section compares how GitHub Actions and Travis CI perform common tasks.\n\n### Configuring environment variables\n\nYou can create custom environment variables in a GitHub Actions job.\n\n#### Travis CI syntax for an environment variable\n\n```yaml\nenv:\n  - MAVEN_PATH=\"/usr/local/maven\"\n```\n\n#### GitHub Actions workflow with an environment variable\n\n```yaml\njobs:\n  maven-build:\n    env:\n      MAVEN_PATH: '/usr/local/maven'\n```\n\n### Building with Node.js\n\n#### Travis CI for building with Node.js\n\n```yaml\ninstall:\n  - npm install\nscript:\n  - npm run build\n  - npm test\n```\n\n#### GitHub Actions workflow for building with Node.js\n\n```yaml\nname: Node.js CI\non: [push]\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v6\n      - name: Use Node.js\n        uses: actions/setup-node@v4\n        with:\n          node-version: '16.x'\n      - run: npm install\n      - run: npm run build\n      - run: npm test\n```\n\n## Next steps\n\nTo continue learning about the main features of GitHub Actions, see [Writing workflows](/en/actions/learn-github-actions)."}