Build LMS Scheduler #188
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: Build LMS Scheduler | |
on: | |
workflow_dispatch: | |
schedule: | |
- cron: '40 2,3,4 * * *' | |
jobs: | |
check: | |
name: Check whether build is needed | |
if: ${{ github.repository_owner == 'LMS-Community' || github.event_name == 'workflow_dispatch' }} | |
runs-on: ubuntu-22.04 | |
steps: | |
- uses: actions/github-script@v7 | |
with: | |
script: | | |
const repoStatus = await github.request('GET https://raw.githubusercontent.com/LMS-Community/lms-server-repository/refs/heads/master/servers.json'); | |
if (repoStatus.status !== 200) { | |
console.error("Fetching repo file failed?" + JSON.stringify(repoStatus, null, 2)); | |
return false; | |
} | |
// get the oldest timestamp for each version from previous builds | |
const candidates = []; | |
const repoData = JSON.parse(repoStatus.data); | |
Object.keys(repoData).forEach(version => { | |
const matches = version.match(/(\d+\.\d+)\.\d+/); | |
if (matches && matches.length == 2) { | |
const versionBuilds = repoData[version]; | |
candidates.push({ | |
v: matches[1], | |
r: Object.keys(versionBuilds).reduce((accumulator, build) => { | |
const buildInfo = versionBuilds[build]; | |
accumulator = accumulator || parseInt(buildInfo.revision); | |
return Math.min(accumulator, parseInt(buildInfo.revision)); | |
}, 0) | |
}) | |
} | |
else { | |
delete repoData[version]; | |
} | |
}); | |
// for each version see whether there's a more recent commit than the revision of the previous build | |
for (let i = 0; i < candidates.length; i++) { | |
const latestBuildTimestamp = candidates[i].r * 1000; | |
const commitStatus = await github.rest.repos.listCommits({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
sha: 'public/' + candidates[i].v, | |
per_page: 1, | |
sort: 'created', | |
order: 'asc', | |
}); | |
if (commitStatus.status !== 200) { | |
console.log(JSON.stringify(commitStatus, null, 2)); | |
continue; | |
} | |
// see whether there's really been a commit since that timestamp - above "since" would be inclusive | |
const needsBuild = commitStatus.data.find(commit => new Date(commit.commit.committer.date).getTime() > latestBuildTimestamp); | |
if (needsBuild) { | |
console.log(`${candidates[i].v}: needs a build (${new Date(needsBuild.commit.committer.date).getTime()} > ${latestBuildTimestamp})`); | |
const workflowStatus = await github.rest.actions.createWorkflowDispatch({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
workflow_id: '00_build.yaml', | |
ref: 'public/' + candidates[i].v, | |
inputs: { | |
branch: 'public/' + candidates[i].v, | |
build_type: 'nightly', | |
}, | |
}); | |
if (workflowStatus.status < 200 || workflowStatus.status > 204) { | |
console.log(workflowStatus); | |
} | |
// we only want to run one build at a time - we'll re run the check in a bit | |
break; | |
} | |
else { | |
console.log(`${candidates[i].v}: is up to date (${candidates[i].r})`); | |
} | |
} |