Repository navigation
Controller Pack plugin release monitor #2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Controller Pack plugin release monitor | |
| on: | |
| workflow_dispatch: | |
| schedule: | |
| - cron: "37 4 * * *" | |
| permissions: | |
| contents: read | |
| issues: write | |
| jobs: | |
| scan: | |
| name: Scan upstream plugin repositories | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout Controller Pack repository | |
| uses: actions/checkout@v4 | |
| - name: Check plugin versions | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const fs = require("fs"); | |
| const configPath = ".github/controller_pack_plugins.json"; | |
| const issueLabel = "controller-pack-plugin-update"; | |
| if (!fs.existsSync(configPath)) { | |
| core.setFailed(`Missing ${configPath}`); | |
| return; | |
| } | |
| const config = JSON.parse(fs.readFileSync(configPath, "utf8")); | |
| function cleanVersion(value) { | |
| return String(value || "") | |
| .trim() | |
| .replace(/^v/i, "") | |
| .replace(/^release[-_/]/i, ""); | |
| } | |
| async function ensureLabel() { | |
| try { | |
| await github.rest.issues.getLabel({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| name: issueLabel, | |
| }); | |
| } catch (error) { | |
| if (error.status !== 404) throw error; | |
| await github.rest.issues.createLabel({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| name: issueLabel, | |
| color: "0055A4", | |
| description: "Detected Controller Pack plugin update", | |
| }); | |
| } | |
| } | |
| async function getLatestRelease(plugin) { | |
| const [owner, repo] = plugin.github.split("/"); | |
| if (plugin.include_prereleases) { | |
| const releases = await github.paginate(github.rest.repos.listReleases, { | |
| owner, | |
| repo, | |
| per_page: 50, | |
| }); | |
| const release = releases.find((item) => !item.draft); | |
| return release?.tag_name || ""; | |
| } | |
| try { | |
| const release = await github.rest.repos.getLatestRelease({ | |
| owner, | |
| repo, | |
| }); | |
| return release.data.tag_name || ""; | |
| } catch {} | |
| const tags = await github.rest.repos.listTags({ | |
| owner, | |
| repo, | |
| per_page: 1, | |
| }); | |
| return tags.data[0]?.name || ""; | |
| } | |
| async function issueExists(plugin, latest) { | |
| const result = await github.rest.search.issuesAndPullRequests({ | |
| q: [ | |
| `repo:${context.repo.owner}/${context.repo.repo}`, | |
| "is:issue", | |
| "is:open", | |
| `label:${issueLabel}`, | |
| `"${plugin.github}"`, | |
| `"${latest}"` | |
| ].join(" "), | |
| per_page: 1, | |
| }); | |
| return result.data.total_count > 0; | |
| } | |
| async function createIssue(plugin, latest) { | |
| const body = [ | |
| `A new upstream release was detected for **${plugin.name}**.`, | |
| "", | |
| "| Field | Value |", | |
| "| --- | --- |", | |
| `| Plugin | ${plugin.name} |`, | |
| `| Current packaged version | ${plugin.current} |`, | |
| `| Latest upstream version | ${latest} |`, | |
| `| Repository | ${plugin.github} |`, | |
| "", | |
| "Recommended actions:", | |
| "", | |
| "- Validate the release in EuroScope.", | |
| "- Verify compatibility with the Controller Pack.", | |
| "- Update packaged binaries/configuration if approved.", | |
| `- Update \`.github/controller_pack_plugins.json\` after deployment.`, | |
| "", | |
| `Repository: https://github.com/${plugin.github}`, | |
| `Release: https://github.com/${plugin.github}/releases/tag/${latest}`, | |
| ].join("\\n"); | |
| await github.rest.issues.create({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| title: `[Controller Pack] ${plugin.name} update available (${latest})`, | |
| body, | |
| labels: [issueLabel], | |
| }); | |
| } | |
| await ensureLabel(); | |
| for (const plugin of config.plugins) { | |
| const latest = await getLatestRelease(plugin); | |
| if (!latest) { | |
| core.warning(`No release found for ${plugin.name}`); | |
| continue; | |
| } | |
| if (cleanVersion(plugin.current) === cleanVersion(latest)) { | |
| core.info(`${plugin.name} already up to date`); | |
| continue; | |
| } | |
| if (await issueExists(plugin, latest)) { | |
| core.info(`Issue already exists for ${plugin.name} ${latest}`); | |
| continue; | |
| } | |
| await createIssue(plugin, latest); | |
| core.info(`Created issue for ${plugin.name}`); | |
| } |