diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 26ae004..5b4d1d0 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -108,6 +108,26 @@ When coding: - As an author: respond to every comment, and only resolve a thread once it's addressed. - The author merges the pull request after approval, unless agreed otherwise. +## Releases + +`main` is the only long-lived branch. Between releases it has a development version ending in `.9000`. A release is a tag `vX.Y.Z` on `main` with a GitHub release. [R-universe](https://rivm-syso.r-universe.dev) builds the latest release. + +### In every pull request + +- Add a bullet to `NEWS.md` under the `(development version)` heading for every user-facing change. These bullets become the release notes. +- Don't change `Version` in `DESCRIPTION`. It only changes in a release pull request. +- Every `Remotes:` entry for an ROvis package ends in `@*release`, for example `rivm-syso/ROvis.utils@*release`. If you need an unreleased change from another ROvis package, remove `@*release` from that entry and raise the minimum version in `Imports:` to its development version. That package is then released first. + +### Making a release (maintainers) + +1. Open a release pull request. Run `usethis::use_version()` with `"patch"` (bug fixes only), `"minor"` (new features) or `"major"` (breaking changes). It sets `Version` and renames the `(development version)` heading in `NEWS.md`. Check that every `Remotes:` entry ends in `@*release`. +2. Merge it after review. `release.yaml` creates the tag and the GitHub release, with the `NEWS.md` section as release notes, and opens a pull request that sets the next development version. +3. Merge that pull request. + +R-universe builds the release within about an hour. If `release.yaml` fails, run `usethis::use_github_release()` on `main` and `usethis::use_dev_version()` in a new pull request. + +When several ROvis packages are released together, release them in dependency order: `ROvis.utils`, then `ROvis.table`, `ROvis.ggplot2`, `ROvis.plotly` and `ROvis.echarts`, then `ROvis.shiny`, then `ROvis`. + ## Code standards - **Single source of truth**: all color definitions live in `color()`. Build on existing functions rather than duplicating logic. diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..0164ff4 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,12 @@ +# Keeps the GitHub Actions in .github/workflows up to date, including the commit SHA +# pins in ci.yaml. One grouped PR per month at most. +version: 2 +updates: + - package-ecosystem: github-actions + directory: / + schedule: + interval: monthly + groups: + github-actions: + patterns: + - "*" diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 2a52386..430c3a3 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -20,7 +20,7 @@ jobs: steps: - uses: actions/checkout@v5 - - uses: posit-dev/setup-air@v1 + - uses: posit-dev/setup-air@fd20dd239848b9d807848a7ab92265cf197de694 # v1.0.2 - name: Check formatting run: | @@ -47,7 +47,7 @@ jobs: run: git config --global --add safe.directory "$GITHUB_WORKSPACE" # R is already baked into daratools/robase - no setup-r needed. - - uses: r-lib/actions/setup-r-dependencies@v2 + - uses: r-lib/actions/setup-r-dependencies@f9a764fea8d5c63df6ef9a5c7795bf7deb5d7e05 # v2.14.0 with: extra-packages: any::lintr needs: lint @@ -127,12 +127,12 @@ jobs: run: git config --global --add safe.directory "$GITHUB_WORKSPACE" # R and pandoc are already baked into daratools/robase - no setup-r/setup-pandoc needed. - - uses: r-lib/actions/setup-r-dependencies@v2 + - uses: r-lib/actions/setup-r-dependencies@f9a764fea8d5c63df6ef9a5c7795bf7deb5d7e05 # v2.14.0 with: extra-packages: any::rcmdcheck needs: check - - uses: r-lib/actions/check-r-package@v2 + - uses: r-lib/actions/check-r-package@f9a764fea8d5c63df6ef9a5c7795bf7deb5d7e05 # v2.14.0 with: upload-snapshots: true build_args: 'c("--no-manual", "--compact-vignettes=gs+qpdf")' @@ -201,7 +201,7 @@ jobs: # R is already baked into daratools/robase - no setup-r step needed. - name: Setup R dependencies - uses: r-lib/actions/setup-r-dependencies@v2 + uses: r-lib/actions/setup-r-dependencies@f9a764fea8d5c63df6ef9a5c7795bf7deb5d7e05 # v2.14.0 with: extra-packages: any::covr, any::jsonlite, any::dplyr needs: coverage @@ -267,49 +267,49 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.AT_ROvis || secrets.GITHUB_TOKEN }} - # pkgdown: - # needs: test-coverage - # # test-coverage only runs on push/pull_request (see its `if:`), so on a - # # release/workflow_dispatch trigger it's skipped rather than successful - - # # explicitly allow that here, otherwise the default needs-gating would - # # skip this job too. - # if: | - # github.event_name != 'pull_request' && - # !cancelled() && - # (needs.test-coverage.result == 'success' || needs.test-coverage.result == 'skipped') - # runs-on: ubuntu-latest - # container: - # image: daratools/robase:latest - # permissions: - # contents: write - # pages: write - # env: - # GITHUB_PAT: ${{ secrets.AT_ROvis || secrets.GITHUB_TOKEN }} - # steps: - # - name: Checkout repository - # uses: actions/checkout@v5 - - # # rocker-based images run as root; mark the workspace as safe for git - # - name: Fix git safe directory - # run: git config --global --add safe.directory "$GITHUB_WORKSPACE" - - # # No setup-r step needed — R is already installed in your Docker image - # - name: Setup pandoc - # uses: r-lib/actions/setup-pandoc@v2 - - # - name: Setup R dependencies - # uses: r-lib/actions/setup-r-dependencies@v2 - # with: - # extra-packages: any::pkgdown, local::. - # needs: website - - # - name: Build pkgdown site - # run: pkgdown::build_site_github_pages(new_process = FALSE, install = FALSE) - # shell: Rscript {0} - - # - name: Deploy to GitHub Pages - # uses: JamesIves/github-pages-deploy-action@v4 - # with: - # clean: false # keeps the badges/ folder written by the coverage job - # branch: gh-pages - # folder: docs + pkgdown: + needs: test-coverage + # test-coverage only runs on push/pull_request (see its `if:`), so on a + # release/workflow_dispatch trigger it's skipped rather than successful - + # explicitly allow that here, otherwise the default needs-gating would + # skip this job too. + if: | + github.event_name != 'pull_request' && + !cancelled() && + (needs.test-coverage.result == 'success' || needs.test-coverage.result == 'skipped') + runs-on: ubuntu-latest + container: + image: daratools/robase:latest + permissions: + contents: write + pages: write + env: + GITHUB_PAT: ${{ secrets.AT_ROvis || secrets.GITHUB_TOKEN }} + steps: + - name: Checkout repository + uses: actions/checkout@v5 + + # rocker-based images run as root; mark the workspace as safe for git + - name: Fix git safe directory + run: git config --global --add safe.directory "$GITHUB_WORKSPACE" + + # No setup-r step needed — R is already installed in your Docker image + - name: Setup pandoc + uses: r-lib/actions/setup-pandoc@f9a764fea8d5c63df6ef9a5c7795bf7deb5d7e05 # v2.14.0 + + - name: Setup R dependencies + uses: r-lib/actions/setup-r-dependencies@f9a764fea8d5c63df6ef9a5c7795bf7deb5d7e05 # v2.14.0 + with: + extra-packages: any::pkgdown, local::. + needs: website + + - name: Build pkgdown site + run: pkgdown::build_site_github_pages(new_process = FALSE, install = FALSE) + shell: Rscript {0} + + - name: Deploy to GitHub Pages + uses: JamesIves/github-pages-deploy-action@fa24774553152dd7873cd16ebd8d959b010c5445 # v4.9.0 + with: + clean: false # keeps the badges/ folder written by the coverage job + branch: gh-pages + folder: docs diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 0000000..c9f498b --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,124 @@ +# Publishes a release when main has a release version (no .9000) that has no tag yet: +# creates the tag and GitHub release, then opens the dev version PR. +# See "Releases" in .github/CONTRIBUTING.md. +on: + push: + branches: [main] + workflow_dispatch: + +name: Release + +permissions: read-all + +jobs: + release: + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + env: + # A release or PR created with the default GITHUB_TOKEN does not trigger other + # workflows, so ci.yaml would not deploy pkgdown on the release and would not run + # on the dev version PR. AT_ROvis does trigger them. + GH_TOKEN: ${{ secrets.AT_ROvis || secrets.GITHUB_TOKEN }} + steps: + - uses: actions/checkout@v5 + with: + token: ${{ secrets.AT_ROvis || secrets.GITHUB_TOKEN }} + + # Decides whether this push is a release. The result is passed to the next steps + # as steps.version.outputs.release ("true" or "false"); they only run on "true". + - name: Check version + id: version + run: | + # Read the "Package:" and "Version:" fields from DESCRIPTION, + # e.g. PKG=ROvis.utils and VERSION=0.2.0 + PKG=$(grep '^Package:' DESCRIPTION | cut -d ' ' -f 2) + VERSION=$(grep '^Version:' DESCRIPTION | cut -d ' ' -f 2) + + # Make both values available to the next steps + echo "package=$PKG" >> "$GITHUB_OUTPUT" + echo "version=$VERSION" >> "$GITHUB_OUTPUT" + + # A release version has exactly three numbers (0.2.0). + # A development version has four (0.2.0.9000): no release. + if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "Version $VERSION is a development version, nothing to release." + echo "release=false" >> "$GITHUB_OUTPUT" + + # Already released: the tag v0.2.0 exists on GitHub. This happens on every + # push between merging the release PR and merging the dev version PR. + elif git ls-remote --exit-code --tags origin "refs/tags/v$VERSION" > /dev/null; then + echo "Tag v$VERSION already exists, nothing to release." + echo "release=false" >> "$GITHUB_OUTPUT" + + # Release version without a tag: the release PR was just merged + else + echo "Version $VERSION has no tag yet, releasing." + echo "release=true" >> "$GITHUB_OUTPUT" + fi + + - name: Create tag and GitHub release + if: steps.version.outputs.release == 'true' + env: + PKG: ${{ steps.version.outputs.package }} + VERSION: ${{ steps.version.outputs.version }} + run: | + # Copy the release notes from NEWS.md: every line below the heading + # "# ROvis.utils 0.2.0", up to the next "# " heading (the previous release). + # awk reads NEWS.md line by line: + # - strip trailing spaces, so "# ROvis.utils 0.2.0 " still matches + # - at the heading: start copying, skip the heading itself + # - at the next "# " heading while copying: stop + # - while copying: print the line + awk -v heading="# $PKG $VERSION" ' + { sub(/[[:space:]]+$/, "") } + $0 == heading { copying = 1; next } + copying && /^# / { exit } + copying { print } + ' NEWS.md > "$RUNNER_TEMP/release-notes.md" + + # Stop if nothing was copied: the heading is missing or misspelled + if [ ! -s "$RUNNER_TEMP/release-notes.md" ]; then + echo "::error::NEWS.md has no '# $PKG $VERSION' section. Run usethis::use_version() in the release PR." + exit 1 + fi + + # Create tag v0.2.0 on the merged commit and a GitHub release with those notes + gh release create "v$VERSION" \ + --target "$GITHUB_SHA" \ + --title "$PKG $VERSION" \ + --notes-file "$RUNNER_TEMP/release-notes.md" + + - name: Open dev version PR + if: steps.version.outputs.release == 'true' + env: + PKG: ${{ steps.version.outputs.package }} + VERSION: ${{ steps.version.outputs.version }} + run: | + # Same result as usethis::use_dev_version(): 0.2.0 becomes 0.2.0.9000 + DEV_VERSION="$VERSION.9000" + BRANCH="dev-version-$DEV_VERSION" + + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git switch -c "$BRANCH" + + # Replace the "Version:" line in DESCRIPTION + sed -i "s/^Version: .*/Version: $DEV_VERSION/" DESCRIPTION + + # Add "# ROvis.utils (development version)" at the top of NEWS.md, + # where the bullets for the next release go + { printf '# %s (development version)\n\n' "$PKG"; cat NEWS.md; } > "$RUNNER_TEMP/NEWS.md" + mv "$RUNNER_TEMP/NEWS.md" NEWS.md + + # Commit on the new branch, push it and open the PR into main + git add DESCRIPTION NEWS.md + git commit -m "Increment version number to $DEV_VERSION" + git push origin "$BRANCH" + + gh pr create \ + --base main \ + --head "$BRANCH" \ + --title "Increment version number to $DEV_VERSION" \ + --body "Opened by \`release.yaml\` after the v$VERSION release. Sets the development version and adds a new \`NEWS.md\` heading. Merge this PR to continue development." diff --git a/DESCRIPTION b/DESCRIPTION index ff1dcd7..92393b2 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -4,6 +4,8 @@ Version: 0.1.0 Authors@R: person("ROvis team", email = "spin@rivm.nl", role = c("cre", "aut")) Description: A tool to uniformly visualise graphs in 'ggplot2' using standardized Rijksoverheid (Dutch National Government) styling. Part of the ROvis umbrella package. License: EUPL (>= 1.2) +URL: https://rivm-syso.github.io/ROvis.ggplot2/, https://github.com/rivm-syso/ROvis.ggplot2 +BugReports: https://github.com/rivm-syso/ROvis.ggplot2/issues Imports: ggplot2 (>= 4.0.3), grid (>= 4.5.1), @@ -24,7 +26,7 @@ Suggests: Depends: R (>= 4.5.0) Remotes: - rivm-syso/ROvis.utils + rivm-syso/ROvis.utils@*release VignetteBuilder: quarto Config/roxygen2/version: 8.1.0 Config/testthat/edition: 3 diff --git a/NEWS.md b/NEWS.md index f7c3dae..b13d62e 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,4 +1,4 @@ -# ROvis.ggplot2 v0.1.0 +# ROvis.ggplot2 0.1.0 ### :sparkles: Added diff --git a/README.md b/README.md index 34b9ea6..e9f7a9b 100644 --- a/README.md +++ b/README.md @@ -14,12 +14,23 @@ A tool to uniformly visualise graphs in 'ggplot2' using standardized Rijksoverhe ## Installation +Install the latest release from [R-universe](https://rivm-syso.r-universe.dev): + +```r +install.packages( + "ROvis.ggplot2", + repos = c("https://rivm-syso.r-universe.dev", "https://cloud.r-project.org") +) +``` + +Install the development version from GitHub: + ```r -# Install from GitHub # install.packages("pak") pak::pak("rivm-syso/ROvis.ggplot2") ``` +A version number ending in `.9000` is a development version. ## Usage A short example of on how to use the ro_gg_theme() function in combination with your ggplot-object. diff --git a/_pkgdown.yml b/_pkgdown.yml index d71acfb..fe81290 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -1,4 +1,6 @@ -url: ~ +url: https://rivm-syso.github.io/ROvis.ggplot2/ template: bootstrap: 5 - +# Released versions build the site root, development versions (.9000) build /dev/ +development: + mode: auto