Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add reusbale deployment template #74

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions .github/workflows/dashboard_deploy_template.yaml
oadetayo marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
name: Dashboard Deploy

on:
workflow_call:
inputs:
parameter_file:
description: "Path to the parameters file"
required: true
type: string

jobs:
deployShiny:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install yq
run: |
sudo apt-get update
sudo apt-get install -y yq

- name: Read parameters
run: |
DASHBOARD_NAME=$(yq '.dashboard_name' ${{ inputs.parameter_file }})
DEPLOY_TARGET=$(yq '.deploy_target' ${{ inputs.parameter_file }})
INSTALL_TERRA_DEPENDENCIES=$(yq '.install_terra_dependencies' ${{ inputs.parameter_file }})
INSTALL_UNITS_DEPENDENCIES=$(yq '.install_unit_dependencies' ${{ inputs.parameter_file }})
EXTRA_PACKAGES=$(yq '.extra_packages | join(" ")' ${{ inputs.parameter_file }})

echo "DASHBOARD_NAME=$DASHBOARD_NAME" >> $GITHUB_ENV
echo "DEPLOY_TARGET=$DEPLOY_TARGET" >> $GITHUB_ENV
echo "INSTALL_TERRA_DEPENDENCIES=INSTALL_TERRA_DEPENDENCIES" >> $GITHUB_ENV
echo "INSTALL_UNITS_DEPENDENCIES=INSTALL_UNITS_DEPENDENCIES" >> $GITHUB_ENV
echo "EXTRA_PACKAGES=$EXTRA_PACKAGES" >> $GITHUB_ENV

- uses: r-lib/actions/setup-r@v2
with:
use-public-rspm: true

- name: Install terra dependencies
if: env.INSTALL_TERRA_DEPENDENCIES == 'true'
run: |
sudo apt-get update -y
sudo apt-get install -y gdal-bin libgdal-dev proj-bin libproj-dev

- name: Install units dependencies
if: env.INSTALL_UNITS_DEPENDENCIES == 'true'
run: sudo apt-get install libudunits2-dev

- name: Set environment variables based on branch
run: |
if [[ "${{ github.ref_name }}" == "main" ]]; then
echo "SHINYAPP_NAME='${{ env.DASHBOARD_NAME }}'" >> $GITHUB_ENV
else
echo "SHINYAPP_NAME='dev-${{ env.DASHBOARD_NAME }}'" >> $GITHUB_ENV
fi

- name: Restore renv snapshot
shell: Rscript {0}
run: |
if (!requireNamespace("renv", quietly = TRUE)) install.packages("renv")
renv::restore()

- name: Install extra R packages
if: env.EXTRA_PACKAGES != ''
shell: Rscript {0}
run: |
packages <- strsplit(Sys.getenv("EXTRA_PACKAGES"), " ")[[1]]
if (length(packages) > 0 && nchar(packages[1]) > 0) {
install.packages(packages, repos='https://cloud.r-project.org')
}

- name: Install rsconnect
if: env.DEPLOY_TARGET == 'shinyapps'
shell: Rscript {0}
run: |
if (!requireNamespace("rsconnect", quietly = TRUE)) install.packages("rsconnect")

- name: Deploy to ShinyApps.io
if: env.DEPLOY_TARGET == 'shinyapps'
run: |
Rscript -e "rsconnect::setAccountInfo(name = 'department-for-education', token = '${{ secrets.SHINYAPPS_TOKEN }}', secret = '${{ secrets.SHINYAPPS_SECRET }}')"
Rscript -e "rsconnect::deployApp(appName='${{ env.SHINYAPP_NAME }}', forceUpdate = TRUE)"
175 changes: 175 additions & 0 deletions vignettes/using-the-dfeshiny-deploy-template.Rmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
---
title: "Using the dfeshiny Deploy Template"
output: rmarkdown::html_vignette
vignette: >
%\VignetteIndexEntry{Using the dfeshiny Deploy Template}
%\VignetteEncoding{UTF-8}
%\VignetteEngine{knitr::rmarkdown}
editor_options:
markdown:
wrap: 72
---

```{r, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>"
)
```

When developing DFE Shiny dashboards, it’s common to want a consistent,
simple, and secure way to deploy applications to platforms such as
ShinyApps.io or the new DfE hosting platform. This article shows how to
use the dfeshiny reusable workflow template for GitHub Actions, with
parameters defined in a separate YAML file to minimize duplication and
speed up development.

## Overview

1. **Have a `deploy_parameters.yaml`**: Store all your deployment
parameters, including the app name, environment toggles (e.g.,
`install_terra_dependencies`), and extra R packages to install.

