Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
11 changes: 11 additions & 0 deletions .detect-secrets-ignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Per-repo secret detection exclusions for your_package_name.
# One regex per line; lines starting with # are comments.
# These supplement the global exclusions in scripts/detect_secrets_baseline.sh.

# Test fixture directories that may contain sample/fake credentials
.*/test/data/.*
.*/tests/data/.*

# Documentation files contain placeholder/example credentials only
README\.md
CHANGELOG\.md
63 changes: 11 additions & 52 deletions .github/workflows/secrets-detection.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,63 +16,22 @@ jobs:
name: Checkout code
uses: actions/checkout@v6
-
name: Install necessary packages
run: |
pip install git+https://github.com/NASA-AMMOS/slim-detect-secrets.git@exp
pip install jq
name: Install detect-secrets
run: pip install detect-secrets~=1.5.0

-
name: Create an initial .secrets.baseline if .secrets.baseline does not exist
name: Verify .secrets.baseline exists
run: |
if [ ! -f .secrets.baseline ]; then
# This generated baseline file will only be temporarily available on the GitHub side and will not appear in the user's local files.
# Scanning an empty folder to generate an initial .secrets.baseline without secrets in the results.
echo "⚠️ No existing .secrets.baseline file detected. Creating a new blank baseline file."
mkdir empty-dir
detect-secrets scan empty-dir > .secrets.baseline
echo "βœ… Blank .secrets.baseline file created successfully."
rm -r empty-dir
else
echo "βœ… Existing .secrets.baseline file detected. No new baseline file will be created."
echo "❌ No .secrets.baseline found." >&2
echo "" >&2
echo "Run the following locally, audit the results, then commit the baseline:" >&2
echo " scripts/detect_secrets_baseline.sh scan" >&2
echo " scripts/detect_secrets_baseline.sh audit" >&2
exit 1
fi
echo "βœ… .secrets.baseline found."

-
name: Scan repository for secrets
run: |
# scripts to scan repository for new secrets

# backup the list of known secrets
cp .secrets.baseline .secrets.new

# find the secrets in the repository
detect-secrets scan --disable-plugin AbsolutePathDetectorExperimental --baseline .secrets.new \
--exclude-files '\.secrets..*' \
--exclude-files '\.git.*' \
--exclude-files '\.mypy_cache' \
--exclude-files '\.pytest_cache' \
--exclude-files '\.tox' \
--exclude-files '\.venv' \
--exclude-files 'venv' \
--exclude-files 'dist' \
--exclude-files 'build' \
--exclude-files '.*\.egg-info' \
--exclude-files '\.pre-commit-config\.yaml'

# if there is any difference between the known and newly detected secrets, break the build
# Function to compare secrets without listing them
compare_secrets() { diff <(jq -r '.results | keys[] as $key | "\($key),\(.[$key] | .[] | .hashed_secret)"' "$1" | sort) <(jq -r '.results | keys[] as $key | "\($key),\(.[$key] | .[] | .hashed_secret)"' "$2" | sort) >/dev/null; }

# Check if there's any difference between the known and newly detected secrets
if ! compare_secrets .secrets.baseline .secrets.new; then
echo "⚠️ Attention Required! ⚠️" >&2
echo "New secrets have been detected in your recent commit. Due to security concerns, we cannot display detailed information here and we cannot proceed until this issue is resolved." >&2
echo "" >&2
echo "Please follow the steps below on your local machine to reveal and handle the secrets:" >&2
echo "" >&2
echo "1️⃣ Run the 'detect-secrets' tool on your local machine. This tool will identify and clean up the secrets. You can find detailed instructions at this link: https://nasa-ammos.github.io/slim/continuous-testing/starter-kits/#detect-secrets" >&2
echo "" >&2
echo "2️⃣ After cleaning up the secrets, commit your changes and re-push your update to the repository." >&2
echo "" >&2
echo "Your efforts to maintain the security of our codebase are greatly appreciated!" >&2
exit 1
fi
run: scripts/detect_secrets_baseline.sh
26 changes: 6 additions & 20 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -56,24 +56,10 @@ repos:
stages: [push]
pass_filenames: false

