Skip to content
Merged
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
67 changes: 67 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
name: Release

on:
push:
tags:
- "v*.*.*"

permissions:
contents: write

jobs:
test:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[low] workflow-duplication

The release workflow's test job duplicates the exact same steps as ci.yaml. If test commands change, both workflows must be updated independently.

Suggested fix: Consider creating a reusable workflow that both ci.yaml and release.yml call, or rely on branch protection requiring CI to pass before tagging.

runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6
- run: uv python install 3.12
- run: uv sync --extra dev
- run: uv run ruff check src/ tests/
- run: uv run ruff format --check src/ tests/
- run: uv run pytest -v --cov=src --cov-report=term-missing --cov-fail-under=60

release:
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Extract version from tag
id: version
run: echo "tag=${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT"

- name: Extract changelog section
id: changelog
env:
TAG: ${{ steps.version.outputs.tag }}
run: |
version="${TAG#v}"
# Escape dots for awk regex
escaped=$(echo "$version" | sed 's/\./\\./g')
# Extract the section for this version from CHANGELOG.md
section=$(awk "/^## \[${escaped}\]/{found=1; next} /^## \[/{if(found) exit} found{print}" CHANGELOG.md)
if [ -z "$section" ]; then

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[low] regex-correctness

The awk command interpolates the version string into a regex without escaping dots (. matches any character in awk regex). Unlikely to cause problems with standard semver headings, but technically incorrect.

section="Release ${version}"
fi
# Use a delimiter for multiline output
echo "body<<CHANGELOG_EOF" >> "$GITHUB_OUTPUT"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[low] edge-case

The static heredoc delimiter CHANGELOG_EOF used for multiline GITHUB_OUTPUT could be prematurely terminated if CHANGELOG.md contains a line that is exactly CHANGELOG_EOF. While CHANGELOG.md is maintainer-controlled content (limiting risk), GitHub's recommended practice is to use a random delimiter for multiline outputs.

Suggested fix: Use a dynamic delimiter: delimiter=$(uuidgen) or delimiter=$(openssl rand -hex 16).

echo "$section" >> "$GITHUB_OUTPUT"
echo "CHANGELOG_EOF" >> "$GITHUB_OUTPUT"

- name: Create GitHub Release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG: ${{ steps.version.outputs.tag }}
NOTES: ${{ steps.changelog.outputs.body }}
run: |

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[medium] GitHub Actions script injection

The gh release create step interpolates steps.version.outputs.tag directly into shell arguments via ${{ }} expression syntax (lines 51-52 and 57). The Actions runner expands ${{ }} before bash parses the command, so a tag containing shell metacharacters would be interpreted as code. While only users with push access can create tags, defense-in-depth requires passing values through environment variables. The same pattern appears in the Update major version tag step (line 57).

Suggested fix: Use env: TAG: ${{ steps.version.outputs.tag }} and reference as "$TAG" in the run script. Apply the same pattern to all steps that interpolate step outputs.

gh release create "$TAG" \
--title "$TAG" \
--notes "$NOTES"

- name: Update major version tag
env:
TAG: ${{ steps.version.outputs.tag }}
run: |
major=$(echo "$TAG" | grep -oP '^v\d+')
git tag -f "$major"
git push -f origin "$major"
28 changes: 28 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# 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.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [0.1.0] - 2026-08-16

Initial tagged release. The action has been in use since September 2025;
this release captures the current feature set for stable pinning.

### Added

- AI-powered documentation review and update via PR comments
(`[review-docs]`, `[update-docs]`)
- Spec-vs-code gap analysis via Jira integration (`[review-feature]`)
- Support for Markdown, AsciiDoc, and reStructuredText doc formats
- Same-repo and separate-docs-repo configurations
- Semantic folder indexes for faster file discovery
- Persistent style guidelines via `.code-to-docs/style.md`
- Repository configuration via `.code-to-docs/config.json`
- Interactive review with checkboxes for accepting/rejecting file suggestions
- Fork PR detection with suggested-changes fallback
- Per-file and global reviewer instructions in `[update-docs]` comments
- CI pipeline with ruff linting, formatting, and 60% coverage threshold
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ jobs:
"AUTHORIZATION: basic $(echo -n "x-access-token:${GH_TOKEN}" | base64 -w 0)"

