diff --git a/.github/workflows/end-to-end.yml b/.github/workflows/end-to-end.yml index 586b3250e..6638fce0c 100644 --- a/.github/workflows/end-to-end.yml +++ b/.github/workflows/end-to-end.yml @@ -7,7 +7,11 @@ name: end-2-end jobs: end-2-end: - runs-on: macOS-latest + strategy: + fail-fast: false + matrix: + os: [macOS-latest, ubuntu-latest] + runs-on: ${{ matrix.os }} env: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} steps: @@ -31,6 +35,36 @@ jobs: key: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1-${{ hashFiles('.github/depends.Rds') }} restore-keys: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1- + - name: Generate system dependency commands (Linux only) + if: runner.os == 'Linux' + run: | + install.packages('pak') + sysreqs <- pak::pkg_sysreqs('local::.', dependencies = TRUE) + scripts <- c(sysreqs[['pre_install']], sysreqs[['install_scripts']], sysreqs[['post_install']]) + commands <- vapply(scripts, function(x) { + if (length(x) == 0L || !any(nzchar(x))) { + return(NA_character_) + } + paste(unlist(x), collapse = ' ') + }, character(1)) + commands <- commands[!is.na(commands)] + writeLines(commands, 'sysreqs.sh') + cat(commands, sep = '\n') + shell: Rscript {0} + + - name: Run system dependency commands (Linux only) + if: runner.os == 'Linux' + shell: bash + run: | + set -euo pipefail + if [[ -f sysreqs.sh ]]; then + while IFS= read -r cmd; do + [[ -z "$cmd" ]] && continue + echo "Running: $cmd" + sudo bash -lc "$cmd" + done < sysreqs.sh + fi + - name: Install dependencies run: | remotes::install_deps(dependencies = TRUE) @@ -57,15 +91,24 @@ jobs: run: | # hacky, maybe can use pre-commit try-repo? # https://stackoverflow.com/questions/30871868/sed-replace-first-occurence-in-place-with-big-files - sed -i '' -e "1,/rev:.*/{s/rev:.*/rev: $GITHUB_SHA/;}" .pre-commit-config.yaml + # sed -i '' is BSD (macOS); sed -i is GNU (Linux) — use a temp file for portability + sed "1,/rev:.*/{s/rev:.*/rev: $GITHUB_SHA/;}" .pre-commit-config.yaml > .pre-commit-config.yaml.tmp + mv .pre-commit-config.yaml.tmp .pre-commit-config.yaml git config --local user.email "github-actions[bot]@users.noreply.github.com" git config --local user.name "github-actions[bot]" git add . git commit -m 'current hash must be head' + - name: Install pre-commit (macOS) + if: runner.os == 'macOS' + run: brew install pre-commit + + - name: Install pre-commit (Linux) + if: runner.os == 'Linux' + run: pipx install pre-commit + - name: Run pre-commit run: | - brew install pre-commit pre-commit install --install-hooks echo 'running R/test.R' diff --git a/.github/workflows/hook-dependencies-update.yml b/.github/workflows/hook-dependencies-update.yml index a1209b063..a73e3d8aa 100644 --- a/.github/workflows/hook-dependencies-update.yml +++ b/.github/workflows/hook-dependencies-update.yml @@ -14,6 +14,13 @@ jobs: steps: - uses: actions/checkout@v7 + - name: Configure git identity and record starting commit + id: start + run: | + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + echo "sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT" + - uses: r-lib/actions/setup-r@v2 with: use-public-rspm: true @@ -30,13 +37,51 @@ jobs: brew install pipx pipx install pre-commit - name: auto-release - run: Rscript -e 'source("renv/activate.R"); renv::restore(); renv::install("."); precommit:::auto_release()' + run: Rscript -e 'source("renv/activate.R"); renv::restore(); renv::install("."); precommit:::auto_release()' + + - name: Commit dependency updates (commit A) + id: deps + env: + START_SHA: ${{ steps.start.outputs.sha }} + run: | + git add -A + if ! git diff --cached --quiet; then + git commit -m "Update renv dependencies" + fi + head_sha=$(git rev-parse HEAD) + if [ "$head_sha" = "$START_SHA" ]; then + echo "changed=false" >> "$GITHUB_OUTPUT" + else + echo "changed=true" >> "$GITHUB_OUTPUT" + echo "sha=$head_sha" >> "$GITHUB_OUTPUT" + fi + + - name: Pin .pre-commit-config.yaml rev to commit A (commit B) + if: steps.deps.outputs.changed == 'true' + env: + SHA: ${{ steps.deps.outputs.sha }} + run: | + f=.pre-commit-config.yaml + + sed -i.bak '\#repo: https://github.com/lorenzwalthert/precommit$#,/rev:/ s/\(rev: \).*/\1'"$SHA"'/' "$f" + + stat=$(git diff --no-index --numstat "$f.bak" "$f" || true) + + if echo "$stat" | awk '{ exit !($1 == 1 && $2 == 1) }'; then + rm "$f.bak" + else + echo "Expected exactly one changed line, got:" >&2 + git diff --no-index --unified=0 "$f.bak" "$f" >&2 || true + exit 1 + fi + git commit -am "Pin hooks rev to ${SHA::7}" + - name: Create Pull Request + if: steps.deps.outputs.changed == 'true' id: cpr uses: peter-evans/create-pull-request@v8.1.1 with: token: ${{ secrets.PRECOMMIT_HOOK_DEPENDENCY_UPDATE }} - commit-message: Update renv dependencies branch: hook-dependencies-update delete-branch: true assignees: lorenzwalthert @@ -45,16 +90,13 @@ jobs: This PR updates the hook dependencies in `renv.lock`, auto-generated by [create-pull-request][1]. Close and re-open this to trigger `on: pull_request` events to circumvent [limitation of GitHub actions](https://github.com/peter-evans/create-pull-request/blob/master/docs/concepts-guidelines.md#push-pull-request-branches-to-a-fork). [1]: https://github.com/peter-evans/create-pull-request - - name: Checkout PR head SHA - if: steps.cpr.outputs['pull-request-operation'] != 'none' - uses: actions/checkout@v7 - with: - ref: ${{ steps.cpr.outputs['pull-request-head-sha'] }} - fetch-depth: 0 # good practice if you need history - name: Push latest tag + if: steps.deps.outputs.changed == 'true' + env: + SHA: ${{ steps.deps.outputs.sha }} run: | Rscript -e "install.packages('desc')" TAG="v$(Rscript -e 'cat(as.character(desc::desc_get_version()))')" - git tag $TAG - git push origin $TAG + git tag "$TAG" "$SHA" + git push origin "$TAG" diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b38bc12e5..04e9f8730 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,7 +2,7 @@ # R specific hooks: https://github.com/lorenzwalthert/precommit repos: - repo: https://github.com/lorenzwalthert/precommit - rev: v0.4.3.9029 + rev: v0.4.3.9030 hooks: - id: style-files args: [--style_pkg=styler, --style_fun=tidyverse_style, --cache-root=styler-perm]