Skip to content

Commit b5e1d90

Browse files
Merge pull request #178 from CCBR/update-copilot-instructions
chore: 🤖 sync copilot instructions - 2026-03-13
2 parents 915a738 + 56f0cd7 commit b5e1d90

6 files changed

Lines changed: 182 additions & 14 deletions

File tree

.github/copilot-instructions.md

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
# CoPilot Instructions for CCBR Repositories
2+
3+
## Reviewer guidance (what to look for in PRs)
4+
5+
- Reviewers must validate enforcement rules: no secrets, container specified, and reproducibility pins.
6+
- If code is AI-generated, reviewers must ensure the author documents what was changed and why, and that the PR is labeled `generated-by-AI`.
7+
- Reviewers should verify license headers and ownership metadata (for example, `CODEOWNERS`) are present.
8+
- Reviews must read the code and verify that it adheres to the project's coding standards, guidelines, and best practices in software engineering.
9+
10+
## CI & enforcement suggestions (automatable)
11+
12+
1. **PR template**: include optional AI-assistance disclosure fields (model used, high-level prompt intent, manual review confirmation).
13+
2. **Pre-merge check (GitHub Action)**: verify `.github/copilot-instructions.md` is present in the repository and that new pipeline files include a `# CRAFT:` header.
14+
3. **Lint jobs**: `ruff` for Python, `shellcheck` for shell, `lintr` for R, and `nf-core lint` or Snakemake lint checks where applicable.
15+
4. **Secrets scan**: run `TruffleHog` or `Gitleaks` on PRs to detect accidental credentials.
16+
5. **AI usage label**: if AI usage is declared, an Action should add `generated-by-AI` label (create this label if it does not exist); the PR body should end with the italicized Markdown line: _Generated using AI_, and any associated commit messages should end with the plain footer line: `Generated using AI`.
17+
18+
_Sample GH Action check (concept): if AI usage is declared, require an AI-assistance disclosure field in the PR body._
19+
20+
## Security & compliance (mandatory)
21+
22+
- Developers must not send PHI or sensitive NIH internal identifiers to unapproved external AI services; use synthetic examples.
23+
- Repository content must only be sent to model providers approved by NCI/NIH policy (for example, Copilot for Business or approved internal proxies).
24+
- For AI-assisted actions, teams must keep an auditable record including: user, repository, action, timestamp, model name, and endpoint.
25+
- If using a server wrapper (Option C), logs must include the minimum metadata above and follow institutional retention policy.
26+
- If policy forbids external model use for internal code, teams must use approved local/internal LLM workflows.
27+
28+
## Operational notes (practical)
29+
30+
- `copilot-instructions.md` should remain concise and prescriptive; keep only high-value rules and edge-case examples.
31+
- Developers should include the CRAFT block in edited files when requesting substantial generated code to improve context quality.
32+
- CoPilot must ask the user for permission before deleting any file unless the file was created by CoPilot for a temporary run or test.
33+
- CoPilot must not edit any files outside of the current open workspace.
34+
35+
## Code authoring guidance
36+
37+
- Code must not include hard-coded secrets, credentials, or sensitive absolute paths on disk.
38+
- Code should be designed for modularity, reusability, and maintainability. It should ideally be platform-agnostic, with special support for running on the Biowulf HPC.
39+
- Use pre-commit to enforce code style and linting during the commit process.
40+
41+
### Pipelines
42+
43+
- Authors must review existing CCBR pipelines first: <https://github.com/CCBR>.
44+
- New pipelines should follow established CCBR conventions for folder layout, rule/process naming, config structure, and test patterns.
45+
- Pipelines must define container images and pin tool/image versions for reproducibility.
46+
- Contributions should include a test dataset and a documented example command.
47+
48+
#### Snakemake
49+
50+
- In general, new pipelines should be created with Nextflow rather than Snakemake, unless there is a compelling reason to use Snakemake.
51+
- Generate new pipelines from the CCBR_SnakemakeTemplate repo: <https://github.com/CCBR/CCBR_SnakemakeTemplate>
52+
- For Snakemake, run `snakemake --lint` and a dry-run before PR submission.
53+
54+
#### Nextflow
55+
56+
- Generate new pipelines from the CCBR_NextflowTemplate repo: <https://github.com/CCBR/CCBR_NextflowTemplate>
57+
- For Nextflow pipelines, authors must follow nf-core patterns and references: <https://nf-co.re>.
58+
- Nextflow code must use DSL2 only (DSL1 is not allowed).
59+
- For Nextflow, run `nf-core lint` (or equivalent checks) before PR submission.
60+
- Where possible, reuse modules and subworkflows from CCBR/nf-modules or nf-core/modules.
61+
- New modules and subworkflows should be tested with `nf-test`.
62+
63+
### Python scripts and packages
64+
65+
- Python scripts must include module and function/class docstrings.
66+
- Where a standard CLI framework is adopted, Python CLIs should use `click` or `typer` for consistency with existing components.
67+
- Scripts must support `--help` and document required/optional arguments.
68+
- Python code must follow [PEP 8](https://peps.python.org/pep-0008/), use `snake_case`, and include type hints for public functions.
69+
- Scripts must raise descriptive error messages on failure and warnings when applicable. Prefer raising an exception over printing an error message, and over returning an error code.
70+
- Python code should pass `ruff`;
71+
- Each script must include a documented example usage in comments or README.
72+
- Tests should be written with `pytest`. Other testing frameworks may be used if justified.
73+
- Do not catch bare exceptions. The exception type must always be specified.
74+
- Only include one return statement at the end of a function.
75+
76+
### R scripts and packages
77+
78+
- R scripts must include function and class docstrings via roxygen2.
79+
- CLIs must be defined using the `argparse` package.
80+
- CLIs must support `--help` and document required/optional arguments.
81+
- R code should pass `lintr` and `air`.
82+
- Tests should be written with `testthat`.
83+
- Packages should pass `devtools::check()`.
84+
- R code should adhere to the tidyverse style guide. https://style.tidyverse.org/
85+
- Only include one return statement at the end of a function, if a return statement is used at all. Explicit returns are preferred but not required for R functions.
86+
87+
## AI-generated commit messages (Conventional Commits)
88+
89+
- Commit messages must follow [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) (as enforced in `CONTRIBUTING.md`).
90+
- Generate messages from staged changes only (`git diff --staged`); do not include unrelated work.
91+
- Commits should be atomic: one logical change per commit.
92+
- If mixed changes are present, split into multiple logical commits; the number of commits does not need to equal the number of files changed.
93+
- Subject format must be: `<type>(optional-scope): short imperative summary` (<=72 chars), e.g., `fix(profile): update release table parser`.
94+
- Add a body only when needed to explain **why** and notable impact; never include secrets, tokens, PHI, or large diffs.
95+
- For AI-assisted commits, add this final italicized footer line in the commit message body: _commit message is ai-generated_
96+
97+
Suggested prompt for AI tools:
98+
99+
```text
100+
Create a Conventional Commit message from this staged diff.
101+
Rules:
102+
1) Use one of: feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert.
103+
2) Keep subject <= 72 chars, imperative mood, no trailing period.
104+
3) Include optional scope when clear.
105+
4) Add a short body only if needed (why/impact), wrapped at ~72 chars.
106+
5) Output only the final commit message.
107+
```
108+
109+
## Pull Requests
110+
111+
When opening a pull request, use the repository's pull request template (usually it is `.github/PULL_REQUEST_TEMPLATE.md`).
112+
Different repos have different PR templates depending on their needs.
113+
Ensure that the pull request follows the repository's PR template and includes all required information.
114+
Do not allow the developer to proceed with opening a PR if it does not fill out all sections of the template.
115+
Before a PR can be moved from draft to "ready for review", all of the relevant checklist items must be checked, and any
116+
irrelevant checklist items should be crossed out.
117+
118+
When new features, bug fixes, or other behavioral changes are introduced to the code,
119+
unit tests must be added or updated to cover the new or changed functionality.
120+
121+
If there are any API or other user-facing changes, the documentation must be updated both inline via docstrings and long-form docs in the `docs/` or `vignettes/` directory.
122+
123+
When a repo contains a build workflow (i.e. a workflow file in `.github/workflows` starting with `build` or named `R-CMD-check`),
124+
the build workflow must pass before the PR can be approved.
125+
126+
### Changelog
127+
128+
The changelog for the repository should be maintained in a `CHANGELOG.md` file
129+
(or `NEWS.md` for R packages) at the root of the repository. Each pull request
130+
that introduces user-facing changes must include a concise entry with the PR
131+
number and author username tagged. Developer-only changes (i.e. updates to CI
132+
workflows, development notes, etc.) should never be included in the changelog.
133+
Example:
134+
135+
```
136+
## development version
137+
138+
- Fix bug in `detect_absolute_paths()` to ignore comments. (#123, @username)
139+
```
140+
141+
## Onboarding checklist for new developers
142+
143+
- [ ] Read `.github/CONTRIBUTING.md` and `.github/copilot-instructions.md`.
144+
- [ ] Configure VSCode workspace to open `copilot-instructions.md` by default (so Copilot Chat sees it).
145+
- [ ] Install pre-commit and run `pre-commit install`.
146+
147+
## Appendix: VSCode snippet (drop into `.vscode/snippets/craft.code-snippets`)
148+
149+
```json
150+
{
151+
"Insert CRAFT prompt": {
152+
"prefix": "craft",
153+
"body": [
154+
"/* C: Context: Repo=${workspaceFolderBasename}; bioinformatics pipelines; NIH HPC (Biowulf/Helix); containers: quay.io/ccbr */",
155+
"/* R: Rules: no PHI, no secrets, containerize, pin versions, follow style */",
156+
"/* F: Flow: inputs/ -> results/, conf/, tests/ */",
157+
"/* T: Tests: provide a one-line TEST_CMD and expected output */",
158+
"",
159+
"A: $1"
160+
],
161+
"description": "Insert CRAFT prompt and place cursor at Actions"
162+
}
163+
}
164+
```

bin/install_biowulf.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,4 @@ fi
2727

2828
if [[ ":$PYTHONPATH:" != *":${install_path}:"* ]];then
2929
export PYTHONPATH="${PYTHONPATH}:${install_path}"
30-
fi
30+
fi

docs/usage/gui.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,14 @@ _NOTE: `ccbrpipeliner` is a custom module created on biowulf which contains vari
3030
```bash
3131
# Setup Step 3.) Add ccbrpipeliner module
3232

33-
module purge
33+
module purge
3434
module load ccbrpipeliner
3535
```
3636

3737
If the module was loaded correctly, the greetings message should be displayed.
3838

3939
```bash
40-
[+] Loading ccbrpipeliner 8 ...
40+
[+] Loading ccbrpipeliner 8 ...
4141
###########################################################################
4242
CCBR Pipeliner release 8
4343
###########################################################################
@@ -47,7 +47,7 @@ If the module was loaded correctly, the greetings message should be displayed.
4747
Tools are available on BIOWULF, HELIX and FRCE.
4848

4949
The following pipelines/tools will be loaded in this module:
50-
50+
5151
PIPELINES:
5252
ASPEN v1.1 ATAC-seq https://ccbr.github.io/ASPEN/1.1
5353
CARLISLE v2.7 CUT&RUN https://ccbr.github.io/CARLISLE/2.7
@@ -59,12 +59,12 @@ If the module was loaded correctly, the greetings message should be displayed.
5959
RENEE v2.7 bulk RNA-seq https://ccbr.github.io/RENEE/2.7
6060
SINCLAIR v0.3 scRNA-seq https://ccbr.github.io/SINCLAIR/0.3
6161
XAVIER v3.2 whole exome-seq https://ccbr.github.io/XAVIER/3.2
62-
62+
6363
TOOLS:
6464
spacesavers2 v0.14 https://ccbr.github.io/spacesavers2/
6565
permfix v0.6 https://github.com/ccbr/permfix/
6666
ccbr_tools v0.4 https://ccbr.github.io/Tools/
67-
67+
6868
###########################################################################
6969
Thank you for using CCBR Pipeliner
7070
Comments/Questions/Requests:

src/xavier/__main__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ def parsed_arguments():
338338
required=True,
339339
# choices = ['hg38', 'hg38_noalt', 'mm10'],
340340
type=lambda option: str(
341-
genome_options(subparser_run, option, ["hg38", "hg38_noalt","mm10"])
341+
genome_options(subparser_run, option, ["hg38", "hg38_noalt", "mm10"])
342342
),
343343
help=argparse.SUPPRESS,
344344
)

src/xavier/run.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ def run(sub_args):
102102
else:
103103
log = os.path.join(sub_args.output, "logfiles", "master.log")
104104
logfh = open(log, "w")
105-
105+
106106
mjob = runner(
107107
mode=sub_args.mode,
108108
outdir=sub_args.output,
@@ -192,11 +192,13 @@ def init(
192192

193193
return inputs
194194

195+
195196
def _now():
196197
ct = datetime.datetime.now()
197198
now = ct.strftime("%y%m%d%H%M%S")
198199
return now
199200

201+
200202
def copy_safe(source, target, resources=[]):
201203
"""Private function: Given a list paths it will recursively copy each to the
202204
target location. If a target path already exists, it will NOT over-write the
@@ -728,8 +730,10 @@ def get_rawdata_bind_paths(input_files):
728730

729731

730732
def dryrun(
731-
outdir, config="config.json", snakefile=os.path.join("workflow", "Snakefile"),
732-
write_to_file=True,
733+
outdir,
734+
config="config.json",
735+
snakefile=os.path.join("workflow", "Snakefile"),
736+
write_to_file=True,
733737
):
734738
"""Dryruns the pipeline to ensure there are no errors prior to running.
735739
@param outdir <str>:
@@ -768,7 +772,7 @@ def dryrun(
768772
except subprocess.CalledProcessError as e:
769773
print(e, e.output)
770774
raise (e)
771-
775+
772776
if write_to_file:
773777
now = _now()
774778
with open(os.path.join(outdir, "dryrun." + str(now) + ".log"), "w") as outfile:

tests/data/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
These input files are used for continuous integration purposes, specifically to dry run the pipeline whenever commits have been made to the main, master, or unified branches.
44

5-
Human whole exome sequence reads from the Sequencing Quality Control Phase 2 (SEQC2) Consortium has been subsampled and added.
5+
Human whole exome sequence reads from the Sequencing Quality Control Phase 2 (SEQC2) Consortium has been subsampled and added.
66

7-
The tumor-normal paired reads were downloaded from the [seqc2](https://sites.google.com/view/seqc2/home/sequencing) server that were sequenced by the NCI (WES_NC_T_1 vs. WES_NC_N_1) which corresponds to NCBI SRA accession no. [SRX4728524](https://www.ncbi.nlm.nih.gov/sra/SRX4728524) and [SRX4728523](https://www.ncbi.nlm.nih.gov/sra/SRX4728523) respectively.
7+
The tumor-normal paired reads were downloaded from the [seqc2](https://sites.google.com/view/seqc2/home/sequencing) server that were sequenced by the NCI (WES_NC_T_1 vs. WES_NC_N_1) which corresponds to NCBI SRA accession no. [SRX4728524](https://www.ncbi.nlm.nih.gov/sra/SRX4728524) and [SRX4728523](https://www.ncbi.nlm.nih.gov/sra/SRX4728523) respectively.
88

99
Next, the reads were subsampled to 0.1% using `seqtk` and gzipped as follows:
1010

@@ -17,4 +17,4 @@ Similarly, the BAM files were created by first mapping to the hg38 genome and th
1717

1818
```bash
1919
samtools view -s 0.00125 -b WES_NC_[T/N]_1.bam -o WES_NC_[T/N]_1_sub.bam
20-
```
20+
```

0 commit comments

Comments
 (0)