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
- Alpacon workspace created
 - Server registered and agent installed
 - GitHub repository access
 
Step 1: Generate API token (2 min)
1-1. Navigate to workspace settings
- Log in to your Alpacon workspace
 - Click Settings > API Tokens in the left menu
 - Click Create Token button
 
1-2. Configure token permissions
Enter the following information in the token creation screen:
Token Name: github-actions-deploy
Token Type: Deployment Token
Expiry: 90 days (recommended)
 
Command ACL:
  - git pull origin main
  - npm ci
  - npm run build
  - pm2 restart app
  - pm2 status
  - systemctl status nginx
💡 Tip: Separate development and production tokens for better management.
1-3. Save token
- Click Create
 - Copy the generated token to a safe place (shown only once!)
 
Step 2: Configure GitHub repository (3 min)
2-1. Add GitHub Secrets
In your GitHub repository:
- Go to Settings > Secrets and variables > Actions
 - Click New repository secret
 - Add the following secrets:
 
| Name | Value | 
|---|---|
ALPACON_WORKSPACE_URL | https://alpacon.io/your-workspace/ | 
ALPACON_API_TOKEN | Token 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@v3
 
    - name: Setup Node.js
      uses: actions/setup-node@v3
      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@v3
      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@v3
      with:
        name: build-artifacts
        path: dist/
 
    # Install Alpacon CLI
    - name: Setup Alpacon CLI
      uses: alpacax/alpacon-setup-action@v1.0.0
 
    # Upload build to server
    - name: Upload to server
      uses: alpacax/alpacon-cp-action@v1.0.0
      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.0.0
      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.0.0
      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
- Go to Actions tab in GitHub repository
 - Click on running workflow
 - Check logs for each step
 
3-3. Verify in Alpacon
- Go to Monitoring in Alpacon workspace
 - Check executed commands and results
 - Review API token usage in audit logs
 
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@v3
 
    - name: Setup Alpacon CLI
      uses: alpacax/alpacon-setup-action@v1.0.0
 
    # 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.0.0
      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.0.0
 
    - name: Rollback application
      uses: alpacax/alpacon-websh-action@v1.0.0
      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
- 
Check GitHub Actions logs
- Check failed step in Actions tab
 - Review error messages
 
 - 
Check Alpacon monitoring
- Review command execution logs
 - Verify server connection status
 
 - 
Verify token permissions
- Ensure required commands are in ACL
 - Check token expiration
 
 
Common issues
| Issue | Cause | Solution | 
|---|---|---|
Permission denied | Command not in token ACL | Update token permissions | 
Server not found | Wrong server name | Verify server name in workspace | 
Token expired | Token expired | Generate 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.