Skip to content

Commit 92e4dfa

Browse files
medley56Copilot
andauthored
Ai and devops (#249)
* Devops and AI Related Improvements Improve factoring of agent instructions for Copilot/Claude Simplify devcontainer config and add per-file debug launch config * Add .claude to git tracking for skills and common settings Update changelog to match Keep A Changelog formatting * Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 3ae56b0 commit 92e4dfa

10 files changed

Lines changed: 300 additions & 296 deletions

File tree

.claude/CLAUDE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
@.github/instructions/space_packet_parser.instructions.md
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
Update `docs/source/changelog.md` based on recent git history. Follow these steps exactly.
2+
3+
## Step 1 — Gather context
4+
5+
Run the following commands:
6+
7+
```bash
8+
git tag --sort=-version:refname | head -1
9+
```
10+
11+
Save the output as `LATEST_TAG`. Then run:
12+
13+
```bash
14+
git log <LATEST_TAG>..HEAD --oneline --no-merges
15+
git log <LATEST_TAG>..HEAD --oneline --merges
16+
```
17+
18+
Read these files in full:
19+
20+
- `docs/source/changelog.md`
21+
- `pyproject.toml` (find `version =` under `[project]`)
22+
- `meta.yaml` (find `version:` field)
23+
- `CITATION.cff` (find `version:` field)
24+
25+
## Step 2 — Detect release scenario
26+
27+
Compare the version in `pyproject.toml` / `meta.yaml` / `CITATION.cff` against `LATEST_TAG`.
28+
29+
- If the version in the files **differs** from `LATEST_TAG`, use `AskUserQuestion` to confirm:
30+
> "Version X.Y.Z appears in pyproject.toml/meta.yaml/CITATION.cff but the latest git tag is LATEST_TAG. Is this a new release that should be added as a versioned section in the changelog?"
31+
- If the user confirms → **Scenario A** (new release)
32+
- If the user declines → **Scenario B** (update unreleased only)
33+
- If the version already matches `LATEST_TAG`**Scenario B** automatically.
34+
35+
## Step 3 — Analyze git log
36+
37+
From the combined output of both `git log` commands:
38+
39+
- Identify meaningful changes. Look for PR numbers via patterns `(#NNN)` or `Merge pull request #NNN`.
40+
- **Skip**: pure Dependabot dependency bumps (e.g. "Bump X from Y to Z"), CI/workflow-only changes with no user-visible impact.
41+
- Classify each meaningful change into one of these Keep A Changelog categories:
42+
- `Added` — new features or capabilities
43+
- `Changed` — changes to existing behavior; prefix `_BREAKING_:` for breaking changes
44+
- `Fixed` — bug fixes
45+
- `Removed` — removed features or APIs; prefix `_BREAKING_:` for breaking removals
46+
- `Deprecated` — features marked for future removal
47+
- `Security` — security fixes
48+
- Format each entry as:
49+
```
50+
- Description of the change. [#NNN](https://github.com/lasp/space_packet_parser/issues/NNN)
51+
```
52+
- Check the existing `## [Unreleased]` section in the changelog — do **not** duplicate entries already present there.
53+
54+
## Step 4 — Edit the changelog
55+
56+
### Scenario A — New release (user confirmed)
57+
58+
Let:
59+
60+
- `NEW_VERSION` = version from `pyproject.toml`
61+
- `TODAY` = today's date in `YYYY-MM-DD` format
62+
- `PREV_TAG` = `LATEST_TAG`
63+
64+
1. Rename the `## [Unreleased]` heading to `## [NEW_VERSION] - TODAY`. Populate its body with the categorized entries from Step 3, preserving any entries that were already in `[Unreleased]` before them.
65+
2. Insert a new empty `## [Unreleased]` section above the renamed section:
66+
67+
```markdown
68+
## [Unreleased]
69+
70+
## [NEW_VERSION] - TODAY
71+
```
72+
73+
3. Update the footer diff links at the bottom of the file:
74+
- Change the `[unreleased]` link to:
75+
```
76+
[unreleased]: https://github.com/lasp/space_packet_parser/compare/NEW_VERSION...HEAD
77+
```
78+
- Insert a new versioned link immediately after the `[unreleased]` line:
79+
```
80+
[NEW_VERSION]: https://github.com/lasp/space_packet_parser/compare/PREV_TAG...NEW_VERSION
81+
```
82+
83+
### Scenario B — Update unreleased only
84+
85+
1. Add the categorized entries from Step 3 under the appropriate `### Category` headings within the existing `## [Unreleased]` section. Create any missing `### Category` headings as needed.
86+
2. Footer: if `[unreleased]` currently points to a tag other than `LATEST_TAG`, update it to:
87+
```
88+
[unreleased]: https://github.com/lasp/space_packet_parser/compare/LATEST_TAG...HEAD
89+
```
90+
91+
## Step 5 — Verify
92+
93+
After editing, confirm:
94+
95+
- `## [Unreleased]` is the first version section in the file.
96+
- All new entries are under the correct `### Category` heading.
97+
- The footer `[unreleased]` link ends with `...HEAD`.
98+
- No duplicate entries exist.
99+
- Footer versioned links are in descending version order.

.devcontainer/Dockerfile

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,3 @@ RUN sh -c "$(wget -O- https://github.com/deluan/zsh-in-docker/releases/download/
7979
# Copy and set up dev environment script
8080
COPY setup-dev-environment.sh /usr/local/bin/
8181
RUN chmod +x /usr/local/bin/setup-dev-environment.sh
82-
83-
# Copy CLAUDE.md and settings to Claude config directory
84-
COPY CLAUDE.md /root/.claude/

.devcontainer/devcontainer.json

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
"python-envs.terminal.autoActivationType": "command",
3030
"python.testing.pytestEnabled": true,
3131
"python.testing.unittestEnabled": false,
32-
"python.testing.pytestArgs": ["-s", "."],
32+
"python.testing.pytestArgs": ["."],
3333
"debugpy.debugJustMyCode": false,
3434
"files.associations": {
3535
"*.xtce": "xml"
@@ -43,6 +43,18 @@
4343
},
4444
"ruff.organizeImports": true,
4545
"ruff.fixAll": true
46+
},
47+
"launch": {
48+
"configurations": [
49+
{
50+
"name": "Python Debugger: Current File",
51+
"type": "debugpy",
52+
"request": "launch",
53+
"program": "${file}",
54+
"console": "integratedTerminal",
55+
"justMyCode": false
56+
}
57+
]
4658
}
4759
}
4860
},