2. **Minimal Local Workflow**: Reference the *remote* reusable workflow
(stored in another repository) from your local
`.github/workflows/deploy.yaml`.

3. **Secrets Management**: Ensure your repository has the required
secrets (e.g., `SHINYAPPS_TOKEN` and `SHINYAPPS_SECRET`) set up
under *Settings \> Secrets and variables*.

oadetayo marked this conversation as resolved.
Show resolved Hide resolved
## 1. Create a `deploy_parameters.yaml`

At the root of your project, add a file called
`deploy_parameters.yaml`.\
Below is an example with optional parameters:

```{yaml}
dashboard_name: "my-cool-dashboard"
deploy_target: "shinyapps"
install_terra_dependencies: true
install_unit_dependencies: true
extra_packages:
- sf
- data.table
Fixed Show fixed Hide fixed
- DT
```

- `dashboard_name`: Your application’s name on ShinyApps (or other
hosting platform).

- `deploy_target`: Where you want to deploy (e.g., `"shinyapps"`).

- `install_terra_dependencies`: Whether to install the GDAL libraries
(important for certain spatial packages like `sf` which is itself a
dependency of map plotting packages such as `leaflet`).

- `install_unit_dependencies`: Whether to install the linux libraries
(important for the `units` package).

- `extra_packages`: A list of additional packages to install beyond
what you have in your `renv.lock`.

## 2. Set Up Your Local Workflow

In your local `.github/workflows/` folder, create or edit a
file—commonly named `deploy.yaml`. This file defines **only** the
trigger conditions (which branches to watch) and then calls the remote
reusable workflow.

Here is a minimal example:

```{yaml}
name: Deploy Dashboard
Dismissed Show dismissed Hide dismissed

on:
push:
Fixed Show fixed Hide fixed
Dismissed Show dismissed Hide dismissed
branches:
Fixed Show fixed Hide fixed
Dismissed Show dismissed Hide dismissed
- main
Fixed Show fixed Hide fixed
Dismissed Show dismissed Hide dismissed
- development

jobs:
deploy:
Fixed Show fixed Hide fixed
Dismissed Show dismissed Hide dismissed
uses: dfe-analytical-services/dfeshiny/.github/workflows/deploy-dashboard-template.yaml@main
Dismissed Show dismissed Hide dismissed
with:
parameter_file: deploy_parameters.yaml
Dismissed Show dismissed Hide dismissed
```

- `on: push`… ensures this workflow runs whenever code is pushed to
`main` or `development`.

- `uses: dfe-analytical-services/dfeshiny-deploy-templates…` points to
the remote repo and file containing the actual deployment steps.

- `with: parameter_file: deploy_parameters.yaml` tells the remote
workflow which file to parse for parameters.

## 3. Secrets and Permissions

Before your deployment can succeed, you need to set the relevant secrets
in your local repository. These secrets are **not** shared automatically
across repos, so you must create them in your project’s *Settings \>
Secrets and variables \> Actions*:

- **SHINYAPPS_TOKEN**

- **SHINYAPPS_SECRET**

## 4. How the Template Works

Once you commit your `deploy.yaml` and `deploy_parameters.yaml`, the
GitHub Actions runner will:

1. **Check Out the Code** – Pulls your repository code and the
`deploy_parameters.yaml`.

2. **Parse Parameters** – Uses a tool like `yq` to read
`deploy_parameters.yaml`:

- `dashboard_name`

- `deploy_target`

- etc.

3. **Install Dependencies** – Optionally installs GDAL libraries if
`install_terra_dependencies: true`.

4. **Restore R Dependencies** – If your project uses `renv`, it runs
`renv::restore()` to ensure your local library is consistent.

5. **Install Extra Packages** – Installs any packages listed in
`extra_packages`.

6. **Deploy** – Calls the appropriate deployment method based on
`deploy_target`.

- For ShinyApps.io, it uses `rsconnect::deployApp()`.

## Summary

Using a reusable GitHub Actions workflow template:

- **Reduces complexity** of dashboards deployments - you only maintain
a minimal local config .

- **Ensures** **consistent deployment** practices across your
dashboards.

- Makes it easy to **update** deployments across your dashboards with
minimal changes in each repository.

If you have questions about credentials or advanced usage, contact the
Explore Education Statistics Platforms team at
[explore.statistics\@education.gov.uk](mailto:[email protected]).

> Whilst following the instructions in this article will help you set up
> the deployment of your dashboard, you will still need to seek approval
> to publish from the Explore Education Statistics team and ask for them
> to set up the secrets management on GitHub for your deployment to go
> through.

With these steps, you can quickly set up your dashboards to deploy on
push—whether that’s to ShinyApps.io or a future DfE platform—while
keeping all your deployment logic in a single, centralized workflow
template.
Loading