Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
159 changes: 159 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
name: Release

on:
workflow_dispatch:
inputs:
version:
description: 'Version to release (e.g., 1.0.1)'
required: true
type: string
release_type:
description: 'Release type'
required: true
type: choice
options:
- patch
- minor
- major

permissions:
contents: write

jobs:
release:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install toml

- name: Validate version format
run: |
if ! echo "${{ inputs.version }}" | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$'; then
echo "Error: Version must be in format X.Y.Z"
exit 1
fi

- name: Check if tag already exists
run: |
if git rev-parse "v${{ inputs.version }}" >/dev/null 2>&1; then
echo "Error: Tag v${{ inputs.version }} already exists"
exit 1
fi

- name: Wait for tests to complete
uses: lewagon/[email protected]
with:
ref: ${{ github.sha }}
check-name: 'Test template generation'
repo-token: ${{ secrets.GITHUB_TOKEN }}
wait-interval: 10

- name: Update version in pyproject.toml
run: |
python -c "
import toml
import sys

# Read the current pyproject.toml
with open('pyproject.toml', 'r') as f:
data = toml.load(f)

# Update the version
data['project']['version'] = '${{ inputs.version }}'

# Write back
with open('pyproject.toml', 'w') as f:
toml.dump(data, f)
"

- name: Update version in cookiecutter.json
run: |
python -c "
import json

# Read cookiecutter.json
with open('cookiecutter.json', 'r') as f:
data = json.load(f)

# Add version field if it doesn't exist
data['_template_version'] = '${{ inputs.version }}'

# Write back with proper formatting
with open('cookiecutter.json', 'w') as f:
json.dump(data, f, indent=4)
f.write('\n')
"

- name: Commit version updates
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add pyproject.toml cookiecutter.json
git commit -m "chore: bump version to ${{ inputs.version }}"
git push origin main

- name: Create and push tag
run: |
git tag -a "v${{ inputs.version }}" -m "Release v${{ inputs.version }}"
git push origin "v${{ inputs.version }}"

- name: Generate release notes
id: release_notes
run: |
# Get the previous tag
PREV_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")

if [ -z "$PREV_TAG" ]; then
echo "No previous tag found, this is the first release"
COMPARE_FROM=$(git rev-list --max-parents=0 HEAD)
else
COMPARE_FROM=$PREV_TAG
fi

# Generate commit list
echo "commits<<EOF" >> $GITHUB_OUTPUT
git log --pretty=format:"- %s (%h)" $COMPARE_FROM..HEAD >> $GITHUB_OUTPUT
echo "" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT

- name: Create Release
uses: softprops/action-gh-release@v2
with:
tag_name: v${{ inputs.version }}
name: Release v${{ inputs.version }}
draft: false
prerelease: false
generate_release_notes: true
body: |
## 🎉 Release v${{ inputs.version }}

**Release type**: ${{ inputs.release_type }}

### For Users of This Template

To update your existing protocol generated from this template:
```bash
cruft update
```

Or to create a new protocol:
```bash
cookiecutter gh:ReproNim/reproschema-protocol-cookiecutter
```

### What's Changed

Auto-generated release notes are below.
41 changes: 41 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added
- GitHub Pages deployment workflow for generated protocols
- Comprehensive testing infrastructure with CI/CD
- Improved error handling in post-generation hooks
- Support for deploying specific versions/commits to GitHub Pages

### Changed
- Updated all schemas to use stable ReproSchema version 1.0.0
- Standardized schema filenames to lowercase convention
- Fixed context paths from `/contexts/generic` to `/contexts/reproschema`

### Fixed
- Schema version inconsistencies
- Hardcoded activity references in protocol template
- Path mismatches in generated schemas

## [1.0.0] - 2024-06-12

### Added
- Initial release of reproschema-protocol-cookiecutter
- Support for generating ReproSchema protocols
- Customizable number of activities (1-5)
- Pre-configured activity types:
- Basic activities with various input types
- Voice recording activities
- Selection activities
- Integration with reproschema-ui
- Cruft support for template updates
- Basic documentation and examples