- name: Documentation Assistant
uses: redhat-community-ai-tools/code-to-docs@main
uses: redhat-community-ai-tools/code-to-docs@v0
with:
model-api-base: ${{ secrets.MODEL_API_BASE }}
model-api-key: ${{ secrets.MODEL_API_KEY }}
Expand Down Expand Up @@ -198,6 +198,12 @@ These are set as `with:` parameters in the workflow step (not as secrets):
|-------|-------------|
| `style-config-path` | _(Optional)_ Path to a Markdown style configuration file (`.md`) containing documentation style guidelines. If not set, auto-detects `.code-to-docs/style.md`. |

### Versioning

- `@v0` receives all backward-compatible updates (recommended)
- `@v0.1.0` pins to an exact release
- `@main` tracks unreleased changes and is not stable

### Supported Model Backends

Any OpenAI-compatible API works. Common examples:
Expand Down
82 changes: 39 additions & 43 deletions RELEASING.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,66 +2,62 @@

This document explains how to release new versions of the code-to-docs action.

## Releasing a New Version

When you're ready to release a new version (e.g., v1.2.0):

### 1. Create and push the specific version tag
## How It Works

```bash
git tag v1.2.0
git push origin v1.2.0
```
Pushing a semver tag triggers `.github/workflows/release.yaml`, which:

### 2. Move the major version tag
1. Runs the full test suite (lint, format, tests with coverage)
2. Extracts the release notes from `CHANGELOG.md`
3. Creates a GitHub Release
4. Force-updates the moving major tag (e.g. `v0` points to `v0.1.0`)

This ensures users using `@v1` get the latest v1.x.x version:
## Releasing a New Version

```bash
git tag -f v1 # Move v1 tag to point to v1.2.0
git push -f origin v1 # Force push the moved tag
```
### 1. Update CHANGELOG.md

### 3. Update the README (if needed)
Move items from `[Unreleased]` into a new version section:

If the example in README.md references a specific version, consider whether it needs updating.
```markdown
## [0.2.0] - 2026-09-01

## Version Numbering
### Added
- New feature description
```

Follow semantic versioning (MAJOR.MINOR.PATCH):
### 2. Bump the version in pyproject.toml

- **MAJOR** (v2.0.0): Breaking changes
- **MINOR** (v1.2.0): New features, backward compatible
- **PATCH** (v1.1.1): Bug fixes, backward compatible
```toml
version = "0.2.0"
```

## Complete Example
### 3. Commit, tag, and push

```bash
# Release v1.2.0
git tag v1.2.0
git push origin v1.2.0
git add CHANGELOG.md pyproject.toml
git commit -m "chore(release): prepare v0.2.0"
git tag v0.2.0
git push origin main --tags
```

# Move v1 to v1.2.0
git tag -f v1
git push -f origin v1
The release workflow handles the rest: it creates the GitHub Release and
moves the `v0` tag.

echo "✅ Released v1.2.0 and updated v1 tag"
```
## Version Numbering

## Verification
Follow semantic versioning (MAJOR.MINOR.PATCH):

After releasing, verify users can access it:
- **MAJOR** (v1.0.0): Breaking changes to action inputs, outputs, or behavior
- **MINOR** (v0.2.0): New features, backward compatible
- **PATCH** (v0.1.1): Bug fixes, backward compatible

```bash
# Check tags
git ls-remote --tags origin | grep v1
## What Users Pin To

# Should see both:
# refs/tags/v1.2.0
# refs/tags/v1
```
- `@v0` receives all compatible updates (recommended)
- `@v0.1.0` is pinned to an exact release
- `@main` tracks unreleased changes (unstable, not recommended)

Users can now use:
- `redhat-community-ai-tools/code-to-docs@v1` (gets v1.2.0)
- `redhat-community-ai-tools/code-to-docs@v1.2.0` (pinned to v1.2.0)
## Marketplace

After the GitHub Release is created, visit the Release page and click
"Publish this Action to the GitHub Marketplace" if the listing is not yet
automatic. This is a manual step in the GitHub UI.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "code-to-docs"
version = "0.0.0"
version = "0.1.0"
description = "GitHub Action that generates documentation suggestions from code changes using LLMs"
requires-python = ">=3.12"
license = {text = "MIT"}
Expand Down
Loading