diff --git a/.Rbuildignore b/.Rbuildignore index a5e34a4362..c11fff1596 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -35,3 +35,4 @@ ^TODO\.md$ ^staged_dependencies\.yaml$ ^\.gitlab-ci\.yml$ +coverage.* diff --git a/.github/workflows/build-check-install.yaml b/.github/workflows/build-check-install.yaml index 5a68557b5a..bf271e3c71 100644 --- a/.github/workflows/build-check-install.yaml +++ b/.github/workflows/build-check-install.yaml @@ -2,6 +2,8 @@ name: R CMD Check on: push: + tags: + - "v*" branches: - main - pre-release @@ -116,10 +118,16 @@ jobs: if (file.exists("staged_dependencies.yaml")) { cat("\nInstall Staged Dependencies\n\n\n") if (!require("staged.dependencies")) { - remotes::install_github("openpharma/staged.dependencies", ref = "v0.2.1", Ncpus = ncores, upgrade = "never") + remotes::install_github("openpharma/staged.dependencies", ref = "97tags@main", Ncpus = ncores, upgrade = "never") + } + cat("\nCalculating Staged Dependency Table for ref: ${{ github.ref }} ...\n\n") + ref = "${{ github.ref }}" + if (startsWith(ref, "refs/tags")){ + x <- staged.dependencies::dependency_table(ref=ref) + } + else { + x <- staged.dependencies::dependency_table() } - cat("\nCalculating Staged Dependency Table...\n\n") - x <- staged.dependencies::dependency_table() print(x, width = 120) cat("\n\n") staged.dependencies::install_deps(dep_structure = x, install_project = FALSE, verbose = TRUE) @@ -175,3 +183,43 @@ jobs: - name: Install R package run: R CMD INSTALL ${{ env.PKGBUILD }} shell: bash + + - name: Upload package + if: startsWith(github.ref, 'refs/tags/v') + uses: actions/upload-artifact@v2 + with: + path: ${{ env.PKGBUILD }} + name: ${{ env.PKGBUILD }} + + upload-release-assets: + name: Upload build tar.gz + needs: build-install-check + runs-on: ubuntu-latest + if: startsWith(github.ref, 'refs/tags/v') + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Wait for release to succeed + timeout-minutes: 2 + uses: lewagon/wait-on-check-action@v1.1.1 + with: + ref: "${{ github.ref }}" + check-name: 'Release' + repo-token: ${{ secrets.REPO_GITHUB_TOKEN }} + wait-interval: 10 + - name: Set env + run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/v}" >> $GITHUB_ENV + - name: Get package name + run: echo "PKGBUILD=${{ github.event.repository.name }}_${{ env.RELEASE_VERSION }}.tar.gz" >> $GITHUB_ENV + - name: Download artifact + uses: actions/download-artifact@v2 + with: + name: "${{ env.PKGBUILD }}" + - name: Upload binaries to release + uses: svenstaro/upload-release-action@v2 + with: + repo_token: ${{ secrets.REPO_GITHUB_TOKEN }} + file: "${{ env.PKGBUILD }}" + asset_name: "${{ env.PKGBUILD }}" + tag: "${{ github.ref }}" + overwrite: false diff --git a/.github/workflows/links.yml b/.github/workflows/links.yml index 12b9bf2119..1063335e8f 100755 --- a/.github/workflows/links.yml +++ b/.github/workflows/links.yml @@ -18,7 +18,16 @@ jobs: - name: Check URLs in docs uses: lycheeverse/lychee-action@v1 with: - args: --exclude-private --exclude "https://github.com.*.git|https://insightsengineering.github.io.*" --verbose --no-progress **/*.md **/*.html **/*.Rmd **/*.yaml **/*.yml + args: >- + --exclude-private + --exclude "https://github.com.*.git|https://insightsengineering.github.io.*|lewagon.*|knightdave.*" + --verbose + --no-progress + **/*.md + **/*.html + **/*.Rmd + **/*.yaml + **/*.yml env: GITHUB_TOKEN: ${{ secrets.REPO_GITHUB_TOKEN }} diff --git a/.github/workflows/pkgdown.yml b/.github/workflows/pkgdown.yml index 89c2b0e325..26b0418fb8 100755 --- a/.github/workflows/pkgdown.yml +++ b/.github/workflows/pkgdown.yml @@ -2,6 +2,8 @@ name: Pkgdown Docs on: push: + tags: + - "v*" branches: - main pull_request: @@ -104,10 +106,16 @@ jobs: if (file.exists("staged_dependencies.yaml")) { cat("\nInstall Staged Dependencies\n\n\n") if (!require("staged.dependencies")) { - remotes::install_github("openpharma/staged.dependencies", ref = "v0.2", Ncpus = ncores, upgrade = "never") + remotes::install_github("openpharma/staged.dependencies", ref = "97tags@main", Ncpus = ncores, upgrade = "never") + } + cat("\nCalculating Staged Dependency Table for ref: ${{ github.ref }} ...\n\n") + ref = "${{ github.ref }}" + if (startsWith(ref, "refs/tags")){ + x <- staged.dependencies::dependency_table(ref=ref) + } + else { + x <- staged.dependencies::dependency_table() } - cat("\nCalculating Staged Dependency Table...\n\n") - x <- staged.dependencies::dependency_table() print(x, width = 120) cat("\n\n") staged.dependencies::install_deps(dep_structure = x, install_project = FALSE, verbose = TRUE) @@ -140,12 +148,19 @@ jobs: } shell: Rscript {0} + - name: Create artifacts + run: | + pushd ${{ github.event.repository.name }}/docs/ + zip -r9 $OLDPWD/pkgdown.zip * + popd + shell: bash + - name: Upload docs for review if: github.ref != 'refs/heads/main' uses: actions/upload-artifact@v2 with: - name: docs - path: ${{ github.event.repository.name }}/docs/ + name: pkgdown.zip + path: pkgdown.zip - name: Publish docs if: github.ref == 'refs/heads/main' # Only after merge or push to main @@ -154,3 +169,32 @@ jobs: git config --local user.email "actions@github.com" git config --local user.name "GitHub Actions" Rscript -e 'pkgdown::deploy_to_branch(new_process = FALSE)' + + upload-release-assets: + name: Upload documentation assets + needs: pkgdown + runs-on: ubuntu-latest + if: startsWith(github.ref, 'refs/tags/v') + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Wait for release to succeed + timeout-minutes: 2 + uses: lewagon/wait-on-check-action@v1.1.1 + with: + ref: "${{ github.ref }}" + check-name: 'Release' + repo-token: ${{ secrets.REPO_GITHUB_TOKEN }} + wait-interval: 10 + - name: Download artifact + uses: actions/download-artifact@v2 + with: + name: pkgdown.zip + - name: Upload binaries to release + uses: svenstaro/upload-release-action@v2 + with: + repo_token: ${{ secrets.REPO_GITHUB_TOKEN }} + file: pkgdown.zip + asset_name: pkgdown.zip + tag: ${{ github.ref }} + overwrite: false diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 0000000000..7317843f77 --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,23 @@ +name: Release + +on: + push: + tags: + - "v*" + +jobs: + release: + name: Release + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Set env + run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/v}" >> $GITHUB_ENV + - name: Generate Changelog + run: (awk "/^#.*${{ env.RELEASE_VERSION }}$/{flag=1;next}/^#.*/{flag=0}flag" NEWS.md |grep -v "^$" || echo "* ${{ env.RELEASE_VERSION }}") > RELEASE_BODY.txt + - name: Release + uses: softprops/action-gh-release@v1 + with: + body_path: RELEASE_BODY.txt + token: ${{ secrets.REPO_GITHUB_TOKEN }} diff --git a/.github/workflows/test-coverage.yaml b/.github/workflows/test-coverage.yaml new file mode 100644 index 0000000000..73b14e27bc --- /dev/null +++ b/.github/workflows/test-coverage.yaml @@ -0,0 +1,184 @@ +name: Coverage + +on: + push: + branches: + - main + pull_request: + branches: + - main + - pre-release + +jobs: + test-coverage: + name: Coverage + runs-on: ubuntu-latest + container: + image: ghcr.io/insightsengineering/rstudio_4.1.0_bioc_3.13:latest + steps: + - name: Checkout repo + uses: actions/checkout@v2 + + - name: Gather info from PR + uses: actions/github-script@v4 + id: get-pr + if: github.event_name == 'pull_request' + with: + script: | + const request = { + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: context.issue.number + } + core.info(`Getting PR #${request.pull_number} from ${request.owner}/${request.repo}`) + try { + const result = await github.pulls.get(request) + return result.data + } catch (err) { + core.setFailed(`Request failed with error ${err}`) + } + + - name: Install remotes R package if needed + run: | + options(repos = c(CRAN = "https://cloud.r-project.org/")) + ncores <- parallel::detectCores(all.tests = FALSE, logical = TRUE) + cat(paste("\n\nnumber of cores detected:", ncores, "\n\n")) + if (!require("remotes")) install.packages("remotes", upgrade = "never", Ncpus = ncores) + shell: Rscript {0} + env: + GITHUB_PAT: ${{ secrets.REPO_GITHUB_TOKEN }} # or ${{ secrets.GITHUB_TOKEN }} + + - name: Checkout repo during PR + uses: actions/checkout@v2 + if: github.event_name == 'pull_request' + with: + repository: ${{ fromJSON(steps.get-pr.outputs.result).head.repo.full_name }} + ref: ${{ fromJSON(steps.get-pr.outputs.result).head.ref }} + path: ${{ github.event.repository.name }} + + - name: Checkout repo from push + uses: actions/checkout@v2 + if: github.event_name == 'push' + with: + path: ${{ github.event.repository.name }} + + - name: Install system dependencies for R package + run: | + ubuntu_info <- read.csv("/etc/os-release", sep = "=", header = FALSE) + v_ubuntu_info <- setNames(ubuntu_info$V2, ubuntu_info$V1) + if (v_ubuntu_info[['NAME']] != "Ubuntu") stop("only works on ubuntu") + ubuntu_version <- v_ubuntu_info[['VERSION_ID']] + + sys_deps_for_pkg <- remotes::system_requirements("ubuntu", ubuntu_version, path = "${{ github.event.repository.name }}") + + sys_pgks <- gsub("^apt-get install -y ", "", sys_deps_for_pkg) + + has_pkgs <- vapply(sys_pgks, function(pkg) system2("dpkg", c("-l", pkg), stdout = NULL, stderr = NULL) == 0, logical(1)) + + if (any(!has_pkgs)) { + system2("apt-get", "update") + system2("apt-get", c("install", "-y", sys_pgks[!has_pkgs])) + } + shell: Rscript {0} + + - name: Install R package dependencies + run: | + setwd("${{ github.event.repository.name }}") + options(repos = c(CRAN = "https://cloud.r-project.org/")) + ncores <- parallel::detectCores(all.tests = FALSE, logical = TRUE) + cat(paste("\n\nnumber of cores detected:", ncores, "\n\n")) + if (file.exists("renv.lock")) { + renv::restore() + } else { + remotes::install_deps(dependencies = TRUE, upgrade = "never", Ncpus = ncores) + } + if (file.exists("staged_dependencies.yaml")) { + cat("\nInstall Staged Dependencies\n\n\n") + if (!require("staged.dependencies")) { + remotes::install_github("openpharma/staged.dependencies", ref = "v0.2.1", Ncpus = ncores, upgrade = "never") + } + cat("\nCalculating Staged Dependency Table...\n\n") + x <- staged.dependencies::dependency_table() + print(x, width = 120) + cat("\n\n") + staged.dependencies::install_deps(dep_structure = x, install_project = FALSE, verbose = TRUE) + } + shell: Rscript {0} + env: + GITHUB_PAT: ${{ secrets.REPO_GITHUB_TOKEN }} + + - name: Install R package + run: R CMD INSTALL ${{ github.event.repository.name }} + shell: bash + + - name: Install covr + run: if (!require("covr")) install.packages("covr", repos="http://cran.rstudio.com/", upgrade = "never") + shell: Rscript {0} + + - name: Run coverage + run: | + tryCatch( + expr = { + x <- covr::package_coverage() + print(x) + covr::to_cobertura(x, filename = "coverage.xml") + p <- covr::percent_coverage(x) + cat(p, file = "coverage.txt", sep = "") + covr::report( + x, + file = "coverage-report.html", + browse = FALSE + ) + }, + error = function(e) { + message("Errors generated during coverage analysis:") + print(e) + }, + warning = function(w) { + message("Warnings generated during coverage analysis:") + print(w) + } + ) + shell: Rscript {0} + + - name: Check whether coverage reports exists + id: check_coverage_reports + uses: andstor/file-existence-action@v1 + with: + files: "coverage.xml, coverage.txt, coverage-report.html" + + - name: cobertura-report + if: steps.check_coverage_reports.outputs.files_exists == 'true' + uses: 5monkeys/cobertura-action@v9 + with: + path: coverage.xml + repo_token: ${{ secrets.REPO_GITHUB_TOKEN }} + minimum_coverage: 80 + fail_below_threshold: false + skip_covered: true + + - name: Set env + if: steps.check_coverage_reports.outputs.files_exists == 'true' + run: echo "OVERALL_COVERAGE=$(cat coverage.txt)" >> $GITHUB_ENV + + - name: Badge for coverage + if: steps.check_coverage_reports.outputs.files_exists == 'true' + uses: knightdave/anybadge-action@v1.1.0 + with: + file: coverage.svg + value: ${{ env.OVERALL_COVERAGE }} + anybadge_args: coverage + + - name: Upload badge + if: steps.check_coverage_reports.outputs.files_exists == 'true' + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage.svg + + - name: Upload report + if: steps.check_coverage_reports.outputs.files_exists == 'true' + uses: actions/upload-artifact@v2 + with: + name: coverage-report + path: "coverage-report.html" diff --git a/.gitignore b/.gitignore index dfeead09ea..ef34c12c15 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,4 @@ tmp.* vignettes/*.html vignettes/*.md vignettes/*.R +coverage.*