diff --git a/.github/workflows/R-CMD-check-status.yaml b/.github/workflows/R-CMD-check-status.yaml new file mode 100644 index 0000000..15860ac --- /dev/null +++ b/.github/workflows/R-CMD-check-status.yaml @@ -0,0 +1,76 @@ +# Workflow to update the status of a commit for the R-CMD-check workflow +# Necessary because remote PRs cannot update the status of the commit +on: + workflow_run: + workflows: + - rcc + types: + - requested + - completed + +name: rcc-status + +jobs: + rcc-status: + runs-on: ubuntu-latest + + name: "Update commit status" + + # Only run if triggered by rcc workflow + if: github.event.workflow_run.name == 'rcc' + + steps: + - name: "Update commit status" + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + set -x + + if [ "${{ github.event.workflow_run.status }}" == "completed" ]; then + if [ "${{ github.event.workflow_run.conclusion }}" == "success" ]; then + state="success" + else + state="failure" + fi + + # Read artifact ID + artifact_id=$(gh api \ + -H "Accept: application/vnd.github+json" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + repos/${{ github.repository }}/actions/runs/${{ github.event.workflow_run.id }}/artifacts | jq -r '.artifacts[] | select(.name == "rcc-smoke-sha") | .id') + + if [ -n "${artifact_id}" ]; then + # Download artifact + curl -L -o rcc-smoke-sha.zip \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer ${GH_TOKEN}" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + https://api.github.com/repos/${{ github.repository }}/actions/artifacts/${artifact_id}/zip + + # Unzip artifact + unzip rcc-smoke-sha.zip + + # Read artifact + sha=$(cat rcc-smoke-sha.txt) + + # Clean up + rm rcc-smoke-sha.zip rcc-smoke-sha.txt + fi + else + state="pending" + fi + + if [ -z "${sha}" ]; then + sha=${{ github.event.workflow_run.head_sha }} + fi + + html_url=${{ github.event.workflow_run.html_url }} + description=${{ github.event.workflow_run.name }} + + gh api \ + --method POST \ + -H "Accept: application/vnd.github+json" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + repos/${{ github.repository }}/statuses/${sha} \ + -f "state=${state}" -f "target_url=${html_url}" -f "description=${description}" -f "context=rcc" + shell: bash diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml index 5c685f5..b622c48 100644 --- a/.github/workflows/R-CMD-check.yaml +++ b/.github/workflows/R-CMD-check.yaml @@ -9,6 +9,8 @@ on: branches: - main - master + - release + - cran-* pull_request: branches: - main @@ -36,6 +38,8 @@ jobs: runs-on: ubuntu-latest outputs: sha: ${{ steps.commit.outputs.sha }} + versions-matrix: ${{ steps.versions-matrix.outputs.matrix }} + dep-suggests-matrix: ${{ steps.dep-suggests-matrix.outputs.matrix }} name: "Smoke test: stock R" @@ -59,31 +63,34 @@ jobs: - uses: ./.github/workflows/install with: token: ${{ secrets.GITHUB_TOKEN }} - install-r: false cache-version: rcc-smoke-2 - needs: check - extra-packages: any::rcmdcheck r-lib/roxygen2 any::decor r-lib/styler + needs: check, website + # Beware of using dev pkgdown here, has brought in dev dependencies in the past + extra-packages: any::rcmdcheck r-lib/roxygen2 any::decor r-lib/styler pkgdown - uses: ./.github/workflows/custom/after-install if: hashFiles('.github/workflows/custom/after-install/action.yml') != '' - - uses: ./.github/workflows/versions-matrix - if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository + - id: versions-matrix + # Only run for pull requests if the base repo is different from the head repo, always run for other events + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.repository + uses: ./.github/workflows/versions-matrix - - uses: ./.github/workflows/dep-suggests-matrix - if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository + - id: dep-suggests-matrix + uses: ./.github/workflows/dep-suggests-matrix - uses: ./.github/workflows/update-snapshots - if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository - uses: ./.github/workflows/style - if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository - uses: ./.github/workflows/roxygenize - if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository + + - name: Remove config files from previous iteration + run: | + rm -f .github/dep-suggests-matrix.json .github/versions-matrix.json + shell: bash - id: commit - if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository uses: ./.github/workflows/commit with: token: ${{ secrets.GITHUB_TOKEN }} @@ -92,81 +99,51 @@ jobs: with: results: ${{ runner.os }}-smoke-test - # Runs in a separate workflow, because it's using dev pkgdown - # which might bring in other dev dependencies - pkgdown: - needs: rcc-smoke - - runs-on: ubuntu-latest - - name: "pkgdown" - - # Begin custom: services - # End custom: services - - steps: - - uses: actions/checkout@v4 - with: - ref: ${{ needs.rcc-smoke.outputs.sha }} - - - uses: ./.github/workflows/rate-limit - with: - token: ${{ secrets.GITHUB_TOKEN }} + - uses: ./.github/workflows/pkgdown-build + if: github.event_name != 'push' - - uses: ./.github/workflows/git-identity + - uses: ./.github/workflows/pkgdown-deploy if: github.event_name == 'push' - - uses: ./.github/workflows/custom/before-install - if: hashFiles('.github/workflows/custom/before-install/action.yml') != '' + # Upload sha as artifact + - run: | + echo -n "${{ steps.commit.outputs.sha }}" > rcc-smoke-sha.txt + shell: bash - - uses: ./.github/workflows/install + - uses: actions/upload-artifact@v2 with: - token: ${{ secrets.GITHUB_TOKEN }} - install-r: false - cache-version: pkgdown-1 - needs: website - extra-packages: r-lib/pkgdown local::. - - - uses: ./.github/workflows/custom/after-install - if: hashFiles('.github/workflows/custom/after-install/action.yml') != '' + name: rcc-smoke-sha + path: rcc-smoke-sha.txt - - uses: ./.github/workflows/pkgdown-build - if: github.event_name != 'push' - - - uses: ./.github/workflows/pkgdown-deploy - if: github.event_name == 'push' + rcc-smoke-check-matrix: + runs-on: ubuntu-latest - versions-matrix: - runs-on: ubuntu-22.04 - outputs: - matrix: ${{ steps.set-matrix.outputs.matrix }} + name: "Check matrix" - name: Collect versions + needs: + - rcc-smoke steps: - uses: actions/checkout@v4 with: - fetch-depth: 0 + ref: ${{ needs.rcc-smoke.outputs.sha }} - - uses: ./.github/workflows/rate-limit + - uses: ./.github/workflows/matrix-check with: - token: ${{ secrets.GITHUB_TOKEN }} + matrix: ${{ needs.rcc-smoke.outputs.versions-matrix }} - - uses: r-lib/actions/setup-r@v2 + - uses: ./.github/workflows/matrix-check with: - install-r: false - use-public-rspm: true - - - id: set-matrix - uses: ./.github/workflows/versions-matrix-read + matrix: ${{ needs.rcc-smoke.outputs.dep-suggests-matrix }} rcc-full: needs: - rcc-smoke - - versions-matrix runs-on: ${{ matrix.os }} + if: ${{ needs.rcc-smoke.outputs.versions-matrix != '' }} + name: 'rcc: ${{ matrix.os }} (${{ matrix.r }}) ${{ matrix.desc }}' # Begin custom: services @@ -174,7 +151,7 @@ jobs: strategy: fail-fast: false - matrix: ${{fromJson(needs.versions-matrix.outputs.matrix)}} + matrix: ${{fromJson(needs.rcc-smoke.outputs.versions-matrix)}} steps: - uses: actions/checkout@v4 @@ -201,72 +178,22 @@ jobs: with: results: ${{ runner.os }}-r${{ matrix.r }} - - uses: ./.github/workflows/update-status - if: always() - with: - sha: ${{ needs.rcc-smoke.outputs.sha }} - - suggests-matrix: - runs-on: ubuntu-22.04 - outputs: - matrix: ${{ steps.set-matrix.outputs.matrix }} - - name: Collect suggests deps - - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - uses: ./.github/workflows/rate-limit - with: - token: ${{ secrets.GITHUB_TOKEN }} - - - uses: r-lib/actions/setup-r@v2 - with: - install-r: false - use-public-rspm: true - - - id: set-matrix - uses: ./.github/workflows/dep-suggests-matrix-read - - check-suggests-matrix: - runs-on: ubuntu-22.04 - needs: suggests-matrix - - name: Check suggests deps - - if: ${{ needs.suggests-matrix.outputs.matrix != '' }} - - steps: - - name: Install json2yaml - run: | - sudo npm install -g json2yaml - - - name: Check matrix definition - run: | - matrix='${{ needs.suggests-matrix.outputs.matrix }}' - echo $matrix - echo $matrix | jq . - echo $matrix | json2yaml - rcc-suggests: needs: - rcc-smoke - - suggests-matrix runs-on: ubuntu-22.04 - name: Without ${{ matrix.package }} + if: ${{ needs.rcc-smoke.outputs.dep-suggests-matrix != '' }} - if: ${{ needs.suggests-matrix.outputs.matrix != '' }} + name: Without ${{ matrix.package }} # Begin custom: services # End custom: services strategy: fail-fast: false - matrix: ${{fromJson(needs.suggests-matrix.outputs.matrix)}} + matrix: ${{fromJson(needs.rcc-smoke.outputs.dep-suggests-matrix)}} steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/commit/action.yml b/.github/workflows/commit/action.yml index d5049bc..ed6f9b8 100644 --- a/.github/workflows/commit/action.yml +++ b/.github/workflows/commit/action.yml @@ -20,9 +20,13 @@ runs: if [ -n "$(git status --porcelain)" ]; then echo "Changed" protected=${{ github.ref_protected }} - if [ "${protected}" = "true" ]; then + foreign=${{ github.event.pull_request.head.repo.full_name != github.repository }} + if [ "${foreign}" = "true" ]; then + # https://github.com/krlmlr/actions-sync/issues/44 + echo "Can't push to foreign branch" + elif [ "${protected}" = "true" ]; then current_branch=$(git branch --show-current) - new_branch=gha-commit + new_branch=gha-commit-$(git rev-parse --short HEAD) git checkout -b ${new_branch} git add . git commit -m "chore: Auto-update from GitHub Actions"$'\n'$'\n'"Run: ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}" @@ -38,6 +42,7 @@ runs: fi gh workflow run rcc -f ref=$(git rev-parse HEAD) + gh pr merge --merge --auto else git fetch if [ -n "${GITHUB_HEAD_REF}" ]; then @@ -50,8 +55,9 @@ runs: git add . git commit -m "chore: Auto-update from GitHub Actions"$'\n'$'\n'"Run: ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}" git push -u origin HEAD + + # Only set output if changed + echo sha=$(git rev-parse HEAD) >> $GITHUB_OUTPUT fi fi - # Unconditionally set the output because it could come from a manually triggered run - echo sha=$(git rev-parse HEAD) >> $GITHUB_OUTPUT shell: bash diff --git a/.github/workflows/dep-suggests-matrix-read/action.yml b/.github/workflows/dep-suggests-matrix-read/action.yml deleted file mode 100644 index 39e7a7b..0000000 --- a/.github/workflows/dep-suggests-matrix-read/action.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: "Actions to read a matrix with all suggested packages, computed with the dep-suggests-matrix action" -outputs: - matrix: - description: "Generated matrix" - value: ${{ steps.set-matrix.outputs.matrix }} - -runs: - using: "composite" - steps: - - name: Install json2yaml - run: | - sudo npm install -g json2yaml - shell: bash - - - id: set-matrix - run: | - # Empty contents if no suggested packages - matrix=$(cat .github/dep-suggests-matrix.json || true) - if [ -n "$matrix" ]; then - echo $matrix | jq . - echo $matrix | json2yaml - fi - echo "matrix=$matrix" | tee -a $GITHUB_OUTPUT - shell: bash diff --git a/.github/workflows/dep-suggests-matrix/action.R b/.github/workflows/dep-suggests-matrix/action.R index 1395194..eff3a50 100644 --- a/.github/workflows/dep-suggests-matrix/action.R +++ b/.github/workflows/dep-suggests-matrix/action.R @@ -21,9 +21,12 @@ get_deps <- function() { if (Sys.getenv("GITHUB_BASE_REF") != "") { print(Sys.getenv("GITHUB_BASE_REF")) - has_diff <- (system("git diff ${{ github.event.pull_request.base.sha }}... | egrep '^[+][^+]' | grep -q ::") == 0) + system("git fetch origin ${GITHUB_BASE_REF}") + # Use .. to avoid having to fetch the entire history + # https://github.com/krlmlr/actions-sync/issues/45 + has_diff <- (system("git diff origin/${GITHUB_BASE_REF}.. | egrep '^[+][^+]' | grep -q ::") == 0) if (has_diff) { - system("git diff ${{ github.event.pull_request.base.sha }}... | egrep '^[+][^+]' | grep -q ::") + system("git diff origin/${GITHUB_BASE_REF}.. | egrep '^[+][^+]' | grep -q ::") packages <- get_deps() } else { writeLines("No changes using :: found, not checking without suggested packages") @@ -39,9 +42,8 @@ if (length(packages) > 0) { paste0('"', packages, '"', collapse = ","), ']}' ) + writeLines(paste0("matrix=", json), Sys.getenv("GITHUB_OUTPUT")) + writeLines(json) } else { - json <- character() + writeLines("No suggested packages found.") } - -writeLines(json, ".github/dep-suggests-matrix.json") -writeLines(json) diff --git a/.github/workflows/get-extra/action.yml b/.github/workflows/get-extra/action.yml new file mode 100644 index 0000000..84c56d9 --- /dev/null +++ b/.github/workflows/get-extra/action.yml @@ -0,0 +1,16 @@ +name: "Action to determine extra packages to be installed" +outputs: + packages: + description: "List of extra packages" + value: ${{ steps.get-extra.outputs.packages }} + +runs: + using: "composite" + steps: + - name: Get extra packages + id: get-extra + run: | + set -x + packages=$( ( grep Config/gha/extra-packages DESCRIPTION || true ) | cut -d " " -f 2) + echo packages=$packages >> $GITHUB_OUTPUT + shell: bash diff --git a/.github/workflows/matrix-check/action.yml b/.github/workflows/matrix-check/action.yml new file mode 100644 index 0000000..b943048 --- /dev/null +++ b/.github/workflows/matrix-check/action.yml @@ -0,0 +1,23 @@ +name: "Actions to check a matrix with all R and OS versions, computed with the versions-matrix action" +inputs: + matrix: + description: "Generated matrix" + required: true + +runs: + using: "composite" + steps: + - name: Install json2yaml + run: | + sudo npm install -g json2yaml + shell: bash + + - run: | + matrix='${{ inputs.matrix }}' + if [ -n "${matrix}" ]; then + echo $matrix | jq . + echo $matrix | json2yaml + else + echo "No matrix found" + fi + shell: bash diff --git a/.github/workflows/pkgdown.yaml b/.github/workflows/pkgdown.yaml index de69b14..a2206af 100644 --- a/.github/workflows/pkgdown.yaml +++ b/.github/workflows/pkgdown.yaml @@ -42,7 +42,7 @@ jobs: install-r: false cache-version: pkgdown-2 needs: website - extra-packages: r-lib/pkgdown local::. + extra-packages: pkgdown - uses: ./.github/workflows/custom/after-install if: hashFiles('.github/workflows/custom/after-install/action.yml') != '' diff --git a/.github/workflows/update-status/action.yml b/.github/workflows/update-status/action.yml deleted file mode 100644 index d9462fc..0000000 --- a/.github/workflows/update-status/action.yml +++ /dev/null @@ -1,39 +0,0 @@ -name: 'Update status' -description: 'Update status' -inputs: - sha: - description: 'SHA to update' - required: true - -runs: - using: "composite" - steps: - # It's difficult to get the URL of the current job. - # The /jobs API and/or the `github` context are misaligned. - # The duckdbneo repository contains several failed attempts. - - run: | - set -x - if [ -n '${{ inputs.sha }}' ]; then - export GH_TOKEN=${{ github.token }} - - html_url=$(gh api \ - -H "Accept: application/vnd.github+json" \ - -H "X-GitHub-Api-Version: 2022-11-28" \ - repos/${{ github.repository }}/actions/runs/${{ github.run_id }} | jq -r .html_url) - - # Check if a failing status has been set already - status=$(gh api \ - -H "Accept: application/vnd.github+json" \ - -H "X-GitHub-Api-Version: 2022-11-28" \ - repos/${{ github.repository }}/commits/${{ inputs.sha }}/status | jq -r .state) - - if [ "${status}" != "error" ] && [ "${status}" != "failure" ]; then - gh api \ - --method POST \ - -H "Accept: application/vnd.github+json" \ - -H "X-GitHub-Api-Version: 2022-11-28" \ - repos/${{ github.repository }}/statuses/${{ inputs.sha }} \ - -f "state=${{ job.status }}" -f "target_url=$html_url" -f "description=${{ github.workflow }} / ${{ github.job }}" -f "context=actions-sync" - fi - fi - shell: bash diff --git a/.github/workflows/versions-matrix-read/action.yml b/.github/workflows/versions-matrix-read/action.yml deleted file mode 100644 index 4aa4639..0000000 --- a/.github/workflows/versions-matrix-read/action.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: "Actions to read a matrix with all R and OS versions, computed with the versions-matrix action" -outputs: - matrix: - description: "Generated matrix" - value: ${{ steps.set-matrix.outputs.matrix }} - -runs: - using: "composite" - steps: - - name: Install json2yaml - run: | - sudo npm install -g json2yaml - shell: bash - - - id: set-matrix - run: | - matrix=$(cat .github/versions-matrix.json || echo '{"include":[{"os":"macos-latest","r":"release"}]}') - echo $matrix | jq . - echo $matrix | json2yaml - echo "matrix=$matrix" | tee -a $GITHUB_OUTPUT - shell: bash diff --git a/.github/workflows/versions-matrix/action.R b/.github/workflows/versions-matrix/action.R index 4a59fe6..b8e2dcf 100644 --- a/.github/workflows/versions-matrix/action.R +++ b/.github/workflows/versions-matrix/action.R @@ -1,5 +1,25 @@ -# FIXME: Dynamic lookup by parsing https://svn.r-project.org/R/tags/ -r_versions <- c("devel", paste0("4.", 4:0)) +# Determine active versions of R to test against +tags <- xml2::read_html("https://svn.r-project.org/R/tags/") + +bullets <- + tags |> + xml2::xml_find_all("//li") |> + xml2::xml_text() + +version_bullets <- grep("^R-([0-9]+-[0-9]+-[0-9]+)/$", bullets, value = TRUE) +versions <- unique(gsub("^R-([0-9]+)-([0-9]+)-[0-9]+/$", "\\1.\\2", version_bullets)) + +r_release <- head(sort(as.package_version(versions), decreasing = TRUE), 5) + +deps <- desc::desc_get_deps() +r_crit <- deps$version[deps$package == "R"] +if (length(r_crit) == 1) { + min_r <- as.package_version(gsub("^>= ([0-9]+[.][0-9]+)(?:.*)$", "\\1", r_crit)) + r_release <- r_release[r_release >= min_r] +} + +r_versions <- c("devel", as.character(r_release)) + macos <- data.frame(os = "macos-latest", r = r_versions[2:3]) windows <- data.frame(os = "windows-latest", r = r_versions[1:3]) linux_devel <- data.frame(os = "ubuntu-22.04", r = r_versions[1], `http-user-agent` = "release", check.names = FALSE) @@ -36,5 +56,5 @@ to_json <- function(x) { configs <- unlist(lapply(include_list, to_json)) json <- paste0('{"include":[', paste(configs, collapse = ","), ']}') -writeLines(json, ".github/versions-matrix.json") +writeLines(paste0("matrix=", json), Sys.getenv("GITHUB_OUTPUT")) writeLines(json) diff --git a/.github/workflows/versions-matrix/action.yml b/.github/workflows/versions-matrix/action.yml index 6ac164b..af7378a 100644 --- a/.github/workflows/versions-matrix/action.yml +++ b/.github/workflows/versions-matrix/action.yml @@ -1,8 +1,18 @@ name: "Actions to compute a matrix with all R and OS versions" +outputs: + matrix: + description: "Generated matrix" + value: ${{ steps.set-matrix.outputs.matrix }} + runs: using: "composite" steps: + - name: Install json2yaml + run: | + sudo npm install -g json2yaml + shell: bash + - id: set-matrix run: | Rscript ./.github/workflows/versions-matrix/action.R