Watch FiveTechSoft/harbour and trigger all builds #926
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: Watch harbour/core and trigger all builds | |
| on: | |
| schedule: | |
| - cron: '0 * * * *' # hourly | |
| workflow_dispatch: | |
| inputs: | |
| force: | |
| description: 'Force dispatch even if SHA unchanged' | |
| required: false | |
| default: 'false' | |
| permissions: | |
| contents: write | |
| actions: write | |
| concurrency: | |
| group: watch-harbour-core | |
| cancel-in-progress: false | |
| jobs: | |
| watch: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout self | |
| uses: actions/checkout@v4 | |
| - name: Resolve latest harbour/core SHA | |
| id: core | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| sha=$(gh api repos/harbour/core/commits/master --jq .sha) | |
| if [ -z "$sha" ]; then | |
| echo "Failed to resolve harbour/core HEAD" >&2 | |
| exit 1 | |
| fi | |
| echo "sha=$sha" >> "$GITHUB_OUTPUT" | |
| echo "Latest harbour/core SHA: $sha" | |
| - name: Read last built SHA | |
| id: last | |
| run: | | |
| if [ -f .github/last_core_sha.txt ]; then | |
| last=$(tr -d '[:space:]' < .github/last_core_sha.txt) | |
| else | |
| last="" | |
| fi | |
| echo "sha=$last" >> "$GITHUB_OUTPUT" | |
| echo "Last built SHA: ${last:-<none>}" | |
| - name: Decide whether to dispatch | |
| id: decide | |
| run: | | |
| if [ "${{ inputs.force }}" = "true" ]; then | |
| echo "reason=manual force" >> "$GITHUB_OUTPUT" | |
| echo "dispatch=true" >> "$GITHUB_OUTPUT" | |
| elif [ "${{ steps.core.outputs.sha }}" != "${{ steps.last.outputs.sha }}" ]; then | |
| echo "reason=harbour/core changed" >> "$GITHUB_OUTPUT" | |
| echo "dispatch=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "reason=unchanged" >> "$GITHUB_OUTPUT" | |
| echo "dispatch=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Dispatch all build workflows | |
| if: steps.decide.outputs.dispatch == 'true' | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| set -e | |
| workflows=( | |
| harbour_bcc_32.yml | |
| harbour_darwin_osx.yml | |
| harbour_darwin_osx_x86.yml | |
| harbour_mingw_32.yml | |
| harbour_mingw_64.yml | |
| harbour_msvc_32.yml | |
| harbour_msvc_64.yml | |
| harbour_ubuntu_64.yml | |
| harbour_ubuntu_arm64.yml | |
| harbour_win64_ADS_msvc.yml | |
| harbour_win64_msvc.yml | |
| harbour_win_arm_msvc.yml | |
| harbour_android_ndk.yml | |
| harbour_ios.yml | |
| harbour_freebsd.yml | |
| ) | |
| echo "Dispatching ${#workflows[@]} workflows (reason: ${{ steps.decide.outputs.reason }})" | |
| for wf in "${workflows[@]}"; do | |
| echo " -> $wf" | |
| gh workflow run "$wf" --repo "$GITHUB_REPOSITORY" --ref "${GITHUB_REF_NAME}" | |
| done | |
| - name: Snapshot build statuses to data/builds.json | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| set -e | |
| mkdir -p data | |
| workflows=( | |
| harbour_bcc_32.yml | |
| harbour_darwin_osx.yml | |
| harbour_darwin_osx_x86.yml | |
| harbour_mingw_32.yml | |
| harbour_mingw_64.yml | |
| harbour_msvc_32.yml | |
| harbour_msvc_64.yml | |
| harbour_ubuntu_64.yml | |
| harbour_ubuntu_arm64.yml | |
| harbour_win64_ADS_msvc.yml | |
| harbour_win64_msvc.yml | |
| harbour_win_arm_msvc.yml | |
| harbour_android_ndk.yml | |
| harbour_ios.yml | |
| harbour_freebsd.yml | |
| ) | |
| runs_json=$(jq -n '[]') | |
| for wf in "${workflows[@]}"; do | |
| run=$(gh api "repos/$GITHUB_REPOSITORY/actions/workflows/$wf/runs?per_page=1" \ | |
| --jq '.workflow_runs[0] // null' 2>/dev/null || echo 'null') | |
| slim=$(echo "$run" | jq '. | if . == null then null else | |
| {id, run_number, status, conclusion, html_url, updated_at, created_at, | |
| head_sha, run_attempt} end') | |
| runs_json=$(echo "$runs_json" | jq --arg wf "$wf" --argjson r "$slim" \ | |
| '. + [{file:$wf, run:$r}]') | |
| done | |
| # Recent upstream commits — 10 latest from harbour/core master | |
| commits_json=$(gh api 'repos/harbour/core/commits?per_page=10' \ | |
| --jq '[.[] | { | |
| sha, | |
| short_sha: (.sha[0:7]), | |
| subject: ((.commit.message | split("\n"))[0]), | |
| author: ((.author.login // .commit.author.name) // "unknown"), | |
| date: .commit.author.date, | |
| html_url | |
| }]') | |
| # Repo stargazers count (for the Star CTA in the landing page) | |
| repo_stars=$(gh api "repos/$GITHUB_REPOSITORY" --jq '.stargazers_count // 0') | |
| # Sum download_count across every asset of every release (real, GitHub-tracked). | |
| # Anonymous Releases page asset clicks all hit this counter, so it is the | |
| # honest 'how many people pulled a build' number. Returns 0 when there | |
| # are no releases yet. | |
| total_downloads=$(gh api --paginate "repos/$GITHUB_REPOSITORY/releases" \ | |
| --jq '[.[].assets[]? | .download_count] | add // 0') | |
| releases_count=$(gh api --paginate "repos/$GITHUB_REPOSITORY/releases" --jq 'length') | |
| jq -n \ | |
| --arg ts "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \ | |
| --arg up "${{ steps.core.outputs.sha }}" \ | |
| --arg last "${{ steps.last.outputs.sha }}" \ | |
| --arg dispatched "${{ steps.decide.outputs.dispatch }}" \ | |
| --argjson runs "$runs_json" \ | |
| --argjson commits "$commits_json" \ | |
| --argjson stars "$repo_stars" \ | |
| --argjson dls "$total_downloads" \ | |
| --argjson rels "$releases_count" \ | |
| '{generated_at:$ts, upstream_sha:$up, last_built_sha:$last, | |
| just_dispatched:($dispatched=="true"), repo_stars:$stars, | |
| total_downloads:$dls, releases_count:$rels, | |
| workflows:$runs, recent_commits:$commits}' \ | |
| > data/builds.json | |
| echo "Snapshot:" | |
| cat data/builds.json | jq -r '. | {generated_at, upstream_sha, last_built_sha, just_dispatched, n_workflows: (.workflows|length), n_commits: (.recent_commits|length)}' | |
| - name: Commit snapshot (and tracked SHA when changed) | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | |
| if [ "${{ steps.decide.outputs.dispatch }}" = "true" ] \ | |
| && [ "${{ steps.core.outputs.sha }}" != "${{ steps.last.outputs.sha }}" ]; then | |
| echo "${{ steps.core.outputs.sha }}" > .github/last_core_sha.txt | |
| git add .github/last_core_sha.txt | |
| fi | |
| git add data/builds.json | |
| if git diff --cached --quiet; then | |
| echo "No changes to commit" | |
| else | |
| git commit -m "chore: snapshot builds.json (upstream ${{ steps.core.outputs.sha }})" | |
| git push | |
| fi | |
| - name: Skipped notice | |
| if: steps.decide.outputs.dispatch != 'true' | |
| run: | | |
| echo "No dispatch — harbour/core unchanged at ${{ steps.core.outputs.sha }}" |