[πΎ] Check extendedCallList event mapping #128
This file contains 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: '[πΎ] Check extendedCallList event mapping' | |
run-name: '[πΎ] Check extendedCallList event mapping' | |
on: | |
workflow_dispatch: | |
schedule: | |
- cron: '10 10,17 * * 1,2,3,4,5' | |
jobs: | |
eventMapping: | |
runs-on: ubuntu-latest | |
name: '[πΎ] Check extendedCallList event mapping' | |
steps: | |
- name: '[π₯] checkout' | |
uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
- name: '[π] extract module languages' | |
id: module_languages | |
run: | | |
languages=`find src/modules/extendedCallList/i18n/ -type f -name '*.root.json' -printf '%f\n' | cut -d'.' -f1 | sort | tr '\n' ' '` | |
echo "languages=${languages% }" >> "$GITHUB_OUTPUT" | |
- name: '[‡οΈ] download mission i18n files' | |
run: | | |
mkdir -p static/missions | |
cd static/missions | |
echo "${{ steps.module_languages.outputs.languages }}" | tr ' ' '\n' | xargs -I{} echo "https://v4.lss-manager.de/missions/{}.json" | xargs curl -sSLZ --remote-name-all | |
- name: '[π§] compare event missions to mission i18n files' | |
id: mission_compare | |
run: | | |
jq -cn '{}' > static/missions/unmapped.json | |
languages=`echo "${{ steps.module_languages.outputs.languages }}"` | |
for lang in ${languages}; do | |
echo "Extracting events for ${lang}..." | |
jq '. | map(select(.additional.optional_event_mission and (.additional.date_end > (now | todate)))) | map(.id | tostring) | sort | unique' static/missions/${lang}.json > static/missions/${lang}.events.json | |
echo "Extracting already mapped events for ${lang}..." | |
jq '(.eventMissions.default // {}) | flatten | map(. | tostring) | sort | unique' src/modules/extendedCallList/i18n/${lang}.root.json > static/missions/${lang}.mapped.json | |
echo "Getting unmapped events for ${lang}..." | |
jq -n --slurpfile events static/missions/${lang}.events.json --slurpfile mapped static/missions/${lang}.mapped.json '($events | flatten) - ($mapped | flatten)' > static/missions/${lang}.unmapped.json | |
echo "Merge unmapped events for ${lang}..." | |
jq -cn --arg lang "${lang}" --slurpfile langfile static/missions/${lang}.unmapped.json --rawfile merged static/missions/unmapped.json '$merged | fromjson | .[$lang] = ($langfile | flatten) | del(.. | select(length == 0))' > static/missions/unmapped.tmp.json | |
mv static/missions/unmapped.tmp.json static/missions/unmapped.json | |
done | |
echo "diffs_detected=`cat static/missions/unmapped.json`" >> "$GITHUB_OUTPUT" | |
- name: '[βοΈ] prepare issue body' | |
id: issue_body | |
uses: actions/github-script@v7 | |
with: | |
result-encoding: string | |
script: | | |
const { writeFileSync } = require('fs'); | |
const iconSuggestor = (lang, missionData) => { | |
// find other already mapped missions with the same start/end date and suggest their icon | |
const mappedEvents = require(`./src/modules/extendedCallList/i18n/${lang}.root.json`).eventMissions?.default ?? {}; | |
return (mission) => { | |
const icons = Object.entries(mappedEvents).map(([icon, missions]) => { | |
const mappedMissions = missions | |
.map(missionId => missionData[missionId]) | |
.filter(m => !!m) | |
.filter(m => m.additional.date_start === mission.additional.date_start && m.additional.date_end === mission.additional.date_end) | |
; | |
return { icon, hits: mappedMissions.length }; | |
}).sort((a, b) => b.hits - a.hits); | |
if (icons.length > 0 && icons[0].hits > 0) { | |
return icons[0].icon; | |
} | |
return 'β'; | |
}; | |
}; | |
const diffs = JSON.parse('${{ steps.mission_compare.outputs.diffs_detected }}'); | |
let result = '<!-- automanaged -->\n'; | |
if (Object.keys(diffs).length === 0) { | |
result += '# πΎ No unmapped missions found πΎ\n\n_This issue will be reopened automatically when unmapped missions are found._'; | |
} else { | |
result += 'The following missions are not mapped in the `extendedCallList` module. Please map them in the respective language files.\n\n'; | |
for (const lang in diffs) { | |
const missionData = require(`./static/missions/${lang}.json`); | |
const suggestIcon = iconSuggestor(lang, missionData); | |
const sortedMissions = diffs[lang].map(missionId => missionData[missionId]).filter(m => !!m).sort((a, b) => { | |
if (a.additional.date_start === b.additional.date_start) { | |
return a.id - b.id; | |
} | |
return a.additional.date_start.localeCompare(b.additional.date_start); | |
}); | |
result += `<details><summary>\n\n#### [\`${lang}\`](../blob/dev/src/modules/extendedCallList/i18n/${lang}.root.json) (${diffs[lang].length} mission${diffs[lang].length > 1 ? 's' : ''})\n\n</summary>\n\n`; | |
result += '| ID | Title | Start date | End date | Icon |\n'; | |
result += '| --- | --- | --- | --- | --- |\n'; | |
for (const mission of sortedMissions) { | |
result += `| \`${mission.id}\` | \`${mission.name}\` | \`${mission.additional.date_start}\` | \`${mission.additional.date_end}\` | ${suggestIcon(mission)} |\n`; | |
} | |
result += '\n</details>\n'; | |
} | |
} | |
writeFileSync('body.txt', result); | |
- name: '[π] find existing issue' | |
id: issue_exists | |
uses: actions-cool/issues-helper@v3 | |
with: | |
actions: 'find-issues' | |
token: ${{ secrets.GITHUB_TOKEN }} | |
issue-state: 'all' | |
body-includes: '<!-- automanaged -->' | |
title-includes: 'π©Ή [extendedCallList] Unmapped event missions' | |
- name: '[β¨] create new issue' | |
id: issue_create | |
if: ${{ steps.mission_compare.outputs.diffs_detected != '{}' && steps.issue_exists.outputs.issues == '[]' }} | |
uses: actions/github-script@v7 | |
with: | |
script: | | |
const { readFileSync } = require('fs'); | |
const title = 'π©Ή [extendedCallList] Unmapped event missions'; | |
const existingIssue = context.payload.issue; | |
const issue = await github.rest.issues.create({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
title: title, | |
body: readFileSync('body.txt').toString() | |
}); | |
return issue.data.number; | |
- name: '[βοΈ] update issue' | |
if: ${{ steps.issue_create.outputs.result || steps.issue_exists.outputs.issues != '[]' }} | |
uses: actions/github-script@v7 | |
with: | |
script: | | |
const { readFileSync } = require('fs'); | |
const title = 'π©Ή [extendedCallList] Unmapped event missions'; | |
const existingIssue = context.payload.issue; | |
const issue = await github.rest.issues.update({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
issue_number: ${{ steps.issue_create.outputs.result || (fromJSON(steps.issue_exists.outputs.issues)[0].number) }}, | |
state: '${{ steps.mission_compare.outputs.diffs_detected }}' === '{}' ? 'closed' : 'open', | |
body: readFileSync('body.txt').toString() | |
}); |