Skip to content

Daily GitHub Copilot News Fetcher #451

Daily GitHub Copilot News Fetcher

Daily GitHub Copilot News Fetcher #451

name: Daily GitHub Copilot News Fetcher
on:
workflow_dispatch: # Manual trigger for demos
push:
branches: [ "main" ] # Run on push to main
schedule:
- cron: '0 0 * * *' # Runs at 00:00 UTC every day
# Ensure only one workflow runs at a time
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}
jobs:
fetch-news:
runs-on: ubuntu-latest
timeout-minutes: 10 # Prevent runaway jobs
permissions:
contents: write
steps:
# Security check for API key exposure
- name: Check for exposed secrets
run: |
if [ -z "$DEEPSEEK_API_KEY" ]; then
echo "Error: DEEPSEEK_API_KEY secret is not set!"
exit 1
fi
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 1 # Shallow clone for faster checkout
ref: main # Explicitly checkout main branch
token: ${{ secrets.GITHUB_TOKEN }} # Explicit token for push access
# Security scan for exposed secrets in the repo
- name: Check for exposed API keys
run: |
if grep -r "DEEPSEEK_API_KEY=sk-" . ; then
echo "WARNING: Found exposed API key in repository!"
echo "Please remove the exposed key and regenerate it immediately!"
exit 1
fi
# Create requirements.txt if it doesn't exist
- name: Ensure requirements.txt exists
run: |
mkdir -p .github/scripts
if [ ! -f .github/scripts/requirements.txt ]; then
echo "requests>=2.31.0" > .github/scripts/requirements.txt
echo "python-dateutil>=2.8.2" >> .github/scripts/requirements.txt
fi
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
cache: 'pip' # Enable pip caching
cache-dependency-path: '.github/scripts/requirements.txt'
# Cache the news archive to avoid repeated git operations
- name: Cache news archive
uses: actions/cache@v4
with:
path: news-archive
key: news-archive-${{ github.run_id }}
restore-keys: |
news-archive-
- name: Install dependencies
run: |
python -m pip install --upgrade pip --quiet
pip install --quiet -r .github/scripts/requirements.txt
# Ensure script directory and files exist
- name: Verify script setup
run: |
mkdir -p .github/scripts
# Only create fetch_news.py if it doesn't exist
if [ ! -f .github/scripts/fetch_news.py ]; then
echo "Error: fetch_news.py script is missing!"
exit 1
fi
# Ensure proper permissions
chmod +x .github/scripts/fetch_news.py
- name: Archive previous news
id: archive
continue-on-error: true # Don't fail if no previous news exists
run: |
if [ -f latest-github-news.md ]; then
mkdir -p news-archive
ARCHIVE_NAME="github-news-$(date -d 'yesterday' +'%Y-%m-%d').md"
mv latest-github-news.md "news-archive/$ARCHIVE_NAME"
echo "archived=true" >> $GITHUB_OUTPUT
echo "archive_name=$ARCHIVE_NAME" >> $GITHUB_OUTPUT
else
echo "archived=false" >> $GITHUB_OUTPUT
fi
- name: Fetch latest news
id: fetch
run: |
# Ensure the script runs with proper error handling
set -e
# Change to repo root before running script
cd $GITHUB_WORKSPACE
python .github/scripts/fetch_news.py
if [ ! -f latest-github-news.md ]; then
echo "Error: News fetching failed to create output file!"
exit 1
fi
# Upload the news files as artifacts for potential reuse
- name: Upload news artifacts
if: success() # Only if previous steps succeeded
uses: actions/upload-artifact@v4
with:
name: copilot-news
path: |
latest-github-news.md
news-archive/*.md
retention-days: 7 # Limit retention to save storage
- name: Configure Git and Handle Changes
if: success() # Only if previous steps succeeded
run: |
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
# Ensure we're on the latest main and in repo root
cd $GITHUB_WORKSPACE
git fetch origin main
git reset --hard origin/main
# Re-apply our changes
if [ -f latest-github-news.md ]; then
mkdir -p news-archive
if [ -n "$(ls -A news-archive 2>/dev/null)" ]; then
git add news-archive/
fi
git add latest-github-news.md
if [[ -n "$(git status --porcelain)" ]]; then
git commit -m "Update GitHub Copilot news for $(date +'%Y-%m-%d')"
# Try pushing multiple times with exponential backoff
max_attempts=3
attempt=1
while [ $attempt -le $max_attempts ]; do
if git push origin main; then
break
fi
sleep $((2 ** $attempt))
attempt=$((attempt + 1))
if [ $attempt -le $max_attempts ]; then
echo "Push failed, retrying..."
git pull --rebase origin main
fi
done
if [ $attempt -gt $max_attempts ]; then
echo "Failed to push after $max_attempts attempts"
exit 1
fi
else
echo "No changes to commit"
fi
else
echo "No news file found to commit"
exit 1
fi
# Clean up old artifacts to save space
- name: Cleanup old artifacts
if: always() # Run even if previous steps failed
uses: actions/github-script@v7
with:
script: |
const response = await github.rest.actions.listArtifactsForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
});
const artifacts = response.data.artifacts
.filter(artifact =>
artifact.name === 'copilot-news' &&
new Date(artifact.created_at) < new Date(Date.now() - 7 * 24 * 60 * 60 * 1000)
);
for (const artifact of artifacts) {
await github.rest.actions.deleteArtifact({
owner: context.repo.owner,
repo: context.repo.repo,
artifact_id: artifact.id,
});
}