.devcontainer/setup-dev-environment.sh

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,11 @@ if [ "$SSH_AVAILABLE" = "true" ]; then
4949
if ssh -T git@github.com 2>&1 | grep -q "successfully authenticated"; then
5050
echo "Successfully authenticated with GitHub via SSH."
5151
else
52-
echo "SSH agent available but GitHub SSH authentication failed."
52+
echo "SSH agent available but GitHub SSH authentication failed. This is probably because either your IDE isn't forwarding your SSH agent or you have forgotten to add your SSH key to your ssh-agent."
5353
fi
5454
else
5555
echo "SSH authentication not available. Using HTTPS authentication."
56-
echo "You will need to authenticate either by forwarding your HTTP credentials through (should happen automatically) or by using the gh CLI."
56+
echo "You will need to authenticate either by forwarding your HTTP credentials through (may happen automatically) or by using the gh CLI."
5757
fi
5858

5959
# Configure Git commit signing
@@ -80,8 +80,8 @@ fi
8080
if { [ "$COMMIT_GPGSIGN" = "true" ] || [ "$TAG_GPGSIGN" = "true" ]; } && [ -n "$(git config --get user.signingkey)" ]; then
8181
SIGNING_KEY=$(git config --get user.signingkey)
8282
if ! gpg --list-keys "$SIGNING_KEY" >/dev/null 2>&1; then
83-
echo "Warning: The signing key '$SIGNING_KEY' is not available in GPG keyring."
84-
echo "Commits/tags may fail to sign."
83+
echo "Warning: The signing key '$SIGNING_KEY' is not available in GPG keyring. This probably means your IDE isn't forwarding your GPG agent."
84+
echo "Commits/tags may fail to sign. If you don't care about signing, run `git config --unset commit.gpgsign` and `git config --unset tag.gpgsign` to disable signing."
8585
else
8686
echo "Configured GPG signing key '$SIGNING_KEY' is available."
8787
fi
@@ -94,4 +94,4 @@ echo " Signing key: $(git config --get user.signingkey | cut -c1-50)..."
9494
echo " Sign commits: $(git config --get commit.gpgsign || echo 'NOT SET')"
9595
echo " Sign tags: $(git config --get tag.gpgsign || echo 'NOT SET')"
9696
echo " User name: $(git config --get user.name || echo 'NOT SET')"
97-
echo " User email: $(git config --get user.email || echo 'NOT SET')"
97+
echo " User email: $(git config --get user.email || echo 'NOT SET')"

