Skip to content

Scheduled Fragment Updates #11

Scheduled Fragment Updates

Scheduled Fragment Updates #11

name: Scheduled Fragment Updates
on:
schedule:
- cron: '0 0 * * 0' # Run weekly on Sunday
workflow_dispatch:
inputs:
force_copilot:
description: 'Force creation of the Copilot update issue even if no image changes are detected'
type: boolean
default: false
permissions:
contents: write
pull-requests: write
issues: write
jobs:
update-fragments:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Setup Node
uses: actions/setup-node@v6
with:
node-version: 24
- name: Install dependencies
run: npm install
- name: Update Docker Tags
run: node scripts/update-tags.js
- name: Check for changes
id: check_changes
run: |
if [[ -n $(git status --porcelain) ]]; then
echo "changed=true" >> $GITHUB_OUTPUT
else
echo "changed=false" >> $GITHUB_OUTPUT
fi
- name: Create Copilot Update Issue
id: create_issue
if: steps.check_changes.outputs.changed == 'true' || github.event.inputs.force_copilot == 'true'
uses: actions/github-script@v7
with:
script: |
const issue = await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: "Update fragment image versions and docs",
body: "The scheduled job has detected updated Docker image tags. Please update stale image versions across all fragments.\n\n## Instructions\n\n**Do NOT use web search for version lookups. Use the MCP tools below instead.**\n\n### Step 1: Find fragments to update\nCheck each `.json` file in `fragments/compose/` and note the current image tag in the `variables` field (e.g. `POSTGRES_VERSION`, `REDIS_TAG`).\n\n### Step 2: Look up the best tag using Docker Hub MCP\nFor each image, call the Docker Hub MCP tool `list_repository_tags` to identify the best tag using this priority order:\n- Prefer major-version tags with the image variant suffix (e.g. `4-management-alpine`, `16-alpine`).\n- Fall back to minor-version only if no major-version tag exists for the variant (e.g. `16.3`).\n- Only use full semver (e.g. `4.2.5-management-alpine`) as a last resort.\n- Never use `latest`, `edge`, `nightly`, `beta`, or `rc`.\n```\nlist_repository_tags({ namespace: \"library\", repository: \"postgres\" })\n```\nUse `check_repository_tag` to verify the chosen tag exists before updating.\n\n### Step 3: Look up documentation using Context7 MCP (optional)\nIf you need to understand configuration options for a service, use Context7 MCP:\n```\nresolve-library-id({ libraryName: \"postgres\" })\nquery-docs({ context7CompatibleLibraryId: \"...\" })\n```\n\n### Step 4: Update the files\n- Update the tag value in the fragment `.json` file\n- Update any hardcoded tag references in the corresponding `.yml` file\n- Update the `docs/fragments/<name>.md` frontmatter if it has a version field\n\n### Step 5: Run validation\n```\nnpm run validate\n```\n\n### Step 6: Submit a pull request with all changes.",
labels: ["automated-update"],
headers: {
'X-GitHub-Api-Version': '2022-11-28'
}
});
console.log(`Created issue ${issue.data.number}`);
return issue.data.number;
- name: Assign @copilot to issue
if: steps.create_issue.outputs.result
uses: actions/github-script@v7
with:
github-token: ${{ secrets.RELEASE_PLEASE_TOKEN }}
script: |
const issueNumber = Number(${{ steps.create_issue.outputs.result }});
// Use GraphQL to assign the Copilot bot (BOT_kgDOC9w8XQ) as the authenticated user (PAT)
const issue = await github.rest.issues.get({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueNumber,
});
const mutation = `
mutation($id: ID!, $actorIds: [ID!]!) {
replaceActorsForAssignable(input: { assignableId: $id, actorIds: $actorIds }) {
assignable { ... on Issue { id } }
}
}
`;
try {
await github.graphql(mutation, {
id: issue.data.node_id,
actorIds: ["BOT_kgDOC9w8XQ"]
});
console.log(`Successfully assigned Copilot to issue ${issueNumber}`);
} catch (e) {
// Fallback: post a comment as the PAT user to trigger @copilot
console.log(`GraphQL assignment failed: ${e.message}. Posting comment as PAT user.`);
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueNumber,
body: "@copilot review these changes, update any stale image versions in fragment `.yml` and `.json` files, update the docs, and submit a pull request."
});
}