Skip to content

Commit

Permalink
Start using Decision Records (#430)
Browse files Browse the repository at this point in the history
This PR adopts decision records for this project. A distinction is made
between "architectural" (decisions on software & infrastructure patterns
& use) and "scientific" (decisions on how to calculate and handle data)
records.

I've also added issue templates and automation so that we can create our
ADR/SDR's in GitHub Issues, then add the "accepted" label and close them
for them to be integrated into the repo.

Ideally, after this PR is merged, we will be able to have automation
take care of ADR/SDR filenames and formatting.
  • Loading branch information
ian-noaa authored Oct 24, 2024
2 parents 02a0771 + 8e0319e commit 67845bb
Show file tree
Hide file tree
Showing 11 changed files with 509 additions and 0 deletions.
46 changes: 46 additions & 0 deletions .github/ISSUE_TEMPLATE/adr-template.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: Architecture decision record (ADR)
description: Open a new draft ADR
labels: ["ADR"]
title: "We will "
body:
- type: textarea
id: context
validations:
required: true
attributes:
label: Context
description: > # Turn new lines into spaces
Describe the motivating factors behind this decision: social, political,
technical, etc. Why does this decision need to be made? This section should
be a statement of facts.
- type: textarea
id: decision
validations:
required: true
attributes:
label: Decision
description: >
What was decided? This should be an active-voice statement. For example,
"We will use the US Web Design System."
- type: textarea
id: consequences
validations:
required: true
attributes:
label: Consequences
description: >
What are the consequences of this decision? Consequences can be
positive, negative, or neutral, but all known consequences of this
decision should be listed here.
value: | # Preserve new lines
#### Positive
-
#### Neutral
-
#### Negative
-
46 changes: 46 additions & 0 deletions .github/ISSUE_TEMPLATE/sdr-template.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: Scientific decision record (SDR)
description: Open a new draft SDR
labels: ["SDR"]
title: "We will "
body:
- type: textarea
id: context
validations:
required: true
attributes:
label: Context
description: > # Turn new lines into spaces
Describe the motivating factors behind this decision: social, political,
scientific, etc. Why does this decision need to be made? This section should
be a statement of facts.
- type: textarea
id: decision
validations:
required: true
attributes:
label: Decision
description: >
What was decided? This should be an active-voice statement. For example,
"We will recalculate heights for RAOB observations."
- type: textarea
id: consequences
validations:
required: true
attributes:
label: Consequences
description: >
What are the consequences of this decision? Consequences can be
positive, negative, or neutral, but all known consequences of this
decision should be listed here.
value: | # Preserve new lines
#### Positive
-
#### Neutral
-
#### Negative
-
110 changes: 110 additions & 0 deletions .github/workflows/adr-accepted.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
name: ADR Accepted
on:
issues:
types:
- closed

jobs:
main:
name: Create ADR
runs-on: ubuntu-latest

# Only run this workflow if the closed issue has the "ADR: accepted" label
if: "${{ contains(github.event.issue.labels.*.name, 'ADR: accepted') }}"

steps:
- name: checkout main branch
uses: actions/checkout@v4
with:
ref: main

- name: get ADR number
id: next
run: |
LAST_ADR=$(ls docs/decisions/architecture/*.md | grep -Eo "architecture/adr-[0-9]+-" | sort | tail -n1 | grep -Eo "[0-9]+")
LAST_ADR=$(echo "$LAST_ADR" | sed -E 's/^0+//')
NEXT_ADR=$(($LAST_ADR + 1))
NEXT_ADR=$(printf "%04i" "$NEXT_ADR")
echo "number=$NEXT_ADR" >> "$GITHUB_OUTPUT"
- name: write the ADR
id: create-adr
uses: actions/github-script@v7
with:
script: |
const fs = require("fs/promises");
// Use the GitHub toJSON expression to get these as escaped strings.
// In Javascript, this will preserve line breaks, and using template
// strings further down will preserve all the kinds of quotes.
const title = ${{ toJSON(github.event.issue.title) }};
const body = ${{ toJSON(github.event.issue.body )}};
const slug = title
.toLowerCase()
.trim()
.replace(/[^\w\s-]/g, "") // get rid of non-ascii characters
.replace(/[\s_-]+/g, "-") // convert whitespace and underscore to dash
.replace(/^-+|-+$/g, ""); // git rid of leading/trailing dashes
const filename = `docs/decisions/architecture/adr-${{ steps.next.outputs.number }}-${slug}.md`;
// Get the current date as an ISO8601 string, split at the timestamp,
// and only keep the date portion.
const [date] = new Date().toISOString().split("T");
const adr = `# ${ title }
Date: ${ date }
### Status
Accepted
${ body }
`;
# Set outputs for the next step to use
core.setOutput('filename', filename);
core.setOutput('adr', adr);
await fs.writeFile(filename, adr, { encoding: 'utf-8' });
- name: branch, commit, and open PR
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
BRANCH="adr-auto-${{ steps.next.outputs.number }}"
git config --global user.email "[email protected]"
git config --global user.name "GSL Verification team ADR automation"
# Check if the branch already exists, exit-code 2 means it doesn't, and that creating a new branch is safe.
set +e # override set -e since we're hoping for an exit code
git ls-remote --exit-code --heads origin refs/heads/$BRANCH > /dev/null
branch_exists=$?
set -e
if [ $branch_exists -eq 2 ]; then
git checkout -b $BRANCH
git add docs/decisions/architecture/*.md
git commit -m "add ADR ${{ steps.next.outputs.number }}: ${{ github.event.issue.title }}"
git push -f origin $BRANCH
gh pr create \
--title "Add ADR ${{ steps.next.outputs.number }} to the repo" \
--label "ADR" \
--body "This pull request was opened automatically because #${{ github.event.issue.number }} was closed after being marked as an approved ADR. It contains a markdown file capturing the ADR body at the time the issue was closed. Please verify that the markdown is correct before merging!" || true
else
echo "Error - Branch $BRANCH already exists, PR will need to be created manually. ADR text is below. Exiting."
echo " --- "
echo "Filename: ${{ steps.create-adr.outputs.filename }}"
echo " --- Start File --- "
echo "${{ steps.create-adr.outputs.adr }}"
echo " --- End File --- "
# Create a step summary
echo "# Error" >> $GITHUB_STEP_SUMMARY
echo "Branch $BRANCH already exists, PR will need to be created manually. ADR contents are below. Exiting." >> $GITHUB_STEP_SUMMARY
echo "## Filename" >> $GITHUB_STEP_SUMMARY
echo "\`${{ steps.create-adr.outputs.filename }}\`" >> $GITHUB_STEP_SUMMARY
echo "## ADR Contents" >> $GITHUB_STEP_SUMMARY
echo "${{ steps.create-adr.outputs.adr }}" >> $GITHUB_STEP_SUMMARY
exit 1
fi
35 changes: 35 additions & 0 deletions .github/workflows/adr-proposed.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: ADR proposed
on:
issues:
types:
- labeled

jobs:
main:
name: ADR proposed
runs-on: ubuntu-latest

# Only run this workflow if the issue is open and has the "ADR" label
if: "${{github.event.issue.state == 'open' && contains(github.event.issue.labels.*.name, 'ADR') }}"

steps:
- name: add comment if appropriate
uses: actions/github-script@v7
with:
script: |
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number
});
const botHasCommented = comments.some(({ user: { login }}) => login === 'github-actions[bot]');
if(!botHasCommented) {
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: 'This issue appears to be a draft or in-progress ADR. When it is completed and accepted, add the `ADR: Accepted` label and close the issue. This will start a process to create the ADR document and add it to the repo automatically. If you close the issue before adding the label, simply re-open and re-close it.'
});
}
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ on:
push:
paths-ignore:
- "meta_update_middleware/**"
- "docs/**"
tags:
- "[0-9]+.[0-9]+.[0-9]+"
- "[0-9]+.[0-9]+.[0-9]+-rc[0-9]+"
branches: [main]
pull_request:
paths-ignore:
- "meta_update_middleware/**"
- "docs/**"
workflow_dispatch: # Manually
env:
REGISTRY: ghcr.io/noaa-gsl/vxingest
Expand Down
111 changes: 111 additions & 0 deletions .github/workflows/sdr-accepted.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
name: SDR Accepted
on:
issues:
types:
- closed

jobs:
main:
name: Create SDR
runs-on: ubuntu-latest

# Only run this workflow if the closed issue has the "SDR: accepted" label
if: "${{ contains(github.event.issue.labels.*.name, 'SDR: accepted') }}"

steps:
- name: checkout main branch
uses: actions/checkout@v4
with:
ref: main

- name: get SDR number
id: next
run: |
LAST_SDR=$(ls docs/decisions/scientific/*.md | grep -Eo "scientific/sdr-[0-9]+-" | sort | tail -n1 | grep -Eo "[0-9]+")
LAST_SDR=$(echo "$LAST_SDR" | sed -E 's/^0+//')
NEXT_SDR=$(($LAST_SDR + 1))
NEXT_SDR=$(printf "%04i" "$NEXT_SDR")
echo "number=$NEXT_SDR" >> "$GITHUB_OUTPUT"
- name: write the SDR
id: create-sdr
uses: actions/github-script@v7
with:
script: |
const fs = require("fs/promises");
// Use the GitHub toJSON expression to get these as escaped strings.
// In Javascript, this will preserve line breaks, and using template
// strings further down will preserve all the kinds of quotes.
const title = ${{ toJSON(github.event.issue.title) }};
const body = ${{ toJSON(github.event.issue.body )}};
const slug = title
.toLowerCase()
.trim()
.replace(/[^\w\s-]/g, "") // get rid of non-ascii characters
.replace(/[\s_-]+/g, "-") // convert whitespace and underscore to dash
.replace(/^-+|-+$/g, ""); // git rid of leading/trailing dashes
const filename = `docs/decisions/scientific/sdr-${{ steps.next.outputs.number }}-${slug}.md`;
// Get the current date as an ISO8601 string, split at the timestamp,
// and only keep the date portion.
const [date] = new Date().toISOString().split("T");
const sdr = `# ${ title }
Date: ${ date }
### Status
Accepted
${ body }
`;
# Set outputs for the next step to use
core.setOutput('filename', filename);
core.setOutput('sdr', sdr);
await fs.writeFile(filename, sdr, { encoding: 'utf-8' });
- name: branch, commit, and open PR
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
BRANCH="sdr-auto-${{ steps.next.outputs.number }}"
git config --global user.email "[email protected]"
git config --global user.name "GSL Verification team SDR automation"
# Check if the branch already exists, exit-code 2 means it doesn't, and that creating a new branch is safe.
set +e # override set -e since we're hoping for an exit code
git ls-remote --exit-code --heads origin refs/heads/$BRANCH > /dev/null
branch_exists=$?
set -e
if [ $branch_exists -eq 2 ]; then
git checkout -b $BRANCH
git add docs/decisions/scientific/*.md
git commit -m "add SDR ${{ steps.next.outputs.number }}: ${{ github.event.issue.title }}"
git push -f origin $BRANCH
gh pr create \
--title "Add SDR ${{ steps.next.outputs.number }} to the repo" \
--label "SDR" \
--body "This pull request was opened automatically because #${{ github.event.issue.number }} was closed after being marked as an approved SDR. It contains a markdown file capturing the SDR body at the time the issue was closed. Please verify that the markdown is correct before merging!" || true
exit 0
else
echo "Error - Branch $BRANCH already exists, PR will need to be created manually. SDR text is below. Exiting."
echo " --- "
echo "Filename: ${{ steps.create-sdr.outputs.filename }}"
echo " --- Start File --- "
echo "${{ steps.create-sdr.outputs.sdr }}"
echo " --- End File --- "
# Create a step summary
echo "# Error" >> $GITHUB_STEP_SUMMARY
echo "Branch $BRANCH already exists, PR will need to be created manually. SDR contents are below. Exiting." >> $GITHUB_STEP_SUMMARY
echo "## Filename" >> $GITHUB_STEP_SUMMARY
echo "\`${{ steps.create-sdr.outputs.filename }}\`" >> $GITHUB_STEP_SUMMARY
echo "## SDR Contents" >> $GITHUB_STEP_SUMMARY
echo "${{ steps.create-sdr.outputs.sdr }}" >> $GITHUB_STEP_SUMMARY
exit 1
fi
Loading

0 comments on commit 67845bb

Please sign in to comment.