Skip to content

Commit ec44327

Browse files
authored
Merge branch 'main' into large_spikes_validator
2 parents 5ef2740 + b9cd410 commit ec44327

File tree

982 files changed

+900545
-451376
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

982 files changed

+900545
-451376
lines changed

.github/CONTRIBUTING.md

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
# Contributing to COVIDcast indicator pipelines
2+
3+
## Branches
4+
5+
* `main`
6+
7+
The primary/authoritative branch of this repository is called `main`, and contains up-to-date code and supporting libraries. This should be your starting point when creating a new indicator. It is protected so that only reviewed pull requests can be merged in.
8+
9+
* `deploy-*`
10+
11+
Each automated pipeline has a corresponding branch which automatically deploys to a runtime host which runs the pipeline at a designated time each day. New features and bugfixes are merged into this branch using a pull request, so that our CI system can run the lint and test cycles and make sure the package will run correctly on the runtime host. If an indicator does not have a branch named after it starting with `deploy-`, that means the indicator has not yet been automated, and has a designated human keeper who is responsible for making sure the indicator runs each day -- whether that is manually or using a scheduler like cron is the keeper's choice.
12+
13+
* everything else
14+
15+
All other branches are development branches. We don't enforce a naming policy.
16+
17+
## Issues
18+
19+
Issues are the main communication point when it comes to bugfixes, new features, or other possible changes. The repository has several issue templates that help to structure issues.
20+
21+
If you ensure that each issue deals with a single topic (ie a single new proposed data source, or a single data quality problem), we'll all be less likely to drop subordinate tasks on the floor, but we also recognize that a lot of the people filing issues in this repository are new to large project management and not used to focusing their thoughts in this way. It's okay, we'll all learn and get better together.
22+
23+
Admins will assign issues to one or more people based on balancing expediency, expertise, and team robustness. It may be faster for one person to fix something, but we can reduce the risk of having too many single points of failure if two people work on it together.
24+
25+
## Project Boards
26+
27+
The Delphi Engineering team uses project boards to structure its weekly calls and track active tasks.
28+
29+
Immediate work is tracked on [Release Planning](https://github.com/cmu-delphi/covidcast-indicators/projects/2)
30+
31+
Long-term work and modeling collaborations are tracked on [Refactoring](https://github.com/cmu-delphi/covidcast-indicators/projects/3)
32+
33+
34+
## General workflow for indicators creation and deployment
35+
36+
So, how does one go about developing a pipeline for a new data source?
37+
38+
**tl;dr**
39+
40+
1. Create your new indicator branch from `main`.
41+
2. Build it using the appropriate template, following the guidelines in the included README.md and REVIEW.md files.
42+
3. Make some stuff!
43+
4. When your stuff works, push your `dev-*` branch to remote for review.
44+
5. Consult with a platform engineer for the remaining production setup needs. They will create a branch called `deploy-*` for your indicator.
45+
6. Initiate a pull request against this new branch.
46+
7. Following [the source documentation template](https://github.com/cmu-delphi/delphi-epidata/blob/main/docs/api/covidcast-signals/_source-template.md), create public API documentation for the source. You can submit this as a pull request against the delphi-epidata repository.
47+
8. If your peers like the code, the documentation is ready, and Jenkins approves, deploy your changes by merging the PR.
48+
9. An admin will propagate your successful changes to `main`.
49+
10. Rejoice!
50+
51+
### Starting out
52+
53+
The `main` branch should contain up-to-date code and supporting libraries. This should be your starting point when creating a new indicator.
54+
55+
```shell
56+
# Hint
57+
#
58+
git checkout main
59+
git checkout -b dev-my-feature-branch
60+
```
61+
62+
### Creating your indicator
63+
64+
Create a directory for your new indicator by making a copy of `_template_r` or `_template_python` depending on the programming language you intend to use. If using Python, add the name of the directory to the list found in `jobs > build > strategy > matrix > packages` in `.github/workflows/python-ci.yml`, which will enable automated checks for your indicator when you make PRs. The template copies of `README.md` and `REVIEW.md` include the minimum requirements for code structure, documentation, linting, testing, and method of configuration. Beyond that, we don't have any established restrictions on implementation; you can look at other existing indicators see some examples of code layout, organization, and general approach.
65+
66+
- Consult your peers with questions! :handshake:
67+
68+
Once you have something that runs locally and passes tests you set up your remote branch eventual review and production deployment.
69+
70+
```shell
71+
# Hint
72+
#
73+
git push -u origin dev-my-feature-branch
74+
```
75+
76+
You can then draft public API documentation for people who would fetch this
77+
data from the API. Public API documentation is kept in the delphi-epidata
78+
repository, and there is a [template Markdown
79+
file](https://github.com/cmu-delphi/delphi-epidata/blob/main/docs/api/covidcast-signals/_source-template.md)
80+
that outlines the features that need to be documented. You can create a pull
81+
request to add a new file to `docs/api/covidcast-signals/` for your source. Our
82+
goal is to have public API documentation for the data at the same time as it
83+
becomes available to the public.
84+
85+
### Setting up for review and deployment
86+
87+
Once you have your branch set up you should get in touch with a platform engineer to pair up on the remaining production needs. These include:
88+
89+
- Creating the corresponding `deploy-*` branch in the repo.
90+
- Adding the necessary Jenkins scripts for your indicator.
91+
- Preparing the runtime host with any Automation configuration necessities.
92+
- Reviewing the workflow to make sure it meets the general guidelines and will run as expected on the runtime host.
93+
94+
Once all the last mile configuration is in place you can create a pull request against the correct `deploy-*` branch to initiate the CI/CD pipeline which will build, test, and package your indicator for deployment.
95+
96+
If everything looks ok, you've drafted source documentation, platform engineering has validated the last mile, and the pull request is accepted, you can merge the PR. Deployment will start automatically.
97+
98+
Hopefully it'll be a full on :tada:, after that :crossed_fingers:
99+
100+
If not, circle back and try again.
101+
102+
## Production overview
103+
104+
### Running production code
105+
106+
Currently, the production indicators all live and run on the venerable and perennially useful Delphi primary server (also known generically as "the runtime host").
107+
108+
### Delivering an indicator to the production environment
109+
110+
We use a branch-based git workflow coupled with [Jenkins](https://www.jenkins.io/) and [Ansible](https://www.ansible.com/) to build, test, package, and deploy each indicator individually to the runtime host.
111+
112+
- Jenkins dutifully manages the whole process for us by executing several "stages" in the context of a [CI/CD pipeline](https://dzone.com/articles/learn-how-to-setup-a-cicd-pipeline-from-scratch). Each stage does something unique, building on the previous stage. The stages are:
113+
- Environment - Sets up some environment-specific needs that the other stages depend on.
114+
- Build - Create the Python venv on the Jenkins host.
115+
- Test - Run linting and unit tests.
116+
- Package - Tar and gzip the built environment.
117+
- Deploy - Trigger an Ansible playbook to place the built package onto the runtime host, place any necessary production configuration, and adjust the runtime envirnemnt (if necessary).
118+
119+
There are several additional Jenkins-specific files that will need to be created for each indicator, as well as some configuration additions to the runtime host. It will be important to pair with a platform engineer to prepare the necessary production environment needs, test the workflow, validate on production, and ultimately sign off on a production release.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
---
2+
name: Feature release
3+
about: Begin the finishing work for features ready to be included in a release
4+
title: 'Release NEW_THING'
5+
labels: 'release'
6+
assignees: 'benjaminysmith'
7+
---
8+
9+
- [Link to issue]()
10+
- [Link to PR]()
11+
- Proposed release version: <!-- eg 1.12 -->
12+
13+
<!-- Additional information about the feature: -->
14+
15+
16+
<!-- relevant for most work -->
17+
18+
- [ ] API [documentation](https://github.com/cmu-delphi/delphi-epidata/blob/main/docs/api/covidcast-signals/_source-template.md) and/or [changelog](https://github.com/cmu-delphi/delphi-epidata/blob/main/docs/api/covidcast_changelog.md)
19+
- [ ] API mailing list notification
20+
21+
<!-- relevant for new signals -->
22+
23+
- [ ] Statistical review (usually [correlations](https://github.com/cmu-delphi/covidcast/tree/main/docs/R-notebooks))
24+
- [ ] Signal / source name review (usually [Roni](https://docs.google.com/document/d/10hGd4Evce4lJ4VkWaQEKFQxvmw2P4xyYGtIAWF52Sf8/edit?usp=sharing))
25+
- [ ] Verify licensing terms and any applicable DUA restrictions
26+
27+
<!-- relevant for new map signals -->
28+
29+
- [ ] Visual review
30+
- [ ] [Signal description pop-up text](https://docs.google.com/document/d/1kDqRg8EaI4WQXMaUUbbCGPlsUqEql8kgXCNt6AvMA9I/edit?usp=sharing) review
31+
- [ ] [Map release notes](https://docs.google.com/document/d/1BpxGgIma_Lkd2kxtwEo2DBdHQ3zk6dHRz-leUIRlOIA/edit?usp=sharing)

.github/pull_request_template.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
### Description
2+
Type of change (bug fix, new feature, etc), brief description, and motivation for these changes.
3+
4+
### Changelog
5+
Itemize code/test/documentation changes and files added/removed.
6+
- change1
7+
- change2
8+
9+
### Fixes
10+
- Fixes #(issue)

.github/workflows/python-ci.yml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
2+
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
3+
4+
name: Python package
5+
6+
on:
7+
push:
8+
branches: [ main, prod ]
9+
pull_request:
10+
types: [ opened, synchronize, reopened, ready_for_review ]
11+
branches: [ main, prod ]
12+
13+
jobs:
14+
build:
15+
runs-on: ubuntu-20.04
16+
if: github.event.pull_request.draft == false
17+
strategy:
18+
matrix:
19+
packages: [_delphi_utils_python, cdc_covidnet, changehc, claims_hosp, combo_cases_and_deaths, google_symptoms, jhu, nchs_mortality, quidel, quidel_covidtest, safegraph, safegraph_patterns, usafacts]
20+
defaults:
21+
run:
22+
working-directory: ${{ matrix.packages }}
23+
steps:
24+
- uses: actions/checkout@v2
25+
- name: Set up Python 3.8
26+
uses: actions/setup-python@v2
27+
with:
28+
python-version: 3.8
29+
- name: Install testing dependencies
30+
run: |
31+
python -m pip install --upgrade pip
32+
pip install pylint pytest pydocstyle wheel
33+
- name: Install
34+
run: |
35+
make install
36+
- name: Lint
37+
if: ${{ matrix.packages != 'claims_hosp' }}
38+
run: |
39+
make lint
40+
- name: Test
41+
run: |
42+
make test

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,17 @@ venv.bak/
116116
# mkdocs documentation
117117
/site
118118

119+
# VSCode settings
120+
*.vscode
121+
119122
# mypy
120123
.mypy_cache/
121124

122125
# Ansible
123126
.retry
124127
.indicators-ansible-vault-pass
125128
indicators-ansible-vault-pass
129+
130+
# testing_utils
131+
testing_utils/cache
132+
testing_utils/*.csv

Jenkinsfile

Lines changed: 41 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,81 +1,72 @@
11
#!groovy
22

3-
// import shared library: https://github.com/cmu-delphi/jenkins-shared-library
3+
// Import shared lib.
44
@Library('jenkins-shared-library') _
55

6-
pipeline {
6+
/*
7+
Declare variables.
8+
- indicator_list should contain all the indicators to handle in the pipeline.
9+
- Keep in sync with '.github/workflows/python-ci.yml'.
10+
- TODO: #527 Get this list automatically from python-ci.yml at runtime.
11+
*/
12+
def indicator_list = ["cdc_covidnet", "changehc", "claims_hosp", "combo_cases_and_deaths", "google_symptoms", "jhu", "nchs_mortality", "quidel", "quidel_covidtest", "safegraph", "safegraph_patterns", "usafacts"]
13+
def build_package = [:]
14+
def deploy_staging = [:]
15+
def deploy_production = [:]
716

17+
pipeline {
818
agent any
9-
1019
stages {
11-
12-
stage ("Environment") {
20+
stage('Build and Package') {
1321
when {
14-
anyOf {
15-
branch "deploy-*";
16-
changeRequest target: "deploy-*", comparator: "GLOB"
17-
}
22+
branch "main";
1823
}
1924
steps {
2025
script {
21-
// Get the indicator name from the pipeline env.
22-
if ( env.CHANGE_TARGET ) {
23-
INDICATOR = env.CHANGE_TARGET.replaceAll("deploy-", "")
24-
}
25-
else if ( env.BRANCH_NAME ) {
26-
INDICATOR = env.BRANCH_NAME.replaceAll("deploy-", "")
27-
}
28-
else {
29-
INDICATOR = ""
26+
indicator_list.each { indicator ->
27+
build_package[indicator] = {
28+
sh "jenkins/build-and-package.sh ${indicator}"
29+
}
3030
}
31-
}
32-
}
33-
}
34-
35-
stage('Build') {
36-
when {
37-
changeRequest target: "deploy-*", comparator: "GLOB"
38-
}
39-
steps {
40-
sh "jenkins/${INDICATOR}-jenkins-build.sh"
41-
}
42-
}
43-
44-
stage('Test') {
45-
when {
46-
changeRequest target: "deploy-*", comparator: "GLOB"
47-
}
48-
steps {
49-
sh "jenkins/${INDICATOR}-jenkins-test.sh"
31+
parallel build_package
32+
}
5033
}
5134
}
52-
53-
stage('Package') {
35+
stage('Deploy staging') {
5436
when {
55-
changeRequest target: "deploy-*", comparator: "GLOB"
37+
branch "main";
5638
}
5739
steps {
58-
sh "jenkins/${INDICATOR}-jenkins-package.sh"
40+
script {
41+
indicator_list.each { indicator ->
42+
deploy_staging[indicator] = {
43+
sh "jenkins/deploy-staging.sh ${indicator}"
44+
}
45+
}
46+
parallel deploy_staging
47+
}
5948
}
6049
}
61-
62-
stage('Deploy') {
50+
stage('Deploy production') {
6351
when {
64-
branch "deploy-*"
52+
branch "prod";
6553
}
6654
steps {
67-
sh "jenkins/${INDICATOR}-jenkins-deploy.sh"
55+
script {
56+
indicator_list.each { indicator ->
57+
deploy_production[indicator] = {
58+
sh "jenkins/deploy-production.sh ${indicator}"
59+
}
60+
}
61+
parallel deploy_production
62+
}
6863
}
6964
}
7065
}
71-
7266
post {
7367
always {
7468
script {
75-
/*
76-
Use slackNotifier.groovy from shared library and provide current
77-
build result as parameter.
78-
*/
69+
// Use slackNotifier.groovy from shared lib.
7970
slackNotifier(currentBuild.currentResult)
8071
}
8172
}

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2020 The Delphi Group at Carnegie Mellon University
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

0 commit comments

Comments
 (0)