Skip to content

Commit

Permalink
Merge pull request #6 from ukgovdatascience/add_aqa_docs
Browse files Browse the repository at this point in the history
Add analytical quality assurance documents
  • Loading branch information
ESKYoung authored Oct 8, 2020
2 parents 5fd8c55 + 2a2e5ee commit d677bac
Show file tree
Hide file tree
Showing 8 changed files with 241 additions and 24 deletions.
4 changes: 3 additions & 1 deletion cookiecutter.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,7 @@
"author_name": "Your Name/Organisation",
"overview": "Brief overview of your project.",
"project_version": "0.0.1",
"create_secrets_file": ["No", "Yes"]
"create_secrets_file": ["No", "Yes"],
"departmental_aqa_framework": ["GDS"],
"repository_hosting_platform": ["GitHub", "GitLab"]
}
141 changes: 118 additions & 23 deletions hooks/post_gen_project.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,122 @@
from shutil import rmtree
from textwrap import dedent
import os

# Define the folder path to the 'docs/aqa_frameworks' folder, and the future `docs/aqa` folder
PATH_DOCS_AQA_FRAMEWORKS = os.path.join("docs", "aqa_frameworks")
PATH_DOCS_AQA = os.path.join("docs", "aqa")

# Define the folder path to the `docs/pull_merge_request_templates` folder
PATH_PR_MR_DEPT_TEMPLATES = os.path.join("docs", "pull_merge_request_templates")

# Define the folder path where pull/merge requests should exist as values in a dictionary, where the keys are the
# remote hosts
PATH_PR_MR_TEMPLATE = {
"GitHub": [os.path.join(".github"), "pull_request_template.md"],
"GitLab": [os.path.join(".gitlab", "merge_request_templates"), "{{ cookiecutter.project_name }}.md"]
}


def create_secrets_file(user_option: str) -> None:
"""Create a .secrets file depending on a user option.
Args:
user_option (str): User option.
Returns:
A .secrets file created in the top-level if user_option is 'Yes', otherwise nothing.
"""

# Check if `user_option` is 'Yes'
if user_option == "Yes":

# Define a header for the `.secrets file`
secrets_file = """
# Secrets go here, and can be read in by Python using `os.environ.get`:
#
# --------------------------------------------------------
# import os
#
# EXAMPLE_SECRET = os.environ.get("EXAMPLE_SECRET")
# --------------------------------------------------------
#
# This file is NOT version-controlled!
# Google Cloud authentication credentials
export GOOGLE_APPLICATION_CREDENTIALS=""
"""

# Write the `.secrets` file out
with open(".secrets", "w") as f:
f.write(dedent(secrets_file).lstrip())


def select_dept_aqa_framework(user_option: str, default_option: str = "GDS") -> None:
"""Create analytical quality assurance (AQA) documents for a specific HM Government department.
Args:
user_option (str): User option that defines a HM Government departmental AQA framework to use.
default_option (str): Default: GDS. Default option if user_option is not an existing framework.
Returns:
A new folder in docs/aqa containing the selected HM Government departmental AQA framework.
"""

# Get all the directories in `PATH_DOCS_AQA_FRAMEWORKS`
all_folders = [d for d in os.listdir(PATH_DOCS_AQA_FRAMEWORKS) if os.path.isdir(d)]

# Select the correct folder; use `default_option` if `user_option` is not a valid sub-folder in `all_folders`
selected_folder = user_option if user_option in all_folders else default_option

# Copy the relevant HM Government departmental AQA framework to the `docs/aqa` folder, using `default_option` if
# `user_option` is not a valid sub-folder in `PATH_DOCS_AQA_FRAMEWORKS`
os.rename(os.path.join(PATH_DOCS_AQA_FRAMEWORKS, selected_folder), PATH_DOCS_AQA)

# Remove all framework folders now we have the correct AQA framework
rmtree(PATH_DOCS_AQA_FRAMEWORKS)