[Unreleased]: https://github.com/ReproNim/reproschema-protocol-cookiecutter/compare/v1.0.0...HEAD
[1.0.0]: https://github.com/ReproNim/reproschema-protocol-cookiecutter/releases/tag/v1.0.0
149 changes: 149 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
# Contributing to reproschema-protocol-cookiecutter

Thank you for your interest in contributing to the ReproSchema Protocol Cookiecutter! This document provides guidelines and instructions for contributing.

## Getting Started

1. Fork the repository
2. Clone your fork: `git clone https://github.com/YOUR-USERNAME/reproschema-protocol-cookiecutter.git`
3. Create a new branch: `git checkout -b feature/your-feature-name`
4. Make your changes
5. Test your changes (see Testing section)
6. Commit your changes using conventional commits
7. Push to your fork and submit a pull request

## Development Setup

### Prerequisites

- Python 3.8+
- Node.js 20+ (for testing GitHub Pages deployment)
- Git

### Installing Dependencies

```bash
pip install -r requirements.txt
```

### Pre-commit Hooks

We use pre-commit hooks to ensure code quality:

```bash
pre-commit install
```

## Testing

### Running Tests Locally

```bash
# Test the cookiecutter template generation
python test_cookiecutter.py

# Or use the micromamba environment
./run_in_env.sh python test_cookiecutter.py
```

### Testing Your Changes

1. Generate a test protocol:
```bash
cookiecutter . --no-input -o test-output
```

2. Validate the generated schemas:
```bash
cd test-output/my-reproschema-protocol
reproschema validate my_reproschema_protocol/my_reproschema_protocol_schema
```

## Code Style

- Python code follows PEP 8
- Use meaningful variable and function names
- Add docstrings to functions
- Keep functions focused and small

## Commit Messages

We follow the [Conventional Commits](https://www.conventionalcommits.org/) specification:

- `feat:` New features
- `fix:` Bug fixes
- `docs:` Documentation changes
- `chore:` Maintenance tasks
- `test:` Test additions or modifications

Example:
```
feat: add support for custom activity types

- Allow users to define custom activity schemas
- Update documentation with examples
- Add tests for custom activities
```

## Pull Request Process

1. Ensure all tests pass
2. Update documentation if needed
3. Update CHANGELOG.md with your changes under "Unreleased"
4. Fill out the PR template completely
5. Request review from maintainers

## Release Process

Releases are managed by maintainers using the GitHub Actions release workflow:

### Creating a Release

1. Go to Actions → Release workflow
2. Click "Run workflow"
3. Enter the new version (e.g., 1.0.1)
4. Select release type (patch/minor/major)
5. The workflow will:
- Update version in pyproject.toml and cookiecutter.json
- Create a git tag
- Generate release notes
- Create a GitHub release

### Version Guidelines

- **Major** (X.0.0): Breaking changes to template structure or output
- **Minor** (1.X.0): New features, activities, or capabilities
- **Patch** (1.0.X): Bug fixes, documentation updates

### Post-Release

After a release, update CHANGELOG.md:
1. Move items from "Unreleased" to the new version section
2. Add comparison link at the bottom

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The manual post-release step for updating CHANGELOG.md is well-documented, but it's a manual process that can be error-prone. If this step is forgotten, the changelog can become out of sync with the project's releases.

Since the project has adopted Conventional Commits, I recommend automating this step. You could integrate a tool like release-drafter or git-cliff into the release workflow. This would allow you to:

  • Automatically generate changelog entries from commits.
  • Update CHANGELOG.md with the new version's changes.
  • Prepare the Unreleased section for the next development cycle.

Automating this would make the release process more robust and reduce the manual burden on maintainers.


## Schema Updates

When updating ReproSchema versions or structures:

1. Use `update_schema_version.py` to update all schemas consistently
2. Test that all schemas validate with the new version
3. Update documentation to reflect changes

## Adding New Activities

To add a new activity type:

1. Create the activity folder in `{{cookiecutter.protocol_name}}/activities/`
2. Add the activity schema and item schemas
3. Update `hooks/pre_gen_project.py` to include the new activity option
4. Add tests for the new activity
5. Update documentation

## Questions?

Feel free to:
- Open an issue for bugs or feature requests
- Start a discussion for questions
- Join the ReproNim community channels

Thank you for contributing!