these should be removed? [generate bindings] #1494
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: Tests | |
on: | |
push: | |
branches: | |
- main | |
- master | |
- full_bindings | |
pull_request: | |
branches: | |
- main | |
- master | |
- full_bindings | |
issue_comment: | |
types: | |
- created | |
# Run this once per three days | |
schedule: | |
- cron: '29 17 */3 * *' | |
# This can also manually run | |
workflow_dispatch: {} | |
env: | |
LIBRSYS_BINDINGS_OUTPUT_PATH: generated_bindings | |
jobs: | |
test_with_bindgen: | |
# When the event is not issue_comment, always run the tests. When it is, | |
# check if (1) the comment is on pull request, (2) the comment author is the | |
# member of the organization, and (3) the comment starts with '/bindings'. | |
# | |
# ref. | |
# https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#issue_comment | |
if: | | |
github.event_name != 'issue_comment' | |
|| (github.event.issue.pull_request && github.event.comment.author_association == 'MEMBER' && startsWith(github.event.comment.body, '/bindings')) | |
runs-on: ${{ matrix.config.os }} | |
name: ${{ matrix.config.os }} (R-${{ matrix.config.r }} rust-${{ matrix.config.rust-version }}-${{ matrix.config.target || 'default' }}) | |
strategy: | |
fail-fast: false | |
matrix: | |
config: | |
# On Windows, | |
# | |
# * for R >= 4.2, both the MSVC toolchain and the GNU toolchain should | |
# work. Since we primarily support MSVC, we focus on testing MSVC | |
# here. Also, at least one GNU case should be included so that we | |
# can detect when something gets broken. | |
# * for R < 4.2, the MSVC toolchain must be used to support | |
# cross-compilation to 32-bit. | |
# | |
# options: | |
# - targets: Targets to build and run tests against. If not | |
# specified, 'default' will be used. | |
# - no-test-targets: Targets to skip tests. | |
# - emit-bindings: If 'true', emit bindings. In principle, we choose | |
# only one stable Rust toolchain per combination of a platform and | |
# an R version (e.g. Windows and R-release) to emit bindings. | |
- {os: windows-latest, r: 'release', rust-version: 'stable-msvc', target: 'x86_64-pc-windows-gnu', emit-bindings: 'true'} | |
# - {os: windows-latest, r: 'release', rust-version: 'nightly-msvc', target: 'x86_64-pc-windows-gnu'} | |
- {os: windows-latest, r: 'devel', rust-version: 'stable-msvc', target: 'x86_64-pc-windows-gnu', emit-bindings: 'true'} | |
# - {os: windows-latest, r: 'release', rust-version: 'stable-gnu', target: 'x86_64-pc-windows-gnu'} | |
- {os: windows-latest, r: 'oldrel', rust-version: 'stable-msvc', target: 'x86_64-pc-windows-gnu', emit-bindings: 'true'} | |
- {os: windows-latest, r: '4.2', rust-version: 'stable-msvc', target: 'x86_64-pc-windows-gnu', emit-bindings: 'true' } | |
# - {os: macOS-latest, r: 'release', rust-version: 'nightly'} | |
- {os: macOS-latest, r: 'devel', rust-version: 'stable', emit-bindings: 'true'} | |
- {os: macOS-latest, r: 'oldrel', rust-version: 'stable', emit-bindings: 'true'} | |
- {os: macOS-latest, r: 'release', rust-version: 'stable', emit-bindings: 'true'} | |
- {os: macOS-latest, r: 'release', rust-version: 'stable', target: 'x86_64-apple-darwin', skip-tests: 'true', emit-bindings: 'true'} | |
- {os: macOS-latest, r: '4.2', rust-version: 'stable', emit-bindings: 'true' } | |
- {os: macOS-latest, r: '4.2', rust-version: 'stable', target: 'x86_64-apple-darwin', skip-tests: 'true', emit-bindings: 'true'} | |
# - {os: ubuntu-latest, r: 'release', rust-version: 'nightly'} | |
- {os: ubuntu-latest, r: 'release', rust-version: 'stable', emit-bindings: 'true'} | |
- {os: ubuntu-latest, r: 'release', rust-version: 'stable', target: 'aarch64-unknown-linux-gnu', skip-tests: 'true', emit-bindings: 'true'} | |
- {os: ubuntu-latest, r: 'devel', rust-version: 'stable', emit-bindings: 'true'} | |
- {os: ubuntu-latest, r: 'devel', rust-version: 'stable', target: 'aarch64-unknown-linux-gnu', skip-tests: 'true', emit-bindings: 'true'} | |
- {os: ubuntu-latest, r: 'oldrel', rust-version: 'stable', emit-bindings: 'true'} | |
- {os: ubuntu-latest, r: 'oldrel', rust-version: 'stable', target: 'aarch64-unknown-linux-gnu', skip-tests: 'true', emit-bindings: 'true'} | |
- {os: ubuntu-latest, r: '4.2', rust-version: 'stable', emit-bindings: 'true' } | |
- {os: ubuntu-latest, r: '4.2', rust-version: 'stable', target: 'aarch64-unknown-linux-gnu', skip-tests: 'true', emit-bindings: 'true'} | |
env: | |
RSPM: ${{ matrix.config.rspm }} | |
# PowerShell core is available on all platforms and can be used to unify scripts | |
defaults: | |
run: | |
shell: pwsh | |
steps: | |
- uses: actions/checkout@v4 | |
# When invoked by an issue comment event, the GitHub Actions runner runs | |
# on the default branch, so we need to switch the branch of the pull | |
# request. Since the branch name is not easily accessible via variables | |
# provided GitHub Actions, we use r-lib/actions, which is well-maintained. | |
- name: Switch branch (/bindings command) | |
if: github.event_name == 'issue_comment' | |
uses: r-lib/actions/pr-fetch@v2 | |
with: | |
repo-token: ${{ secrets.GITHUB_TOKEN }} | |
- name: Set up R | |
uses: r-lib/actions/setup-r@v2 | |
with: | |
r-version: ${{ matrix.config.r }} | |
use-public-rspm: true | |
- name: Set up Rust | |
uses: dtolnay/rust-toolchain@master | |
with: | |
toolchain: ${{ matrix.config.rust-version }} | |
components: rustfmt, clippy | |
targets: ${{ matrix.config.target }} | |
# All configurations for Windows go here | |
# 1. Configure linker | |
# 2. Create libgcc_eh mock | |
# 3. Add R bin path to PATH | |
# 4. Add Rtools' GCC to PATH (required to find linker) | |
# 5. Add include path (required to resolve standard headers like stdio.h) | |
- name: Configure Windows | |
if: runner.os == 'Windows' | |
run: | | |
# Configure linker | |
echo "RUSTFLAGS=-Clinker=x86_64-w64-mingw32.static.posix-gcc.exe" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append | |
# Create libgcc_eh mock | |
New-Item -Path libgcc_mock -Type Directory | |
New-Item -Path libgcc_mock\libgcc_eh.a -Type File | |
New-Item -Path libgcc_mock\libgcc_s.a -Type File | |
$pwd_slash = echo "${PWD}" | % {$_ -replace '\\','/'} | |
echo "LIBRARY_PATH=${pwd_slash}/libgcc_mock" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append | |
# Add R bin path to PATH | |
echo "$(Rscript.exe --vanilla -e 'cat(normalizePath(R.home()))')\bin\x64" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append ; | |
# Add Rtools' GCC to PATH | |
# Source: https://github.com/r-lib/actions/blob/b7e68d63e51bdf225997973e2add36d551f60f02/setup-r/lib/installer.js#L471 | |
$directories = @( | |
"C:\rtools44-aarch64\aarch64-w64-mingw32.static.posix", | |
"C:\rtools44\x86_64-w64-mingw32.static.posix", | |
"C:\rtools43\x86_64-w64-mingw32.static.posix", | |
"C:\rtools42\x86_64-w64-mingw32.static.posix", | |
"C:\rtools40\ucrt64", | |
"C:\Rtools\mingw_64" | |
) | |
$mingw_root = $null | |
foreach ($dir in $directories) { | |
if (Test-Path $dir) { | |
$mingw_root = $dir | |
Write-Host "Found Rtools directory at: $mingw_root" | |
break | |
} | |
} | |
echo "MINGW_ROOT=$mingw_root" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append | |
if ($null -eq $mingw_root) { | |
Write-Host "No Rtools directory found." | |
} else { | |
Write-Host "Mingw root set to: $mingw_root" | |
} | |
echo "$mingw_root\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append | |
# Add include path | |
echo "LIBRSYS_LIBCLANG_INCLUDE_PATH=$mingw_root\include" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append | |
env: | |
RUST_TARGET: ${{ matrix.config.target }} | |
# macOS configurations, mainly llvm and path to libclang | |
# Because of this R installation issue on macOS-11.0 | |
# https://github.com/r-lib/actions/issues/200 | |
# Symlinks to R/Rscript are not properly set up, so we do it by hand, using this trick | |
# https://github.com/r-lib/ps/commit/a24f2c4d1bdba63be14e7729b9ab81d0ed9f719e | |
# Environment variables are required fir Mac-OS-11.0, see | |
# https://github.com/extendr/libR-sys/issues/35 | |
# TODO: remove everything except `LIBCLANG_PATH` | |
- name: Configure macOS | |
if: runner.os == 'macOS' | |
run: | | |
brew install llvm | |
echo "LIBCLANG_PATH=$(brew --prefix llvm)/lib" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append | |
$env:LLVM_CONFIG_PATH = "$(brew --prefix llvm)/bin/llvm-config" | |
echo "LLVM_CONFIG_PATH=$env:LLVM_CONFIG_PATH" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append | |
echo "LIBRSYS_LIBCLANG_INCLUDE_PATH=$(. $env:LLVM_CONFIG_PATH --libdir)/clang/$(. $env:LLVM_CONFIG_PATH --version)/include" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append | |
if ((Get-ChildItem -Path /usr/local/bin -Filter R | Measure-Object).Count -eq 0) { | |
echo "::warning:: Found no R symlink in /usr/local/bin, setting up manually..." | |
ln -s /Library/Frameworks/R.framework/Versions/Current/Resources/bin/R /usr/local/bin/ | |
} | |
if ((Get-ChildItem -Path /usr/local/bin -Filter Rscript | Measure-Object).Count -eq 0) { | |
echo "::warning:: Found no Rscript symlink in /usr/local/bin, setting up manually..." | |
ln -s /Library/Frameworks/R.framework/Versions/Current/Resources/bin/Rscript /usr/local/bin/ | |
} | |
# This is required for ubuntu r-devel | |
# 'Del alias:R' removes R alias which prevents running R | |
- name: Configure Linux | |
if: runner.os == 'linux' | |
run: | | |
Del alias:R | |
echo "LD_LIBRARY_PATH=$(R -s -e 'cat(normalizePath(R.home()))')/lib" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append | |
if($env:RUST_TARGET -eq 'aarch64-unknown-linux-gnu') { | |
sudo apt-get update | |
sudo apt-get install gcc-aarch64-linux-gnu binutils-aarch64-linux-gnu | |
# https://github.com/rust-lang/rust-bindgen/issues/1229 | |
echo 'BINDGEN_EXTRA_CLANG_ARGS=--sysroot=/usr/aarch64-linux-gnu' >> $GITHUB_ENV | |
# https://github.com/rust-lang/rust/issues/28924 | |
echo 'CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc' >> $GITHUB_ENV | |
} | |
env: | |
RUST_TARGET: ${{ matrix.config.target }} | |
# Build & run bindings with layout tests | |
- name: Run tests | |
id: test | |
if: matrix.config.skip-tests != 'true' | |
run: | | |
. ./ci-cargo.ps1 | |
ci-cargo test -vv --features use-bindgen,layout_tests $(if ($env:RUST_TARGET -ne '') {"--target=$env:RUST_TARGET"} ) '--' --nocapture -ActionName "Running bindgen tests for target: $env:RUST_TARGET" | |
ci-cargo test -vv --features use-bindgen,non-api,layout_tests $(if ($env:RUST_TARGET -ne '') {"--target=$env:RUST_TARGET"} ) '--' --nocapture -ActionName "Running bindgen tests for target: $env:RUST_TARGET (with non-API)" | |
env: | |
RUST_TARGET: ${{ matrix.config.target }} | |
# Build and emit bindings to './generated_bindings' | |
- name: Build & Emit bindings | |
id: build | |
run: | | |
. ./ci-cargo.ps1 | |
ci-cargo build -vv --features use-bindgen $(if ($env:RUST_TARGET -ne '') {"--target=$env:RUST_TARGET"} ) -ActionName "Building for target: $env:RUST_TARGET" | |
env: | |
RUST_TARGET: ${{ matrix.config.target }} | |
- name: Upload generated bindings | |
if: | |
steps.build.outcome == 'success' && | |
matrix.config.emit-bindings == 'true' | |
uses: actions/upload-artifact@v4 | |
with: | |
name: generated_binding-${{ matrix.config.os }}-R-${{ matrix.config.r }}-rust-${{ matrix.config.rust-version }}-${{ matrix.config.target || 'default'}} | |
path: ${{ env.LIBRSYS_BINDINGS_OUTPUT_PATH }} | |
check_generate_bindings_flag: | |
name: Check if [generate bindings] is in latest commit message | |
runs-on: ubuntu-latest | |
outputs: | |
head_commit_message: ${{ steps.get_head_commit_message.outputs.HEAD_COMMIT_MESSAGE }} | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
ref: ${{ github.event.pull_request.head.ref }} | |
- name: Get Head Commit Message | |
id: get_head_commit_message | |
run: echo "HEAD_COMMIT_MESSAGE=$(git show -s --format=%s)" >> "$GITHUB_OUTPUT" | |
- name: Show commit message | |
run: | | |
echo "${{ steps.get_head_commit_message.outputs.HEAD_COMMIT_MESSAGE }}" | |
echo "${{ contains(steps.get_head_commit_message.outputs.HEAD_COMMIT_MESSAGE, '[generate bindings]') }}" | |
commit_generated_bindings: | |
name: Commit generated bindings | |
needs: [test_with_bindgen, check_generate_bindings_flag] | |
if: ${{ contains(needs.check_generate_bindings_flag.outputs.head_commit_message, '[generate bindings]') }} | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
ref: ${{ github.event.pull_request.head.ref }} | |
- uses: actions/download-artifact@v4 | |
- name: Update bindings | |
run: | | |
# Update or add the bindings | |
cp generated_binding-*/*.rs bindings/ | |
# Replace the default bindings | |
cd bindings | |
# TODO: this needs adjustment for the new output files... | |
# for x in linux-aarch64 linux-x86_64 macos-aarch64 macos-x86_64 windows-x86_64; do | |
# # Choose the newest version except for devel | |
# ln --force -s "$(ls -1 ./bindings-*-${x}-*.rs | grep -v devel | sort | tail -1)" ./bindings-*-${x}.rs | |
# done | |
cd .. | |
- name: Add generated bindings | |
run: | | |
git add bindings/ | |
git config --local user.name "${GITHUB_ACTOR}" | |
git config --local user.email "${GITHUB_ACTOR}@users.noreply.github.com" | |
git commit -m "Update bindings [skip ci]" | |
- name: Push to PR branch | |
run: git push |