This guide walks you through deploying and managing interactive dashboards using GitHub Pages with the GitHub CLI (gh) and automated workflows. You'll learn to set up both manual deployment and automated updates, with comprehensive CLI workflow management and debugging techniques.
Ensure you are logged into your GitHub account through the GitHub CLI:
gh auth status
Expected output:
github.com
✓ Logged in to github.com account YOUR_USERNAME (keyring)
- Active account: true
- Git operations protocol: https
- Token: gho_************************************
- Token scopes: 'gist', 'read:org', 'repo', 'workflow'
Set your GitHub username as an environment variable for reusable commands:
Unix (Bash/Zsh) / Git Bash on Windows:
GHUSER=$(gh api user -q .login)
Windows (Command Prompt):
for /f %a in ('gh api user -q .login') do set GHUSER=%a
Create the GitHub Pages repository:
Unix (Bash/Zsh) / Git Bash on Windows:
gh repo create $GHUSER.github.io --public --description "Dashboard Website"
git clone https://github.com/$GHUSER/$GHUSER.github.io
cd $GHUSER.github.io
Windows (Command Prompt):
gh repo create %GHUSER%.github.io --public --description "Dashboard Website"
git clone https://github.com/%GHUSER%/%GHUSER%.github.io
cd %GHUSER%.github.io
Create a placeholder dashboard:
echo "<h1>My Dashboard</h1><p>Setting up automated deployment...</p>" > index.html
git add .
git commit -m "Initial commit: Add dashboard placeholder"
git push -u origin main
Create the workflows directory:
mkdir -p .github/workflows
Create .github/workflows/deploy-pages.yml:
# .github/workflows/deploy-pages.yml
name: Deploy to Pages
on:
push:
branches: ["main"]
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: "pages"
cancel-in-progress: false
jobs:
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Pages
uses: actions/configure-pages@v4
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: '.'
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4Create .github/workflows/update-dashboard.yml:
# .github/workflows/update-dashboard.yml
name: Update Dashboard
on:
# schedule:
# - cron: '*/15 * * * *' # Every 15 minutes (commented for demo)
workflow_dispatch:
concurrency:
group: dashboard-update
cancel-in-progress: true
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Pull latest changes first
run: |
git config --global user.name 'github-actions[bot]'
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
git pull --rebase origin ${{ github.ref_name }}
- name: Generate new dashboard content
run: |
if [ -f index.html ]; then
cp index.html index.html.backup
fi
echo "<h1>My Live Dashboard</h1>" > index.html
echo "<p>Last updated: $(date)</p>" >> index.html
echo "<p>Build number: ${{ github.run_number }}</p>" >> index.html
echo "<p>Status: Dashboard is live and updating!</p>" >> index.html
- name: Check for meaningful changes
id: changes
run: |
if [ -f index.html.backup ]; then
grep -v "Last updated:" index.html > index.html.clean || true
grep -v "Last updated:" index.html.backup > index.html.backup.clean || true
if ! diff -q index.html.clean index.html.backup.clean > /dev/null 2>&1; then
echo "meaningful_changes=true" >> $GITHUB_OUTPUT
else
echo "meaningful_changes=false" >> $GITHUB_OUTPUT
fi
else
echo "meaningful_changes=true" >> $GITHUB_OUTPUT
fi
- name: Commit and push changes
if: steps.changes.outputs.meaningful_changes == 'true'
run: |
git add index.html
if ! git diff --staged --quiet; then
git commit -m "Automated dashboard update - $(date -u '+%Y-%m-%d %H:%M:%S UTC')"
for i in {1..3}; do
if git push; then
echo "Successfully pushed changes"
break
else
echo "Push failed, attempt $i/3 - retrying"
if [ $i -eq 3 ]; then
echo "Failed to push after 3 attempts"
exit 1
fi
sleep 2
git pull --rebase origin ${{ github.ref_name }}
fi
done
fiAdd both workflows to your repository:
git add .github/workflows/
git commit -m "Add GitHub Actions workflows for deployment and updates"
git push
The workflow names you use with gh workflow run come directly from the name: field in each YAML file:
- deploy-pages.yml →
name: Deploy to Pages→ Use:gh workflow run "Deploy to Pages" - update-dashboard.yml →
name: Update Dashboard→ Use:gh workflow run "Update Dashboard"
Important: The workflow name is case-sensitive and must match exactly, including spaces.
First, enable GitHub Pages for your repository using the "Deploy to Pages" workflow:
# Enable GitHub Pages with Actions as source
gh api repos/$GHUSER/$GHUSER.github.io/pages -X POST --field source.branch=main --field source.path=/ --field build_type=workflow
# Verify Pages is enabled
gh api repos/$GHUSER/$GHUSER.github.io/pagesExpected response:
{
"url": "https://api.github.com/repos/YOUR_USERNAME/YOUR_USERNAME.github.io/pages",
"status": "built",
"cname": null,
"custom_404": false,
"html_url": "https://YOUR_USERNAME.github.io/",
"build_type": "workflow",
"source": {
"branch": "main",
"path": "/"
}
}List All Available Workflows:
gh workflow listExpected output:
NAME STATE ID
Deploy to Pages active 123456789
Update Dashboard active 987654321
Trigger Workflows Manually:
# Deploy your site (runs the Pages deployment)
gh workflow run "Deploy to Pages"
# Update your dashboard content
gh workflow run "Update Dashboard"Pro Tip: You can also use the workflow file name instead of the display name:
gh workflow run deploy-pages.yml
gh workflow run update-dashboard.ymlList Recent Runs (All Workflows):
gh run listFilter by Specific Workflow:
gh run list --workflow="Deploy to Pages"
gh run list --workflow="Update Dashboard"Watch Runs in Real-Time:
gh run list --workflow="Update Dashboard" --limit 1View Run Summary:
# Get the run ID from 'gh run list', then:
gh run view RUN_IDStream Live Logs (for running workflows):
gh run view RUN_ID --logDownload Logs for Offline Analysis:
gh run download RUN_IDWatch a Workflow Until Completion:
gh run watch RUN_IDHere's a complete debugging session example:
# 1. Trigger a workflow
gh workflow run "Update Dashboard"
# 2. Get the latest run ID
RUN_ID=$(gh run list --workflow="Update Dashboard" --limit 1 --json databaseId -q '.[0].databaseId')
# 3. Watch it complete
gh run watch $RUN_ID
# 4. If it fails, view detailed logs
gh run view $RUN_ID --log
# 5. Check the specific job that failed
gh run view $RUN_ID --log | grep -A 20 -B 5 "Error\|Failed\|❌"Check Workflow Run Status:
gh run list --workflow="Deploy to Pages" --json status,conclusion,createdAt --template '{{range .}}{{.createdAt}} | {{.status}} | {{.conclusion}}{{"\n"}}{{end}}'Get Run URL for Browser Debugging:
gh run list --workflow="Update Dashboard" --limit 1 --json url -q '.[0].url'Cancel a Running Workflow:
gh run cancel RUN_IDRe-run a Failed Workflow:
gh run rerun RUN_IDVerify Both Workflows are Working:
# 1. Update your dashboard content
gh workflow run "Update Dashboard"
# 2. Wait a moment, then deploy the changes
sleep 30
gh workflow run "Deploy to Pages"
# 3. Check both workflows completed successfully
gh run list --limit 5
# 4. Test your live site
curl -L https://$GHUSER.github.io | head -20If Pages deployment fails:
# Check Pages settings
gh api repos/$GHUSER/$GHUSER.github.io/pages
# Re-enable Pages if needed
gh api repos/$GHUSER/$GHUSER.github.io/pages -X DELETE
gh api repos/$GHUSER/$GHUSER.github.io/pages -X POST --field source.branch=main --field source.path=/ --field build_type=workflowIf dashboard updates aren't deploying:
# Manually trigger both workflows in sequence
gh workflow run "Update Dashboard" && sleep 60 && gh workflow run "Deploy to Pages"- Add Real Data: Replace the placeholder content in the "Generate new dashboard content" step with actual data fetching
- Schedule Updates: Uncomment the
schedulesection in update-dashboard.yml for automatic updates - Monitor Usage: Check your GitHub Actions minutes usage with frequent updates
- Enhance Security: Add environment variables and secrets for API keys
Your dashboard is now live at https://YOUR_USERNAME.github.io with full CLI management capabilities!