- repo: https://github.com/NASA-AMMOS/slim-detect-secrets
# using commit id for now, will change to tag when official version is released
rev: 91e097ad4559ae6ab785c883dc5ed989202c7fbe
- repo: local
hooks:
- id: detect-secrets
args:
- '--disable-plugin'
- 'AbsolutePathDetectorExperimental'
- '--baseline'
- '.secrets.baseline'
- --exclude-files '\.secrets..*'
- --exclude-files '\.git.*'
- --exclude-files '\.mypy_cache'
- --exclude-files '\.pytest_cache'
- --exclude-files '\.tox'
- --exclude-files '\.venv'
- --exclude-files 'venv'
- --exclude-files 'dist'
- --exclude-files 'build'
- --exclude-files '.*\.egg-info'
- --exclude-files '\.pre-commit-config\.yaml'
- id: detect-secrets
name: detect-secrets
entry: scripts/detect_secrets_baseline.sh
language: script
pass_filenames: false
42 changes: 25 additions & 17 deletions .secrets.baseline
Original file line number Diff line number Diff line change
@@ -1,18 +1,12 @@
{
"version": "1.4.0",
"version": "1.5.0",
"plugins_used": [
{
"name": "AbsolutePathDetectorExperimental"
},
{
"name": "ArtifactoryDetector"
},
{
"name": "AWSKeyDetector"
},
{
"name": "AWSSensitiveInfoDetectorExperimental"
},
{
"name": "AzureStorageKeyDetector"
},
Expand All @@ -30,10 +24,10 @@
"name": "DiscordBotTokenDetector"
},
{
"name": "EmailAddressDetector"
"name": "GitHubTokenDetector"
},
{
"name": "GitHubTokenDetector"
"name": "GitLabTokenDetector"
},
{
"name": "HexHighEntropyString",
Expand Down Expand Up @@ -61,9 +55,15 @@
{
"name": "NpmDetector"
},
{
"name": "OpenAIDetector"
},
{
"name": "PrivateKeyDetector"
},
{
"name": "PypiTokenDetector"
},
{
"name": "SendGridDetector"
},
Expand All @@ -79,6 +79,9 @@
{
"name": "StripeDetector"
},
{
"name": "TelegramBotTokenDetector"
},
{
"name": "TwilioKeyDetector"
}
Expand Down Expand Up @@ -125,7 +128,7 @@
{
"path": "detect_secrets.filters.regex.should_exclude_file",
"pattern": [
"\\.secrets..*",
"\\.secrets\\..*",
"\\.git.*",
"\\.pre-commit-config\\.yaml",
"\\.mypy_cache",
Expand All @@ -135,21 +138,26 @@
"venv",
"dist",
"build",
".*\\.egg-info"
".*\\.egg-info",
"scripts/detect_secrets_baseline\\.sh",
".*/test/data/.*",
".*/tests/data/.*",
"README\\.md",
"CHANGELOG\\.md"
]
}
],
"results": {
"setup.cfg": [
"CLAUDE.md": [
{
"type": "Email Address",
"filename": "setup.cfg",
"hashed_secret": "3a6d7aa49a8e4a2fe32a5cd0e53da9cb96bd8d29",
"type": "Secret Keyword",
"filename": "CLAUDE.md",
"hashed_secret": "17af698d29702c0d4121498fa6ed3c8346944b42",
"is_verified": false,
"line_number": 22,
"line_number": 97,
"is_secret": false
}
]
},
"generated_at": "2024-10-02T16:13:34Z"
"generated_at": "2026-07-03T00:22:23Z"
}
108 changes: 108 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

> **Template repo notice:** This file was generated for `template-repo-python`. If you created a new repo from this template, update this file to reflect your project's actual package name, commands, and architecture before using it.

## Purpose

This is NASA-PDS's template repository for new Python projects. When working in a repo created from this template, the placeholder `your_package_name` must be replaced with the actual module name throughout `setup.cfg`, `src/pds/`, `tests/`, and other files.

## Commands

### Setup

```bash
python -m venv venv
source venv/bin/activate
pip install --editable '.[dev]'
```

Or via tox:

```bash
tox --devenv venv -e dev
```

### Testing

```bash
pytest # run all tests
pytest tests/path/test_foo.py # run a single test file
pytest -k "test_name" # run a single test by name
ptw # watch mode
```

Tests run in parallel by default (`--numprocesses auto`) with coverage reporting to XML and terminal.

### Linting

```bash
tox -e lint # run all linters (flake8, mypy, pre-commit hooks)
flake8 src # flake8 only
mypy src # type-checking only
```

### Full build (tests + lint + docs)

```bash
tox
```

### Documentation

```bash
sphinx-build docs/source docs/build
# output at docs/build/index.html
```

### Build package

```bash
pip install build
python -m build .
```

### Secrets detection

```bash
scripts/detect_secrets_baseline.sh scan # regenerate .secrets.baseline
scripts/detect_secrets_baseline.sh audit # interactively review/classify detected secrets
scripts/detect_secrets_baseline.sh # check for new secrets vs baseline (run by pre-commit)
```

Per-repo file exclusions go in `.detect-secrets-ignore` (one regex per line). Global exclusions (`.git`, `venv`, `dist`, etc.) are baked into the script.

## Architecture

### Package layout

Source lives under `src/pds/<package_name>/` using a [PEP 420 namespace package](https://peps.python.org/pep-0420/) β€” `src/pds/__init__.py` is intentionally minimal (no `__path__` manipulation) to support the `pds.*` namespace shared across multiple PDS Python packages.

Version is read at import time from `src/pds/<package_name>/VERSION.txt` via `importlib.resources`, not hardcoded.

Entry points (CLI scripts) are declared in `setup.cfg` under `[options.entry_points] console_scripts`.

### Tests

Tests go in `tests/pds/<package_name>/` mirroring the source tree. The `[tool:pytest]` section in `setup.cfg` configures coverage to report on the `pds` namespace.

### CI/CD

Two standard GitHub Actions workflows drive releases via [NASA-PDS/roundup-action](https://github.com/NASA-PDS/roundup-action):

- **`unstable-cicd.yaml`** β€” triggers on push to `main`; publishes a SNAPSHOT release to Test PyPI
- **`stable-cicd.yaml`** β€” triggers on push to `release/<version>` branches; publishes stable releases to PyPI

Required repository secrets: `ADMIN_GITHUB_TOKEN`, `TEST_PYPI_USERNAME`, `TEST_PYPI_PASSWORD`, `SONAR_TOKEN`.

### Code style

- **flake8** enforces PEP8 + docstrings (Google convention) + bugbear; max line length 120
- **mypy** enforces type annotations across `src/`
- **black** is configured (`pyproject.toml`) but disabled in pre-commit due to conflict with `reorder-python-imports`
- Pre-commit hooks run mypy + flake8 on commit; pytest runs on push

### Logging

Use `logging.getLogger(__name__)` β€” never `print()` for runtime output.
31 changes: 9 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,29 +72,18 @@ Install in editable mode and with extra developer dependencies into your virtual

Make a baseline for any secrets (email addresses, passwords, API keys, etc.) in the repository:

detect-secrets scan . \
--all-files \
--exclude-files '\.secrets..*' \
--exclude-files '\.git.*' \
--exclude-files '\.mypy_cache' \
--exclude-files '\.pytest_cache' \
--exclude-files '\.tox' \
--exclude-files '\.venv' \
--exclude-files 'venv' \
--exclude-files 'dist' \
--exclude-files 'build' \
--exclude-files '.*\.egg-info' \
--exclude-files '\.pre-commit-config\.yaml' \
> .secrets.baseline

Review the secrets to determine which should be allowed and which are false positives:

detect-secrets audit .secrets.baseline

Please remove any secrets that should not be seen by the public. You can then add the baseline file to the commit:
scripts/detect_secrets_baseline.sh scan

Review and classify each detected secret (mark as `is_secret: true/false`):

scripts/detect_secrets_baseline.sh audit

Commit the baseline:

git add .secrets.baseline

To exclude additional files specific to this repo from scanning, add regex patterns (one per line) to `.detect-secrets-ignore`. Global exclusions (`.git`, `venv`, `dist`, etc.) are already handled by the script.

Then, configure the `pre-commit` hooks:

pre-commit install
Expand All @@ -104,8 +93,6 @@ Then, configure the `pre-commit` hooks:

These hooks then will check for any future commits that might contain secrets. They also check code formatting, PEP8 compliance, type hints, etc.

πŸ‘‰ **Note:** A one time setup is required both to support `detect-secrets` and in your global Git configuration. See [the wiki entry on Secrets](https://github.com/NASA-PDS/nasa-pds.github.io/wiki/Git-and-Github-Guide#detect-secrets) to learn how.


### Packaging

Expand Down
Loading
Loading