# example: # - uses: ./.github/actions/get-llvm # with: # target: x86_64-unknown-linux-gnu name: "Download LLVM" description: "Downloads a prebuilt LLVM release for a specific target." inputs: target: description: "Target triple (e.g., x86_64-unknown-linux-musl)" required: true runs: using: "composite" steps: - name: check override version id: override shell: bash env: # To test a draft LLVM release across every CI workflow, set this to the full # draft name (e.g. "llvm-21.1.8-revive.0f80912") and revert to "" before merging. OVERRIDE_VERSION: "" run: echo "version=${OVERRIDE_VERSION}" | tee -a "$GITHUB_OUTPUT" - name: resolve llvm version id: resolve-version if: ${{ steps.override.outputs.version == '' }} shell: bash run: | set -euo pipefail if [ ! -s .llvm-version ]; then echo "::error file=.llvm-version::Missing or empty .llvm-version. It must contain the version matching the llvm submodule pin." exit 1 fi echo "version_prefix=$(cat .llvm-version)" | tee -a "$GITHUB_OUTPUT" - name: find asset id: find uses: actions/github-script@v7 env: target: ${{ inputs.target }} version_prefix: ${{ steps.override.outputs.version || steps.resolve-version.outputs.version_prefix }} with: result-encoding: string script: | let page = 1; let allReleases = []; let target = process.env.target let versionPrefix = process.env.version_prefix if (!versionPrefix) { core.setFailed("version_prefix env is missing"); return; } // Fetch all releases from all pages core.info('Fetching releases from revive repository...'); let hasMorePages = true; while (hasMorePages) { const res = await github.rest.repos.listReleases({ owner: context.repo.owner, repo: context.repo.repo, per_page: 50, page, }); if (res.data.length > 0) { core.info(`Page ${page}: Fetched ${res.data.length} releases`); allReleases.push(...res.data); page++; } else { hasMorePages = false; } } core.info(`Total releases fetched: ${allReleases.length}`); // Sort all releases by publication date (newest first) allReleases.sort((a, b) => new Date(b.published_at) - new Date(a.published_at)); // Debug: Print all LLVM releases const llvmReleases = allReleases.filter(r => r.tag_name.startsWith('llvm-') && !r.prerelease); core.info(`Found ${llvmReleases.length} LLVM releases in total:`); llvmReleases.forEach(r => { core.info(` - ${r.tag_name} (published: ${r.published_at})`); }); // Find the latest LLVM release matching the version prefix. const llvmRelease = llvmReleases.find(release => release.tag_name.startsWith(versionPrefix)); if (!llvmRelease) { core.setFailed(`No LLVM releases matching prefix '${versionPrefix}' found! Please check the version, or first release LLVM`); return; } core.info(`Selected LLVM release matching prefix '${versionPrefix}': ${llvmRelease.tag_name}`); const asset = llvmRelease.assets.find(asset => asset.name.includes(target)); if (!asset) { core.setFailed(`Artifact for '${target}' not found in release ${llvmRelease.tag_name} (${llvmRelease.html_url})`); return; } // Use the API URL (rather than `browser_download_url`) so that // the authorization header is respected for draft releases. return asset.url; - name: download shell: bash run: | # Pass the authorization token to allow downloading draft release assets. curl -sSLo llvm.tar.gz -H "Authorization: Bearer ${{ github.token }}" -H "Accept: application/octet-stream" ${{ steps.find.outputs.result }} - name: unpack shell: bash run: | tar -xf llvm.tar.gz rm llvm.tar.gz