Building CI/CD pipeline with GitHub Actions

Step-by-step tutorial for building a CI/CD pipeline using Alpacon GitHub Actions.

Learning objectives

After completing this tutorial, you’ll be able to:

  • Build secure deployment pipelines without SSH keys
  • Implement fine-grained command-level access control
  • Create automated build and deployment processes

Prerequisites

Step 1: Generate API token (2 min)

1-1. Create an API token

  1. Log in to your Alpacon workspace
  2. Open Preferences > API tokens
  3. Click New API token

1-2. Configure the token

In the New API token form, set:

Token name: github-actions-deploy
Expiration: 90 days (recommended)
Scopes: select the scopes the deployment needs (or a preset)

After the token is created, open it and add Allowed commands so it can run only the commands your pipeline needs. Each entry is a command pattern (wildcards * supported), one per entry:

git *
npm *
pm2 *
curl *
systemctl status nginx

đź’ˇ Tip: Separate development and production tokens for better management.

1-3. Save the token

  1. Click Create token
  2. Copy the generated token to a safe place (it’s shown only once)

Step 2: Configure GitHub repository (3 min)

2-1. Add GitHub Secrets

In your GitHub repository:

  1. Go to Settings > Secrets and variables > Actions
  2. Click New repository secret
  3. Add the following secrets:
NameValue
ALPACON_WORKSPACE_URLhttps://your-workspace.us1.alpacon.io
ALPACON_API_TOKENToken generated in Step 1

2-2. Create workflow file

Create .github/workflows directory in repository root:

.github/workflows/deploy.yml:

name: Deploy to Production
 
on:
  push:
    branches: [main]
 
env:
  NODE_VERSION: '18'
 
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
 
    - name: Setup Node.js
      uses: actions/setup-node@v4
      with:
        node-version: ${{ env.NODE_VERSION }}
        cache: 'npm'
 
    - name: Install dependencies
      run: npm ci
 
    - name: Run tests
      run: npm test
 
    - name: Build application
      run: npm run build
 
    # Save build artifacts
    - name: Upload build artifacts
      uses: actions/upload-artifact@v4
      with:
        name: build-artifacts
        path: dist/
 
  deploy:
    needs: test
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
 
    steps:
    # Download build artifacts
    - name: Download artifacts
      uses: actions/download-artifact@v4
      with:
        name: build-artifacts
        path: dist/
 
    # Install Alpacon CLI
    - name: Setup Alpacon CLI
      uses: alpacax/alpacon-setup-action@v1
 
    # Upload build to server
    - name: Upload to server
      uses: alpacax/alpacon-cp-action@v1
      with:
        workspace-url: ${{ secrets.ALPACON_WORKSPACE_URL }}
        api-token: ${{ secrets.ALPACON_API_TOKEN }}
        source: './dist/'
        target-server: 'prod-server'
        target-path: '/var/www/app/dist/'
        recursive: true
 
    # Restart application
    - name: Restart application
      uses: alpacax/alpacon-websh-action@v1
      with:
        workspace-url: ${{ secrets.ALPACON_WORKSPACE_URL }}
        api-token: ${{ secrets.ALPACON_API_TOKEN }}
        target: 'prod-server'
        script: |
          pm2 restart app
          pm2 status
 
    # Health check
    - name: Health check
      uses: alpacax/alpacon-websh-action@v1
      with:
        workspace-url: ${{ secrets.ALPACON_WORKSPACE_URL }}
        api-token: ${{ secrets.ALPACON_API_TOKEN }}
        target: 'prod-server'
        script: |
          curl -f http://localhost:3000/health || exit 1

Step 3: Run first deployment (2 min)

3-1. Push code

git add .github/workflows/deploy.yml
git commit -m "Add CI/CD pipeline with Alpacon"
git push origin main

3-2. Monitor deployment

  1. Go to Actions tab in GitHub repository
  2. Click on running workflow
  3. Check logs for each step

3-3. Verify in Alpacon

  1. Open Audit > Events in your Alpacon workspace
  2. Check the Commands tab for executed commands and results
  3. Review the token’s Activity log for its usage

Step 4: Advanced configuration (Optional)

Multi-environment deployment

.github/workflows/deploy-multi-env.yml:

name: Multi-Environment Deploy
 
on:
  push:
    branches: [main, develop]
 
jobs:
  deploy:
    runs-on: ubuntu-latest
 
    steps:
    - uses: actions/checkout@v4
 
    - name: Setup Alpacon CLI
      uses: alpacax/alpacon-setup-action@v1
 
    # Set environment based on branch
    - name: Set environment
      id: env
      run: |
        if [[ "${{ github.ref }}" == "refs/heads/main" ]]; then
          echo "target=prod-server" >> $GITHUB_OUTPUT
          echo "token=${{ secrets.ALPACON_PROD_TOKEN }}" >> $GITHUB_OUTPUT
        else
          echo "target=dev-server" >> $GITHUB_OUTPUT
          echo "token=${{ secrets.ALPACON_DEV_TOKEN }}" >> $GITHUB_OUTPUT
        fi
 
    - name: Deploy to ${{ steps.env.outputs.target }}
      uses: alpacax/alpacon-websh-action@v1
      with:
        workspace-url: ${{ secrets.ALPACON_WORKSPACE_URL }}
        api-token: ${{ steps.env.outputs.token }}
        target: ${{ steps.env.outputs.target }}
        script: |
          cd /app
          git pull
          npm ci
          npm run build
          pm2 restart app

Rollback workflow

.github/workflows/rollback.yml:

name: Rollback Deployment
 
on:
  workflow_dispatch:
    inputs:
      version:
        description: 'Version to rollback to'
        required: true
        default: 'previous'
 
jobs:
  rollback:
    runs-on: ubuntu-latest
 
    steps:
    - name: Setup Alpacon CLI
      uses: alpacax/alpacon-setup-action@v1
 
    - name: Rollback application
      uses: alpacax/alpacon-websh-action@v1
      with:
        workspace-url: ${{ secrets.ALPACON_WORKSPACE_URL }}
        api-token: ${{ secrets.ALPACON_API_TOKEN }}
        target: 'prod-server'
        script: |
          cd /app
          if [ "${{ github.event.inputs.version }}" = "previous" ]; then
            git reset --hard HEAD~1
          else
            git reset --hard ${{ github.event.inputs.version }}
          fi
          npm ci
          npm run build
          pm2 restart app

Troubleshooting

When deployment fails

  1. Check GitHub Actions logs

    • Check failed step in Actions tab
    • Review error messages
  2. Check Alpacon audit events

    • Review command execution logs under Audit > Events
    • Verify server connection status
  3. Verify token permissions

    • Ensure required commands are in the token’s Allowed commands
    • Check token expiration

Common issues

IssueCauseSolution
Permission deniedCommand not in token’s Allowed commandsUpdate the token’s Allowed commands
Server not foundWrong server nameVerify server name in workspace
Token expiredToken expiredGenerate new token and update GitHub Secret

Next steps

Summary

In this tutorial, you completed:

âś… API token generation and permission configuration âś… GitHub Secrets setup âś… CI/CD pipeline creation âś… Automated deployment execution and monitoring

You’ve built a safer and more manageable deployment pipeline using API tokens instead of SSH keys.

Last updated: