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.