.github/copilot-instructions.md

Lines changed: 3 additions & 221 deletions
Original file line numberDiff line numberDiff line change
@@ -1,223 +1,5 @@
11
# GitHub Copilot Instructions for Space Packet Parser
22

3-
## Project Overview
4-
5-
Space Packet Parser is a Python library for decoding CCSDS (Consultative Committee for Space Data Systems) telemetry packets according to XTCE (XML Telemetric and Command Exchange) packet structure definitions. The library is based on the UML model of the XTCE specification and aims to support all but the most esoteric elements of the XTCE telemetry packet specification.
6-
7-
### Key Concepts
8-
9-
- **CCSDS**: Space data systems standard for space communications
10-
- **XTCE**: XML-based format for describing telemetry and command data structures
11-
- **Telemetry Packets**: Binary data packets from spacecraft/instruments that need to be parsed and decoded
12-
13-
## Technical Requirements
14-
15-
### Python Version
16-
17-
- **Minimum**: Python 3.9+
18-
- **Tested on**: Python 3.9, 3.10, 3.11, 3.12, 3.13
19-
20-
### Core Dependencies
21-
22-
- `lxml>=4.8.0` - XML parsing for XTCE definitions
23-
- `click>=8.0` - CLI framework
24-
- `rich>=13.0` - Terminal formatting and output
25-
- `xarray` (optional) - Multi-dimensional data arrays
26-
- `numpy` (optional) - Numerical computing
27-
28-
## Development Setup
29-
30-
### Installation
31-
32-
```bash
33-
# Install with development dependencies using pip
34-
pip install ".[test,xarray]"
35-
36-
# For development with uv (creates and manages virtual environment)
37-
uv sync --all-extras
38-
```
39-
40-
### Pre-commit Hooks
41-
42-
The project uses pre-commit hooks for code quality. Install them with:
43-
44-
```bash
45-
pre-commit install
46-
```
47-
48-
The hooks include:
49-
50-
- `ruff` for linting and code formatting
51-
- `prettier` for YAML, JSON, and Markdown formatting
52-
- `codespell` for spell checking
53-
- Security checks (AWS credentials, private keys)
54-
- Metadata validation
55-
56-
## Code Style and Linting
57-
58-
### Ruff Configuration
59-
60-
- **Line length**: 120 characters
61-
- **Formatter**: ruff format (follows Black-compatible style)
62-
- **Linter**: Enabled rules include:
63-
- E/W (pycodestyle errors and warnings)
64-
- F (pyflakes)
65-
- I (isort import sorting)
66-
- S (flake8-bandit security)
67-
- PT (flake8-pytest-style)
68-
- UP (pyupgrade syntax upgrader)
69-
70-
### Running Linters
71-
72-
```bash
73-
# Format code
74-
ruff format
75-
76-
# Check and fix linting issues
77-
ruff check --fix
78-
79-
# Run all pre-commit hooks
80-
pre-commit run --all-files
81-
```
82-
83-
## Testing
84-
85-
### Running Tests
86-
87-
```bash
88-
# Run all tests with coverage
89-
pytest --color=yes --cov --cov-report=xml
90-
91-
# Run specific test module
92-
pytest tests/unit/test_xtce/
93-
94-
# Run with verbose output
95-
pytest -v
96-
```
97-
98-
### Test Structure
99-
100-
- `tests/unit/` - Unit tests for individual components
101-
- `tests/integration/` - Integration tests for end-to-end scenarios
102-
- `tests/benchmark/` - Performance benchmarks
103-
- `conftest.py` - Shared test fixtures and configuration
104-
105-
### Test Conventions
106-
107-
- Use pytest fixtures defined in `conftest.py`
108-
- Test data is stored in `tests/test_data/`
109-
- Use pytest parametrize for testing multiple scenarios
110-
- Security checks (S-prefixed rules) are disabled in test files
111-
112-
## Project Structure
113-
114-
### Main Package: `space_packet_parser/`
115-
116-
- `__init__.py` - Public API exports (`load_xtce`, `ccsds_generator`, etc.)
117-
- `cli.py` - Command-line interface using Click
118-
- `common.py` - Common data structures (SpacePacket, etc.)
119-
- `definitions.py` - Core definitions and base classes
120-
- `exceptions.py` - Custom exception classes
121-
- `packets.py` - Packet parsing and handling logic
122-
- `xtce/` - XTCE parsing and validation
123-
- `definitions.py` - XTCE packet definitions
124-
- `validation.py` - XTCE schema validation
125-
- `generators/` - Binary data generators and readers
126-
- `xarr.py` - XArray integration (optional feature)
127-
128-
### Examples
129-
130-
Example usage scripts are in `examples/` directory.
131-
132-
### Documentation
133-
134-
- Built with Sphinx
135-
- Uses MyST Parser for Markdown support
136-
- Hosted on ReadTheDocs: https://space-packet-parser.readthedocs.io
137-
- Source files in `docs/source/`
138-
139-
## CLI Tool
140-
141-
The package provides a command-line tool:
142-
143-
```bash
144-
spp <command> [options]
145-
```
146-
147-
Entry point defined in `space_packet_parser.cli:spp`
148-
149-
## Making Changes
150-
151-
### Before Submitting a PR
152-
153-
1. Ensure all tests pass: `pytest`
154-
2. Run linters: `pre-commit run --all-files`
155-
3. Update tests for new functionality
156-
4. Update `docs/source/changelog.md` with your changes
157-
5. Ensure dependencies in `pyproject.toml` are current
158-
159-
### PR Checklist (from template)
160-
161-
- [ ] Changes are fully implemented without dangling issues or TODO items
162-
- [ ] Deprecated/superseded code is removed or marked with deprecation warning
163-
- [ ] Current dependencies have been properly specified and old dependencies removed
164-
- [ ] New code/functionality has accompanying tests and any old tests have been updated
165-
- [ ] The changelog.md has been updated
166-
167-
## Code Review
168-
169-
- Code changes will be reviewed by @medley56 (see CODEOWNERS)
170-
- Follow the project's Code of Conduct
171-
172-
## CI/CD
173-
174-
### GitHub Actions Workflows
175-
176-
- `tests.yml` - Runs tests on Windows, Ubuntu, and macOS across Python 3.9-3.13
177-
- `test_examples.yml` - Validates example scripts
178-
- `release.yml` - Handles package releases
179-
180-
### Coverage
181-
182-
- Code coverage reports are uploaded to Codecov
183-
- Target: Maintain high test coverage for critical components
184-
185-
## Common Tasks
186-
187-
### Adding a New Parameter Type
188-
189-
1. Define the parameter type class in `space_packet_parser/xtce/`
190-
2. Add parsing logic to handle the XTCE element
191-
3. Add unit tests in `tests/unit/test_xtce/test_parameters.py`
192-
4. Add integration test with a real XTCE file if applicable
193-
5. Update documentation
194-
195-
### Adding a New CLI Command
196-
197-
1. Add command function to `space_packet_parser/cli.py`
198-
2. Use Click decorators for arguments/options
199-
3. Use Rich for formatted terminal output
200-
4. Add tests in `tests/unit/test_cli/` (if test directory exists)
201-
202-
### Updating XTCE Validation
203-
204-
1. Modify validation logic in `space_packet_parser/xtce/validation.py`
205-
2. Update schema files if needed
206-
3. Add test cases for the validation scenario
207-
4. Ensure backward compatibility with existing XTCE files
208-
209-
## Important Notes
210-
211-
- The library focuses on **telemetry parsing only** (not command generation)
212-
- Binary data parsing is performance-critical - consider efficiency
213-
- XTCE files can be very large - optimize for memory efficiency
214-
- Support for edge cases in XTCE spec is important for mission use
215-
- This is production code used by real space missions (IMAP, CLARREO, Libera, CTIM-FD, MMS)
216-
217-
## Resources
218-
219-
- [XTCE Green Book (Informational Report)](https://public.ccsds.org/Pubs/660x2g2.pdf)
220-
- [XTCE Element Description (Green Book)](https://public.ccsds.org/Pubs/660x1g2.pdf)
221-
- [XTCE Blue Book (Recommended Standard)](https://public.ccsds.org/Pubs/660x0b2.pdf)
222-
- [Project Documentation](https://space-packet-parser.readthedocs.io)
223-
- [PyHC (Python in Heliophysics Community)](https://heliopython.org)
3+
This is the Space Packet Parser repository. Detailed instructions for coding rules, patterns, and testing are in
4+
[`instructions/space_packet_parser.instructions.md`](instructions/space_packet_parser.instructions.md).
5+
Please refer to that file for the most up-to-date and comprehensive guidelines on contributing to this project.

0 commit comments

Comments
 (0)