Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 124 additions & 0 deletions .github/workflows/monitor-upstream.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
name: Monitor Upstream Changes

on:
schedule:
- cron: '0 8 * * *' # Run daily at 08:00 UTC
workflow_dispatch: # Allow manual triggering

permissions:
contents: read
issues: write

jobs:
check-upstream:
runs-on: ubuntu-latest

steps:
- name: Checkout fork
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Fetch upstream
run: |
git remote add upstream https://github.com/microsoft/graphrag.git
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The git remote add upstream command will fail on subsequent runs because the remote will already exist. This should use git remote add upstream ... || true or check if the remote exists first, or use git remote set-url upstream ... after checking.

Suggested change
git remote add upstream https://github.com/microsoft/graphrag.git
git remote add upstream https://github.com/microsoft/graphrag.git 2>/dev/null || git remote set-url upstream https://github.com/microsoft/graphrag.git

Copilot uses AI. Check for mistakes.
git fetch upstream main

- name: Compute outstanding changes
run: |
COUNT=$(git rev-list --count HEAD..upstream/main 2>/dev/null || echo "0")
echo "$COUNT" > /tmp/commit-count.txt
git log --oneline --no-merges -50 HEAD..upstream/main > /tmp/commit-list.txt 2>/dev/null || true
Comment on lines +30 to +31
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using /tmp/ for temporary files works on Linux/macOS but the repository has workflows running on Windows (see python-integration-tests.yml, python-unit-tests.yml). If this workflow ever runs on Windows or if the pattern is copied to other workflows, it will fail. Consider using ${{ runner.temp }} which provides a cross-platform temporary directory path.

Copilot uses AI. Check for mistakes.

- name: Create or update tracking issue
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');

const count = parseInt(fs.readFileSync('/tmp/commit-count.txt', 'utf8').trim(), 10);
const rawList = fs.readFileSync('/tmp/commit-list.txt', 'utf8').trim();

// Ensure the tracking label exists
try {
await github.rest.issues.getLabel({
owner: context.repo.owner,
repo: context.repo.repo,
name: 'upstream-tracking',
});
} catch {
await github.rest.issues.createLabel({
owner: context.repo.owner,
repo: context.repo.repo,
name: 'upstream-tracking',
color: '0075ca',
description: 'Tracks outstanding changes from the upstream microsoft/graphrag repository',
});
Comment on lines +49 to +56
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error handling for the catch block on line 49 is too broad. If the label doesn't exist, it attempts to create it, but if the catch is triggered by a network error, rate limit, or permissions issue, it will fail when trying to create the label with the same error. Consider logging the error or checking specifically for a 404 status to ensure you're only creating the label when it doesn't exist.

Suggested change
} catch {
await github.rest.issues.createLabel({
owner: context.repo.owner,
repo: context.repo.repo,
name: 'upstream-tracking',
color: '0075ca',
description: 'Tracks outstanding changes from the upstream microsoft/graphrag repository',
});
} catch (error) {
if (error && error.status === 404) {
await github.rest.issues.createLabel({
owner: context.repo.owner,
repo: context.repo.repo,
name: 'upstream-tracking',
color: '0075ca',
description: 'Tracks outstanding changes from the upstream microsoft/graphrag repository',
});
} else {
console.error('Failed to ensure upstream-tracking label exists:', error);
throw error;
}

Copilot uses AI. Check for mistakes.
}

const now = new Date().toUTCString();
const comparisonUrl =
'https://github.com/microsoft/graphrag/compare/main...sharpninja:graphrag:main';
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comparison URL is incorrect. The format 'main...sharpninja:graphrag:main' compares the upstream main with the fork's main, but the direction is reversed. To show commits in upstream that aren't in the fork, it should be 'sharpninja:graphrag:main...microsoft:graphrag:main'. The three-dot syntax shows the symmetric difference, which may not be what's intended. Consider using 'sharpninja:graphrag:main..microsoft:graphrag:main' with two dots to show commits in upstream not in the fork.

Suggested change
'https://github.com/microsoft/graphrag/compare/main...sharpninja:graphrag:main';
'https://github.com/microsoft/graphrag/compare/sharpninja:graphrag:main..microsoft:graphrag:main';

Copilot uses AI. Check for mistakes.

const commitSection =
count === 0
? '_No outstanding commits — fork is up to date with upstream._'
: '```\n' + rawList + '\n```';

const body =
`@sharpninja\n\n` +
`## Outstanding Changes from \`microsoft/graphrag\`\n\n` +
`**${count} commit(s) pending** as of ${now}\n\n` +
`### Recent upstream commits not yet in this fork\n\n` +
commitSection + '\n\n' +
`---\n` +
`[View full comparison on GitHub](${comparisonUrl})\n\n` +
`*This issue is updated automatically every day by the [Monitor Upstream Changes]` +
`(../../actions/workflows/monitor-upstream.yml) workflow.*`;

const title = `\uD83D\uDD04 Upstream Tracking: ${count} pending change(s) from microsoft/graphrag`;

// Find an existing open tracking issue
const existing = await github.rest.issues.listForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open',
labels: 'upstream-tracking',
per_page: 1,
});

if (existing.data.length > 0) {
const issueNumber = existing.data[0].number;

// Update the issue body and title
await github.rest.issues.update({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueNumber,
title,
body,
Comment on lines +93 to +99
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment mentions "@sharpninja" will receive a notification on each run, but the issue body on line 69 also contains "@sharpninja". This means the notification will be triggered both when the issue is created AND when it's updated (via the body update), in addition to the comment. Consider removing "@sharpninja" from the body to avoid duplicate notifications on updates.

Copilot uses AI. Check for mistakes.
});

// Add a comment so @sharpninja receives a new notification
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueNumber,
body:
`@sharpninja **Update ${now}**: ` +
`**${count}** outstanding change(s) from upstream detected.\n\n` +
`[View full comparison](${comparisonUrl})`,
});
Comment on lines +102 to +111
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This workflow will create a new comment on every run (including when count is 0), which could generate unnecessary notifications. Consider only adding a comment when the count has changed or when there are actually outstanding changes. You could store the previous count in the issue body or check if the issue body has already been updated today.

Suggested change
// Add a comment so @sharpninja receives a new notification
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueNumber,
body:
`@sharpninja **Update ${now}**: ` +
`**${count}** outstanding change(s) from upstream detected.\n\n` +
`[View full comparison](${comparisonUrl})`,
});
// Only add a comment (and generate a notification) when there are outstanding changes
if (count > 0) {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueNumber,
body:
`@sharpninja **Update ${now}**: ` +
`**${count}** outstanding change(s) from upstream detected.\n\n` +
`[View full comparison](${comparisonUrl})`,
});
} else {
console.log('No outstanding upstream changes; skipping notification comment.');
}

Copilot uses AI. Check for mistakes.

console.log(`Updated issue #${issueNumber}`);
} else {
const created = await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title,
body,
labels: ['upstream-tracking'],
});

console.log(`Created issue #${created.data.number}`);
}
Loading