Skip to content

Another Copilot CLI issue #1

Another Copilot CLI issue

Another Copilot CLI issue #1

name: 🤖 GitHub Copilot Coder (Master)
# This is a reusable workflow that can be called from other repositories.
# It contains the full implementation logic for the Copilot Coder.
#
# To use this workflow from another repository, create a caller workflow:
# jobs:
# copilot:
# uses: <org>/GHES_CodingAgent/.github/workflows/copilot-coder-master.yml@main
# secrets: inherit
on:
# Direct trigger (for this repository)
issues:
types: [labeled]
# Reusable workflow trigger (for other repositories)
workflow_call:
secrets:
GH_TOKEN:
description: 'Classic PAT with repo and workflow scopes'
required: true
COPILOT_TOKEN:
description: 'Token for GitHub Copilot API access'
required: true
CONTEXT7_API_KEY:
description: 'API key for Context7 documentation service'
required: false
jobs:
copilot-cli:
# Only run when the issue has the 'copilot' label
if: contains(github.event.issue.labels.*.name, 'copilot')
runs-on: self-hosted
permissions:
contents: write
issues: write
pull-requests: write
env:
MODEL: claude-haiku-4.5
COPILOT_VERSION: 0.0.352
# Extract hostname from server URL (removes https:// prefix)
GHES_HOSTNAME: ${{ github.server_url }}
ISSUE_NUMBER: ${{ github.event.issue.number }}
ISSUE_TITLE: ${{ github.event.issue.title }}
ISSUE_BODY: ${{ github.event.issue.body }}
ISSUE_ASSIGNEE: ${{ github.event.issue.assignee.login }}
ISSUE_CREATOR: ${{ github.event.issue.user.login }}
REPO_NAME: ${{ github.repository }}
BRANCH_NAME: copilot/${{ github.event.issue.number }}
steps:
- name: 🚀 Start Workflow
run: |
echo "🚀 GitHub Copilot Coder workflow started!"
echo "═══════════════════════════════════════════════════════════"
echo "📋 Issue: #${ISSUE_NUMBER}"
echo "📌 Title: ${ISSUE_TITLE}"
echo "👤 Creator: ${ISSUE_CREATOR}"
echo "📦 Repository: ${REPO_NAME}"
echo "🌿 Branch: ${BRANCH_NAME}"
echo "═══════════════════════════════════════════════════════════"
env:
ISSUE_NUMBER: ${{ github.event.issue.number }}
ISSUE_TITLE: ${{ github.event.issue.title }}
ISSUE_CREATOR: ${{ github.event.issue.user.login }}
REPO_NAME: ${{ github.repository }}
BRANCH_NAME: copilot/${{ github.event.issue.number }}
- name: 🔐 Configure Git Credentials for GHES
run: |
# Extract hostname from server URL (remove https:// prefix)
GHES_HOST=$(echo "${{ github.server_url }}" | sed 's|https://||')
echo "GHES_HOST=${GHES_HOST}" >> $GITHUB_ENV
git config --global credential.helper store
echo "https://x-access-token:${{ github.token }}@${GHES_HOST}" >> ~/.git-credentials
chmod 600 ~/.git-credentials
echo "✅ Git credentials configured for GHES (${GHES_HOST})"
- name: 📥 Checkout Repository
uses: actions/checkout@v4
with:
token: ${{ github.token }}
persist-credentials: true
- name: 🔐 Configure GitHub CLI for GHES
run: |
# Configure gh to use GHES instance (GHES_HOST set in previous step)
gh auth login --hostname "${GHES_HOST}" --with-token <<< "${{ secrets.GH_TOKEN }}"
gh auth status --hostname "${GHES_HOST}"
echo "✅ GitHub CLI configured for GHES (${GHES_HOST})"
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
- name: 🏷️ Update Issue Labels - In Progress
run: |
gh issue edit ${{ env.ISSUE_NUMBER }} \
--add-label "in-progress" \
--remove-label "copilot"
# Add comment to notify that Copilot is working on this issue
COMMENT="## 🤖 Copilot is on it!
Copilot has been assigned to work on this issue. You can view progress under [GitHub Actions](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}), and once completed a PR will be linked here."
gh issue comment "${{ env.ISSUE_NUMBER }}" --body "${COMMENT}"
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
- name: 🐍 Setup Python (Latest)
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: 📦 Install uv/uvx
run: |
echo "Installing uvx (pipx runner)..."
pip install --upgrade pip
pip install uv
echo "✅ Python and uv installed"
python --version
uv --version
- name: ⚙️ Setup Node.js 22.x
uses: actions/setup-node@v4
with:
node-version: '22.x'
- name: 🔍 Detect NPM Global Path
id: npm-path
run: |
NPM_PREFIX=$(npm config get prefix)
echo "NPM_GLOBAL_PATH=${NPM_PREFIX}/lib/node_modules" >> $GITHUB_ENV
echo "NPM global path: ${NPM_PREFIX}/lib/node_modules"
- name: 📦 Cache Global NPM Packages
uses: actions/cache@v3
with:
key: npm-global-${{ runner.os }}-copilot-${{ env.COPILOT_VERSION }}
path: ${{ env.NPM_GLOBAL_PATH }}
restore-keys: |
npm-global-${{ runner.os }}-copilot-
- name: 📦 Install Copilot CLI
run: |
if ! command -v copilot &> /dev/null; then
echo "Installing @github/copilot@${{ env.COPILOT_VERSION }}..."
npm install -g @github/copilot@${{ env.COPILOT_VERSION }}
else
echo "✅ @github/copilot already installed (from cache)"
copilot --version
fi
- name: ⚙️ Configure MCP Servers
run: |
mkdir -p ~/.config
# Fetch mcp-config.json from the central GHES_CodingAgent repository
echo "📥 Fetching MCP configuration from GHES_CodingAgent..."
GHES_HOST=$(echo "${{ github.server_url }}" | sed 's|https://||')
OWNER="${{ github.repository_owner }}"
# Determine API base URL
if [[ "$GHES_HOST" == "github.com" ]]; then
API_BASE="https://api.github.com"
else
API_BASE="https://$GHES_HOST/api/v3"
fi
# Download mcp-config.json from GHES_CodingAgent repo
curl -s \
-H "Authorization: Bearer ${{ secrets.GH_TOKEN }}" \
-H "Accept: application/vnd.github.v3.raw" \
"$API_BASE/repos/$OWNER/GHES_CodingAgent/contents/mcp-config.json" \
> ~/.config/mcp-config.json
if [ -s ~/.config/mcp-config.json ]; then
echo "✅ MCP configuration downloaded to ~/.config/mcp-config.json"
cat ~/.config/mcp-config.json
else
echo "❌ Failed to download MCP configuration"
exit 1
fi
- name: 🧰 Check MCP Access
run: |
echo "🧰 Verifying MCP server access..."
copilot -p "List tools defined in the current chat session (do not run commands, I am asking about tools defined in the LLM). Just the names in a table, nothing else." --allow-all-tools
env:
GH_TOKEN: ${{ secrets.COPILOT_TOKEN }}
CONTEXT7_API_KEY: ${{ secrets.CONTEXT7_API_KEY }}
- name: 🌿 Create Feature Branch
run: |
echo "🌿 Creating feature branch..."
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git checkout -b ${{ env.BRANCH_NAME }}
echo "✅ Branch ${{ env.BRANCH_NAME }} created"
- name: 🤖 Implement Changes with Copilot
timeout-minutes: 30
working-directory: ${{ github.workspace }}
run: |
echo "🤖 Running GitHub Copilot CLI..."
echo "═══════════════════════════════════════════════════════════"
echo "📋 Issue: #${ISSUE_NUMBER}"
echo "📌 Title: ${ISSUE_TITLE}"
echo "🗂️ Working Directory: $(pwd)"
echo "═══════════════════════════════════════════════════════════"
echo "This is the description that Copilot CLI is going to use to implement the task:"
echo "${ISSUE_BODY}"
mkdir -p logs
# Save issue body to file to avoid injection
printf '%s' "${ISSUE_BODY}" > /tmp/issue_description.txt
# Run Copilot with file input
# Note: -p flag runs in non-interactive mode
# --add-dir allows Copilot to access files in the workspace directory
copilot -p "Implement the GitHub issue following the description details: $(cat /tmp/issue_description.txt)" \
--add-dir "$(pwd)" \
--allow-all-tools \
--log-level all \
--log-dir logs \
--model "${MODEL}"
# Clean up
rm -f /tmp/issue_description.txt
echo "✅ Implementation completed"
env:
GH_TOKEN: ${{ secrets.COPILOT_TOKEN }}
CONTEXT7_API_KEY: ${{ secrets.CONTEXT7_API_KEY }}
ISSUE_NUMBER: ${{ github.event.issue.number }}
ISSUE_TITLE: ${{ github.event.issue.title }}
ISSUE_BODY: ${{ github.event.issue.body }}
MODEL: ${{ env.MODEL }}
- name: 💾 Commit Changes
run: |
echo "📝 Preparing commit..."
# Co-author info from issue creator
CREATOR_NAME="${ISSUE_CREATOR}"
CREATOR_EMAIL="${ISSUE_CREATOR}@users.noreply.github.com"
echo "👤 Co-author: ${CREATOR_NAME} <${CREATOR_EMAIL}>"
# Add all files except metadata files
git add .
# Exclude metadata files from commit
for file in copilot-summary.md commit-message.md .final-commit-msg.txt .github/copilot-instructions.md; do
if git ls-files --cached "$file" > /dev/null 2>&1; then
git reset HEAD "$file" 2>/dev/null || true
fi
done
# Check if there are any staged changes
if ! git diff --cached --quiet; then
echo "✅ Changes staged for commit"
else
echo "⚠️ No changes staged for commit"
fi
# Prepare final commit message with co-author
if [ -f "commit-message.md" ]; then
echo "✅ Using Copilot-generated commit message"
{
cat commit-message.md
echo ""
echo ""
echo "Co-authored-by: ${CREATOR_NAME} <${CREATOR_EMAIL}>"
} > .final-commit-msg.txt
else
echo "⚠️ commit-message.md not found, using default message"
{
echo "feat: Implement issue ${ISSUE_NUMBER}"
echo ""
echo "${ISSUE_TITLE}"
echo ""
echo "Changes implemented by GitHub Copilot CLI"
echo ""
echo "Co-authored-by: ${CREATOR_NAME} <${CREATOR_EMAIL}>"
} > .final-commit-msg.txt
fi
# Create commit if there are staged changes
if git diff --cached --quiet; then
echo "⚠️ No staged changes to commit, skipping git commit"
else
git commit -F .final-commit-msg.txt
echo "✅ Changes committed successfully"
fi
# Clean up
rm -f .final-commit-msg.txt
env:
ISSUE_NUMBER: ${{ github.event.issue.number }}
ISSUE_TITLE: ${{ github.event.issue.title }}
ISSUE_CREATOR: ${{ github.event.issue.user.login }}
- name: 🚀 Push Branch
run: |
echo "🚀 Pushing branch to remote..."
# Configure git remote with GH_TOKEN for authentication
REMOTE_URL=$(git remote get-url origin)
if [[ "$REMOTE_URL" == https://* ]]; then
REPO_PATH=$(echo "$REMOTE_URL" | sed 's|https://[^/]*/||')
GITHUB_HOST=$(echo "$REMOTE_URL" | sed 's|https://||' | sed 's|/.*||')
git remote set-url origin "https://x-access-token:${GH_TOKEN}@${GITHUB_HOST}/${REPO_PATH}"
fi
git push -u origin "${{ env.BRANCH_NAME }}"
echo "✅ Branch pushed successfully"
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
- name: 📬 Create Pull Request
id: create-pr
run: |
# Check if copilot-summary.md exists
if [ -f "copilot-summary.md" ]; then
PR_BODY=$(cat copilot-summary.md)
else
PR_BODY="## 🤖 Automated Implementation
This PR was automatically generated by GitHub Copilot CLI.
### 📋 Related Issue
Closes #${ISSUE_NUMBER}
### 📝 Changes
Please review the changes made by Copilot CLI."
fi
# Save PR body to file to avoid injection
printf '%s' "${PR_BODY}" > /tmp/pr_body.txt
# Create PR and capture URL - use file for body
PR_URL=$(gh pr create \
--title "${ISSUE_TITLE}" \
--body-file /tmp/pr_body.txt \
--base main \
--head "${BRANCH_NAME}" \
--assignee "${ISSUE_CREATOR}")
# Clean up
rm -f /tmp/pr_body.txt
echo "PR_URL=${PR_URL}" >> $GITHUB_ENV
echo "✅ Pull Request created: ${PR_URL}"
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
ISSUE_NUMBER: ${{ github.event.issue.number }}
ISSUE_TITLE: ${{ github.event.issue.title }}
ISSUE_CREATOR: ${{ github.event.issue.user.login }}
BRANCH_NAME: ${{ env.BRANCH_NAME }}
- name: 💬 Add Completion Comment to Issue
run: |
echo "💬 Adding completion comment to issue #${ISSUE_NUMBER}..."
COMMENT="## 🎉 Implementation Complete!
The GitHub Copilot CLI has successfully implemented the changes for this issue.
### 📬 Pull Request
A Pull Request has been created with the implementation:
${PR_URL}
### 👀 Next Steps
1. Review the Pull Request
2. Test the implementation
3. Approve and merge if everything looks good
### 📦 Logs
Workflow logs and Copilot execution logs are available in the workflow run artifacts.
---
*This comment was automatically generated by the GitHub Copilot Coder workflow.*"
gh issue comment "${ISSUE_NUMBER}" --body "${COMMENT}"
echo "✅ Comment added successfully"
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
ISSUE_NUMBER: ${{ github.event.issue.number }}
PR_URL: ${{ env.PR_URL }}
- name: 🏷️ Update Issue Labels - Completed
run: |
gh issue edit ${{ env.ISSUE_NUMBER }} \
--add-label "ready-for-review" \
--remove-label "in-progress"
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
- name: 📦 Publish Logs
uses: actions/upload-artifact@v3
if: always()
with:
name: copilot-logs
path: logs/
retention-days: 30