Migration from GitHub Actions

Atkins supports a GitHub Actions-inspired syntax with jobs: and steps: , familiar for teams that use GHA workflows. Atkins runs similar job definitions locally and in any CI environment, but does not replace GitHub Actions as a CI platform.

Full Example

Here's a complete CI pipeline comparison showing jobs, dependencies, matrix builds, and conditional execution:

  # Atkins syntax - runnable with: atkins -f atkins-after.yml
name: CI Pipeline

vars:
  app_name: my-app
  branch: $(git rev-parse --abbrev-ref HEAD)
  go_versions:
    - '1.21'
    - '1.22'

jobs:
  lint:
    detach: true
    steps:
      - name: Run linter
        run: echo "Running golangci-lint..."

  test:
    detach: true
    steps:
      - name: Run tests for each Go version
        for: version in go_versions
        run: echo "Running tests with Go ${{ version }}"

  build:
    aliases: [default]
    depends_on: [lint, test]
    steps:
      - name: Build
        run: echo "Building ${{ app_name }}..."
      - name: Deploy
        if: branch == "main"
        run: echo "Deploying to production..."

Syntax Comparison

GitHub Actions:

  name: Build

on: [push]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Build
        run: go build ./...

Atkins:

  name: Build

jobs:
  build:
    steps:
      - name: Build
        run: go build ./...

Key Differences

No Triggers or Runner Selection

Atkins doesn't handle CI triggers (on: ) or runner selection (runs-on: ). It's a command runner, not a CI platform. Use it within your existing CI or as a local development tool.

No uses: Actions

Atkins has no equivalent to GitHub's action marketplace. Actions like actions/checkout or actions/setup-go must be replaced with shell commands or handled by your CI environment:

  # GHA actions have no Atkins equivalent
# Checkout: handled by CI before invoking Atkins
# Setup: use your environment's package manager or pre-installed tools

Inline Job Invocation

Atkins supports task: to invoke another job inline within a step. GitHub Actions has no equivalent; GHA jobs form a DAG via needs: and cannot call each other mid-execution.

Atkins:

  jobs:
  build:
    steps:
      - task: lint      # invoke lint job here
      - task: test      # then test job
      - run: go build ./...

  lint:
    steps:
      - run: golangci-lint run

  test:
    steps:
      - run: go test ./...

In GHA, this requires expressing the full dependency graph upfront with needs: .

Field Name Differences

GitHub Actions Atkins
runs-on Not supported
needs depends_on:

Jobs and Dependencies

GitHub Actions:

  jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - run: go test ./...

  build:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - run: go build ./...

Atkins:

  jobs:
  test:
    steps:
      - run: go test ./...

  build:
    depends_on: test
    steps:
      - run: go build ./...

Variables

GitHub Actions:

  env:
  MY_VAR: value

jobs:
  build:
    env:
      BUILD_VAR: ${{ env.MY_VAR }}
    steps:
      - run: echo $BUILD_VAR

Atkins:

  vars:
  my_var: value

jobs:
  build:
    env:
      vars:
        BUILD_VAR: ${{ my_var }}
    steps:
      - run: echo "$BUILD_VAR"

Secrets

GitHub Actions provides encrypted secrets via the secrets context. Atkins has no built-in secrets management.

GitHub Actions:

  jobs:
  deploy:
    steps:
      - run: ./deploy.sh
        env:
          API_KEY: ${{ secrets.API_KEY }}
          DB_PASSWORD: ${{ secrets.DB_PASSWORD }}

Atkins:

  jobs:
  deploy:
    steps:
      # Secrets must come from the environment
      - run: ./deploy.sh

Pass secrets via environment variables when invoking Atkins:

  API_KEY=xxx DB_PASSWORD=yyy atkins deploy

Or use a secrets manager that populates the environment (Vault, AWS Secrets Manager, direnv , etc.).

Matrix Builds

GHA's matrix strategy maps to Atkins' for: loops:

GitHub Actions:

  jobs:
  test:
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest]
        go: ['1.21', '1.22']
    runs-on: ${{ matrix.os }}
    steps:
      - run: go test ./...

Atkins:

  vars:
  go_versions:
    - '1.21'
    - '1.22'

jobs:
  test:
    steps:
      - for: version in go_versions
        task: test_version

  test_version:
    requires: [version]
    steps:
      - run: echo "Testing with Go ${{ version }}"

Conditional Execution

GitHub Actions:

  - name: Deploy
  if: github.ref == 'refs/heads/main'
  run: echo "Deploying..."

Atkins:

  vars:
  branch: $(git rev-parse --abbrev-ref HEAD)

jobs:
  deploy:
    steps:
      - name: Deploy
        if: branch == "main"
        run: echo "Deploying to production..."

Atkins uses expr-lang for condition evaluation. The branch variable is not built-in; define it explicitly in vars: (here using a dynamic shell command).

Parallel Execution

GitHub Actions runs jobs in parallel by default. Atkins runs jobs sequentially unless you use detach: true :

  jobs:
  lint:
    detach: true  # Run in background
    steps:
      - run: golangci-lint run

  test:
    detach: true  # Run in parallel with lint
    steps:
      - run: go test ./...

  build:
    depends_on: [lint, test]  # Wait for both
    steps:
      - run: go build ./...

Summary

Concept GitHub Actions Atkins
Triggers on: [push] Not supported (use CI)
Runner selection runs-on: Not supported (local execution)
Marketplace actions uses: actions/checkout@v4 No equivalent
Job dependencies needs: depends_on:
Inline job calls Not supported task: in steps
Secrets ${{ secrets.X }} Environment variables
Matrix strategy.matrix for: loops
Parallel Default detach: true

Best Practices

  1. Atkins runs commands; use your CI platform for triggers, runners, and secrets
  2. Run the same tasks locally that CI runs
  3. Call atkins from your GHA workflow for consistency