Files
freecad-robust-mcp-fc111/.github/workflows/macro-release-reusable.yaml
T
Sean P. KaneandGitHub 62f6f4dbcf fix: improve release note process (#36)
* fix: improve release note process

* docs: improve release notes

* fix: correct repo name/dir

* fix: CVE resolution for jaraco.context

* fix: docker build with uv.lovl

* fix: CVE remediations

* fix: update docker workflow

* fix: remove setuptools from base image
2026-01-16 13:51:08 -08:00

313 lines
11 KiB
YAML

name: Macro Release (Reusable)
# Reusable workflow for releasing individual FreeCAD macros
# Called by component-specific workflows with appropriate inputs
on:
workflow_dispatch:
inputs:
tag_prefix:
description: 'Tag prefix to match (e.g., macro-cut-object-for-magnets-v)'
required: true
type: string
macro_dir:
description: 'Macro directory relative to macros/ (e.g., Cut_Object_for_Magnets)'
required: true
type: string
macro_file:
description: 'Main macro filename (e.g., CutObjectForMagnets.FCMacro)'
required: true
type: string
macro_name:
description: 'Human-readable macro name (e.g., Cut Object for Magnets)'
required: true
type: string
archive_name:
description: 'Archive base name (e.g., CutObjectForMagnets)'
required: true
type: string
readme_file:
description: 'README filename (e.g., README-CutObjectForMagnets.md)'
required: true
type: string
wiki_url:
description: 'FreeCAD Wiki URL for this macro'
required: false
type: string
default: ''
description:
description: 'Short description for release notes'
required: true
type: string
workflow_call:
inputs:
tag_prefix:
description: 'Tag prefix to match (e.g., macro-cut-object-for-magnets-v)'
required: true
type: string
macro_dir:
description: 'Macro directory relative to macros/ (e.g., Cut_Object_for_Magnets)'
required: true
type: string
macro_file:
description: 'Main macro filename (e.g., CutObjectForMagnets.FCMacro)'
required: true
type: string
macro_name:
description: 'Human-readable macro name (e.g., Cut Object for Magnets)'
required: true
type: string
archive_name:
description: 'Archive base name (e.g., CutObjectForMagnets)'
required: true
type: string
readme_file:
description: 'README filename (e.g., README-CutObjectForMagnets.md)'
required: true
type: string
wiki_url:
description: 'FreeCAD Wiki URL for this macro'
required: false
type: string
default: ''
description:
description: 'Short description for release notes'
required: true
type: string
jobs:
validate-and-release:
name: Validate Tag and Create Release
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Validate semantic version tag
id: version
env:
TAG_PREFIX: ${{ inputs.tag_prefix }}
run: |
TAG="${GITHUB_REF#refs/tags/}"
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
# Build regex pattern from tag prefix
PATTERN="^${TAG_PREFIX}([0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.]+)?)\$"
if [[ ! "$TAG" =~ $PATTERN ]]; then
echo "ERROR: Tag '$TAG' does not match expected format (${TAG_PREFIX}X.Y.Z)"
exit 1
fi
VERSION="${BASH_REMATCH[1]}"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
# Check if this is a prerelease
if [[ "$VERSION" =~ -[a-zA-Z0-9.]+ ]]; then
echo "is_prerelease=true" >> "$GITHUB_OUTPUT"
else
echo "is_prerelease=false" >> "$GITHUB_OUTPUT"
fi
echo "Parsed version: $VERSION"
- name: Verify macro version in files
env:
VERSION: ${{ steps.version.outputs.version }}
MACRO_DIR: ${{ inputs.macro_dir }}
MACRO_FILE: ${{ inputs.macro_file }}
MACRO_NAME: ${{ inputs.macro_name }}
run: |
MACRO_PATH="macros/${MACRO_DIR}/${MACRO_FILE}"
echo "Verifying version in source files matches tag: $VERSION"
# Check __Version__ in .FCMacro file
if [ -f "$MACRO_PATH" ]; then
MACRO_VERSION=$(grep -o '__Version__ = "[^"]*"' "$MACRO_PATH" | cut -d'"' -f2)
if [ "$MACRO_VERSION" != "$VERSION" ]; then
echo "ERROR: Version mismatch in $MACRO_PATH"
echo " Expected: $VERSION"
echo " Found: $MACRO_VERSION"
echo ""
echo "The version in source files must be updated before tagging."
echo "Run the appropriate bump command first."
exit 1
fi
echo "✓ $MACRO_PATH: $MACRO_VERSION"
else
echo "ERROR: Macro file not found: $MACRO_PATH"
exit 1
fi
# Check wiki-source.txt
WIKI_FILE="macros/${MACRO_DIR}/wiki-source.txt"
if [ -f "$WIKI_FILE" ]; then
WIKI_VERSION=$(grep -o '|Version=[^|]*' "$WIKI_FILE" | cut -d= -f2 | tr -d '\n')
if [ "$WIKI_VERSION" != "$VERSION" ]; then
echo "ERROR: Version mismatch in $WIKI_FILE"
echo " Expected: $VERSION"
echo " Found: $WIKI_VERSION"
echo ""
echo "Run the appropriate bump command first."
exit 1
fi
echo "✓ $WIKI_FILE: $WIKI_VERSION"
fi
# Check package.xml
PKG_VERSION=$(awk -v name="$MACRO_NAME" '
/<macro>/ { in_macro=1 }
/<\/macro>/ { in_macro=0; found_name=0 }
in_macro && index($0, name) > 0 { found_name=1 }
in_macro && found_name && /<version>/ {
gsub(/.*<version>/, ""); gsub(/<\/version>.*/, ""); print; exit
}
' package.xml)
if [ "$PKG_VERSION" != "$VERSION" ]; then
echo "ERROR: Version mismatch in package.xml ($MACRO_NAME section)"
echo " Expected: $VERSION"
echo " Found: $PKG_VERSION"
exit 1
fi
echo "✓ package.xml ($MACRO_NAME): $PKG_VERSION"
echo ""
echo "Version verification passed!"
- name: Create macro archive
env:
VERSION: ${{ steps.version.outputs.version }}
MACRO_DIR: ${{ inputs.macro_dir }}
MACRO_FILE: ${{ inputs.macro_file }}
ARCHIVE_NAME: ${{ inputs.archive_name }}
README_FILE: ${{ inputs.readme_file }}
run: |
# Create staging directory
mkdir -p "staging/${ARCHIVE_NAME}-${VERSION}"
# Copy macro files
cp "macros/${MACRO_DIR}/${MACRO_FILE}" "staging/${ARCHIVE_NAME}-${VERSION}/"
# Copy icon if exists
for ext in svg png; do
ICON_FILE="macros/${MACRO_DIR}/${ARCHIVE_NAME}.${ext}"
if [ -f "$ICON_FILE" ]; then
cp "$ICON_FILE" "staging/${ARCHIVE_NAME}-${VERSION}/"
fi
done
# Copy README
if [ -f "macros/${MACRO_DIR}/${README_FILE}" ]; then
cp "macros/${MACRO_DIR}/${README_FILE}" "staging/${ARCHIVE_NAME}-${VERSION}/README.md"
fi
# Copy LICENSE
cp LICENSE "staging/${ARCHIVE_NAME}-${VERSION}/"
# Create tar.gz archive
cd staging
tar -czvf "${ARCHIVE_NAME}-${VERSION}.tar.gz" "${ARCHIVE_NAME}-${VERSION}"
# Create zip archive
zip -r "${ARCHIVE_NAME}-${VERSION}.zip" "${ARCHIVE_NAME}-${VERSION}"
mv "${ARCHIVE_NAME}-${VERSION}.tar.gz" ../
mv "${ARCHIVE_NAME}-${VERSION}.zip" ../
cd ..
echo "Created archives:"
ls -la "${ARCHIVE_NAME}-${VERSION}."*
- name: Extract release notes section
id: changelog
env:
VERSION: ${{ steps.version.outputs.version }}
MACRO_NAME: ${{ inputs.macro_name }}
DESCRIPTION: ${{ inputs.description }}
MACRO_FILE: ${{ inputs.macro_file }}
MACRO_DIR: ${{ inputs.macro_dir }}
README_FILE: ${{ inputs.readme_file }}
WIKI_URL: ${{ inputs.wiki_url }}
run: |
RELEASE_NOTES="macros/${MACRO_DIR}/RELEASE_NOTES.md"
# Extract section for this version from RELEASE_NOTES.md
# Format: ## Version X.Y.Z (date)
CHANGELOG_CONTENT=$(awk -v version="$VERSION" '
BEGIN { found=0 }
/^## Version / {
if (found) exit
if (index($0, version) > 0) { found=1; next }
}
found { print }
' "$RELEASE_NOTES" 2>/dev/null || echo "")
# Build release body
cat > release_body.md << EOF
## ${MACRO_NAME} Macro v${VERSION}
${DESCRIPTION}
### Installation
Copy \`${MACRO_FILE}\` to your FreeCAD macro directory:
- **macOS**: \`~/Library/Application Support/FreeCAD/Macro/\`
- **Linux**: \`~/.local/share/FreeCAD/Macro/\`
- **Windows**: \`%APPDATA%/FreeCAD/Macro/\`
Optionally copy the icon file (\`.svg\` or \`.png\`) to the same location.
### Documentation
- [Full README](https://github.com/spkane/freecad-robust-mcp-and-more/blob/main/macros/${MACRO_DIR}/${README_FILE})
EOF
if [ -n "$WIKI_URL" ]; then
echo "- [FreeCAD Wiki Page](${WIKI_URL})" >> release_body.md
fi
if [ -n "$CHANGELOG_CONTENT" ]; then
{
echo ""
echo "### Changelog"
echo ""
echo "$CHANGELOG_CONTENT"
} >> release_body.md
fi
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
name: "${{ inputs.macro_name }} Macro v${{ steps.version.outputs.version }}"
tag_name: ${{ github.ref_name }}
prerelease: ${{ steps.version.outputs.is_prerelease == 'true' }}
generate_release_notes: true
body_path: release_body.md
files: |
${{ inputs.archive_name }}-${{ steps.version.outputs.version }}.tar.gz
${{ inputs.archive_name }}-${{ steps.version.outputs.version }}.zip
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Generate summary
env:
VERSION: ${{ steps.version.outputs.version }}
MACRO_NAME: ${{ inputs.macro_name }}
ARCHIVE_NAME: ${{ inputs.archive_name }}
run: |
{
echo "## ${MACRO_NAME} Macro Release"
echo ""
echo "**Version:** ${VERSION}"
echo ""
echo "### Downloads"
echo ""
echo "- \`${ARCHIVE_NAME}-${VERSION}.tar.gz\`"
echo "- \`${ARCHIVE_NAME}-${VERSION}.zip\`"
} >> "$GITHUB_STEP_SUMMARY"