Skip to main content

GitHub Actions

This page explains the core concepts and feature mapping you need to migrate from GitHub Actions to Semaphore.

Overview

GitHub Actions uses a YAML-based syntax to define pipelines and actions. With Semaphore, in addition to this method, you can also use the visual workflow editor to easily configure and preview pipelines.

Semaphore provides top-of-market machines for faster build times, along with extra features like fully customizable Role Based Access Control, parameterized promotions, and SSH debugging.

GitHub Actions vs Semaphore

This section describes how to implement common GitHub Actions functionalities on Semaphore.

Checkout

Checkout clones the repository in the CI environment.

GitHub Actions uses the Checkout action in every step and job that requires a copy of the repository.

jobs:
my_job:
steps:
- name: Checkout code
uses: actions/checkout@v4

Language versions

Both Github Actions and Semaphore allow you to use specific language versions.

GitHub Actions uses a language-specific setup action.

The following example sets the Ruby version to 3.3.4

jobs:
my_job:
steps:
- uses: ruby/setup-ruby@v1
with:
ruby-version: '3.3.4'

Caching

Both GitHub Actions and Semaphore support manual file caching.

GitHub Actions has a cache action to cache files. The following example caches Gems in a Ruby project:

- name: Cache gems
uses: actions/cache@v2
with:
path: vendor/bundle
key: bundle-gems-${{ hashFiles('**/Gemfile.lock') }}
restore-keys: bundle-gems-${{ hashFiles('**/Gemfile.lock') }}

Database and services

Both Github Actions and Semaphore support starting databases and services via Docker containers.

GitHub Actions uses service containers. The following example starts service containers for both Postgres and Redis.

jobs:
my_job:
runs-on: ubuntu-20.04
services:
postgresql:
image: postgres
env:
POSTGRES_PASSWORD: postgres
redis:
image: redis:5
env:
REDIS_URL: redis://redis:6379

Artifacts

Both Github Actions and Semaphore support persistent Artifacts storage.

GitHub Actions uses the actions upload-artifact and download-artifact to manage artifacts.

The following example uploads and downloads test.log

- name: Upload test.log
uses: actions/upload-artifact@v2
with:
name: Make
path: test.log
- name: Download test.log
uses: actions/download-artifact@v2
with:
name: Unit tests

Secrets

Secrets inject sensitive data and credentials into the workflow securely.

To use secrets in GitHub Actions, you must create the secret with its value in the repository or organization. Then, you can use it in your jobs using the ${{ secrets.SECRET_NAME }} syntax.

steps:
- name: Hello world action
env:
super_secret: ${{ secrets.SuperSecret }}

Complete example

The following comparison shows how to build and test a Ruby on Rails project on GitHub Actions and Semaphore.

On GitHub Actions, we need several actions to start services, manage Gems, and run the build and test commands.

name: CI

on:
pull_request:
push:
branches: [ main ]

jobs:
scan_ruby:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: .ruby-version
bundler-cache: true

- name: Scan for common Rails security vulnerabilities using static analysis
run: bin/brakeman --no-pager

scan_js:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: .ruby-version
bundler-cache: true

- name: Scan for security vulnerabilities in JavaScript dependencies
run: bin/importmap audit

lint:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: .ruby-version
bundler-cache: true

- name: Lint code for consistent style
run: bin/rubocop -f github

test:
runs-on: ubuntu-latest

steps:
- name: Install packages
run: sudo apt-get update && sudo apt-get install --no-install-recommends -y curl libjemalloc2 libvips sqlite3

- name: Checkout code
uses: actions/checkout@v4

- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: .ruby-version
bundler-cache: true

- name: Run Rake
env:
RAILS_ENV: test
run: |
cp .sample.env .env
bundle exec rake db:setup
bundle exec rake

- name: Run tests
env:
RAILS_ENV: test
run: bin/rails db:test:prepare test test:system

See also