def select_pull_merge_request_template(user_option: str, repo_host: str, default_option: str = "GDS") -> None:
"""Select a pull/merge request template depending on HM Government department, and repository remote host.
Args:
user_option (str): User option that defines a HM Government departmental pull/merge request template to use.
repo_host (str): Repository hosting name.
default_option (str): Default: GDS. Default option if user_option is not an existing pull/merge request
template.
Returns:
A pull/merge request template in the correct location for the selected repo_host.
# Get the user-defined option around whether or not they would like to create a secrets file
require_secrets = "{{ cookiecutter.create_secrets_file }}"

# Check if `require_secrets` is 'Yes'
if require_secrets == "Yes":

# Define a header for the `.secrets file`
secrets_file = """
# Secrets go here, and can be read in by Python using `os.environ.get`:
#
# --------------------------------------------------------
# import os
#
# EXAMPLE_SECRET = os.environ.get("EXAMPLE_SECRET")
# --------------------------------------------------------
#
# This file is NOT version-controlled!
# Google Cloud authentication credentials
export GOOGLE_APPLICATION_CREDENTIALS=""
"""

# Write the `.secrets` file out
with open(".secrets", "w") as f:
f.write(dedent(secrets_file).lstrip())
# Get all Markdown files in `PATH_PR_MR_DEPT_TEMPLATES`
md_files = [os.path.splitext(f)[0] for f in os.listdir(PATH_PR_MR_DEPT_TEMPLATES) if f.endswith(".md")]

# Determine the selected file; fallback to `default_option` if `user_option` is not in `md_files`
selected_md_file = f"{user_option if user_option in md_files else default_option}.md"

# Create a directory for the new location
if not os.path.isdir(PATH_PR_MR_TEMPLATE[repo_host][0]):
os.makedirs(PATH_PR_MR_TEMPLATE[repo_host][0], exist_ok=True)

# Move the `selected_md_file` to the correct location
os.rename(os.path.join(PATH_PR_MR_DEPT_TEMPLATES, selected_md_file), os.path.join(*PATH_PR_MR_TEMPLATE[repo_host]))

# Remove all pull/merge request templates now that we have the correct one
rmtree(PATH_PR_MR_DEPT_TEMPLATES)


if __name__ == "__main__":

# Create a .secrets file, if requested
create_secrets_file("{{ cookiecutter.create_secrets_file }}")

# Select the appropriate AQA framework
select_dept_aqa_framework("{{ cookiecutter.departmental_aqa_framework }}")

# Select the appropriate pull/merge request template
select_pull_merge_request_template("{{ cookiecutter.departmental_aqa_framework }}",
"{{ cookiecutter.repository_hosting_platform }}")
12 changes: 12 additions & 0 deletions {{ cookiecutter.repo_name }}/docs/aqa_frameworks/GDS/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Analytical quality assurance

These pages summarise analytical quality assurance (AQA) required for this project:

```eval_rst
.. toctree::
:maxdepth: 2
aqa_plan.md
assumptions_caveats.md
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Analytical quality assurance plan

This analytical quality assurance (AQA) plan outlines our implementation of the [Aqua Book](
https://www.gov.uk/government/publications/the-aqua-book-guidance-on-producing-quality-analysis-for-government) for
this project. Further resources related to the Aqua Book can be found
[here](https://www.gov.uk/government/collections/aqua-book-resources).

This is a **living** document, and should be updated and/or modified as necessary, e.g. if new tasks not listed here
become relevant to project success, please add them to this plan.
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Assumptions and caveats Log

This log contains a list of assumptions and caveats used in this analysis.

<!-- Use reStructuredText contents directive to generate a local contents -->
```eval_rst
.. contents::
:local:
:depth: 1
```

## Definitions

Assumptions are RAG-rated according to the following definitions for quality and impact<sup>1</sup>:

<!-- Using reStructuredText table here, otherwise the raw Markdown is greater than the 120-character line width -->
```eval_rst
+-------+------------------------------------------------------+-------------------------------------------------------+
| RAG | Assumption quality | Assumption impact |
+=======+======================================================+=======================================================+
| GREEN | Reliable assumption, well understood and/or | Marginal assumptions; their changes have no or |
| | documented; anything up to a validated & recent set | limited impact on the outputs. |
| | of actual data. | |
+-------+------------------------------------------------------+-------------------------------------------------------+
| AMBER | Some evidence to support the assumption; may vary | Assumptions with a relevant, even if not critical, |
| | from a source with poor methodology to a good source | impact on the outputs. |
| | that is a few years old. | |
+-------+------------------------------------------------------+-------------------------------------------------------+
| RED | Little evidence to support the assumption; may vary | Core assumptions of the analysis; the output would be |
| | from an opinion to a limited data source with poor | drastically affected by their change. |
| | methodology. | |
+-------+------------------------------------------------------+-------------------------------------------------------+
```
<sup><sup>1</sup> With thanks to the Home Office Analytical Quality Assurance team for these definitions.</sup>

## Assumptions and caveats

The log contains the following assumptions and caveats:

<!-- Use reStructuredText contents directive to generate a local contents -->
```eval_rst
.. contents::
:local:
:depth: 1
```

### Assumption 1: Insert plain English title here

* **Quality**: Insert RAG rating here
* **Impact**: Insert RAG rating here

Add plain English description here.

### Assumption 2: Insert plain English title here

* **Quality**: Insert RAG rating here
* **Impact**: Insert RAG rating here

Add plain English description here.
1 change: 1 addition & 0 deletions {{ cookiecutter.repo_name }}/docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Here is the documentation for the {{ cookiecutter.project_name }} project.
.. toctree::
:maxdepth: 2
aqa/README.md
structure/README.md
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Summary

Add your summary here - keep it brief, to the point, and in plain English. For further information about pull requests,
check out the [GDS Way](https://gds-way.cloudapps.digital/standards/pull-requests.html).

# Checklists

<!--
These are DO-CONFIRM checklists; it CONFIRMs that you have DOne each item.
Outstanding actions should be completed before reviewers are assigned; if actions are irrelevant, please try and add a
comment stating why.
Incomplete pull/merge requests MAY be blocked until actions are resolved, or closed at the reviewers' discretion.
-->

### General checks

- [ ] Code runs
- [ ] Developments are **secure** and [**ethical**](https://www.gov.uk/government/publications/data-ethics-framework))
- [ ] You have made proportionate checks that the code works correctly
- [ ] Test suite passes
- [ ] Assumptions, and caveats log updated (see `docs/aqa/assumptions_caveats.md`), if necessary
- [ ] [Minimum usable documentation](http://agilemodeling.com/essays/documentLate.htm) written in the `docs` folder

### Project-specific checks

> These are additional checks determined necessary according to the analytical quality assurance plan
(see `docs/aqa/aqa_plan.md`).

- [ ] Check 1
- [ ] Check 2
- [ ] Check 3
6 changes: 6 additions & 0 deletions {{ cookiecutter.repo_name }}/docs/structure/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ make docs

For further information about writing Sphinx documentation, see the `README.md` file in the `docs` folder.

#### Analytical quality assurance (AQA)

All analytical quality assurance (AQA) documents can be found in the `docs/aqa` folder. These files document how this
project meets HM Government guidance on producing quality analysis, as described in the
[Aqua book](https://www.gov.uk/government/publications/the-aqua-book-guidance-on-producing-quality-analysis-for-government).

### `notebooks` folder

All Jupyter notebooks should be stored in this folder. The [`.envrc`](#envrc) file should automatically add the entire
Expand Down

0 comments on commit d677bac

Please sign in to comment.