Create Release #18
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Create Release | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| tag: | |
| description: 'Git tag to release (e.g., v1.2.3)' | |
| required: true | |
| type: string | |
| jobs: | |
| verify-and-release: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
| with: | |
| fetch-depth: 0 | |
| fetch-tags: true | |
| persist-credentials: false | |
| - name: Validate tag format | |
| run: | | |
| TAG="${GITHUB_EVENT_INPUTS_TAG}" | |
| if [[ ! $TAG =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then | |
| echo "❌ Invalid tag format. Expected format: v1.2.3" | |
| exit 1 | |
| fi | |
| echo "✅ Tag format is valid: $TAG" | |
| env: | |
| GITHUB_EVENT_INPUTS_TAG: ${{ github.event.inputs.tag }} | |
| - name: Verify tag exists | |
| run: | | |
| TAG="${GITHUB_EVENT_INPUTS_TAG}" | |
| if ! git rev-parse --verify "refs/tags/$TAG" >/dev/null 2>&1; then | |
| echo "❌ Tag '$TAG' does not exist in the repository" | |
| echo "Available tags:" | |
| git tag --sort=-version:refname | head -10 | |
| exit 1 | |
| fi | |
| echo "✅ Tag '$TAG' exists" | |
| env: | |
| GITHUB_EVENT_INPUTS_TAG: ${{ github.event.inputs.tag }} | |
| - name: Checkout specific tag | |
| run: | | |
| git checkout ${GITHUB_EVENT_INPUTS_TAG} | |
| env: | |
| GITHUB_EVENT_INPUTS_TAG: ${{ github.event.inputs.tag }} | |
| - name: Verify GPG signature on tag | |
| run: | | |
| TAG="${GITHUB_EVENT_INPUTS_TAG}" | |
| # Force fetch the complete tag object (not just commit reference) | |
| echo "=== Fetching Tag Object ===" | |
| git fetch origin tag $TAG --force | |
| # Debug: Show what type of object we have | |
| echo "=== Tag Object Debug ===" | |
| git cat-file -t $TAG | |
| echo "Tag points to commit: $(git rev-parse $TAG^{})" | |
| echo "Tag object hash: $(git rev-parse $TAG)" | |
| echo "=== End Tag Debug ===" | |
| # Import public key for verification | |
| echo "=== Importing GPG Key ===" | |
| echo '${{ secrets.GPG_PUBLIC_KEY }}' > /tmp/pubkey.asc | |
| head -3 /tmp/pubkey.asc | |
| gpg --import /tmp/pubkey.asc | |
| echo "=== GPG Key Imported ===" | |
| # Verify the tag is properly signed | |
| echo "=== Verifying Tag Signature ===" | |
| git tag -v $TAG | |
| echo "✅ Tag signature verified" | |
| # Cleanup | |
| rm /tmp/pubkey.asc | |
| env: | |
| GITHUB_EVENT_INPUTS_TAG: ${{ github.event.inputs.tag }} | |
| - name: Get version from tag | |
| id: get_version | |
| run: | | |
| TAG="${GITHUB_EVENT_INPUTS_TAG}" | |
| VERSION=${TAG#v} | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| echo "tag=$TAG" >> $GITHUB_OUTPUT | |
| env: | |
| GITHUB_EVENT_INPUTS_TAG: ${{ github.event.inputs.tag }} | |
| - name: Package repository | |
| run: | | |
| mkdir -p dist | |
| # Create source package | |
| zip -r dist/fractum-${STEPS_GET_VERSION_OUTPUTS_VERSION}-source.zip \ | |
| src/ \ | |
| packages/ \ | |
| tests/ \ | |
| bootstrap-*.sh \ | |
| bootstrap-*.ps1 \ | |
| Dockerfile \ | |
| .dockerignore \ | |
| assets \ | |
| setup.py \ | |
| README.md \ | |
| LICENSE \ | |
| --exclude="*.pyc" \ | |
| --exclude="__pycache__/*" \ | |
| --exclude="*.DS_Store" \ | |
| --exclude=".git/*" | |
| # Create checksums | |
| cd dist | |
| sha256sum fractum-${STEPS_GET_VERSION_OUTPUTS_VERSION}-source.zip > checksums.txt | |
| env: | |
| STEPS_GET_VERSION_OUTPUTS_VERSION: ${{ steps.get_version.outputs.version }} | |
| - name: Extract release notes from tag | |
| id: release_notes | |
| run: | | |
| TAG="${GITHUB_EVENT_INPUTS_TAG}" | |
| # Extract release notes from signed tag message | |
| NOTES=$(git tag -l --format='%(contents)' $TAG) | |
| echo "notes<<EOF" >> $GITHUB_OUTPUT | |
| echo "$NOTES" >> $GITHUB_OUTPUT | |
| echo "EOF" >> $GITHUB_OUTPUT | |
| env: | |
| GITHUB_EVENT_INPUTS_TAG: ${{ github.event.inputs.tag }} | |
| - name: Create GitHub Release | |
| uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631 # v2.2.2 | |
| with: | |
| tag_name: ${{ steps.get_version.outputs.tag }} | |
| name: Fractum ${{ steps.get_version.outputs.tag }} | |
| body: | | |
| ## 🔐 Security Verification | |
| **GPG Signature:** ✅ This release is cryptographically signed | |
| **Key ID:** D009F6290DCFDAB6 | |
| **Signed by:** S.A.S.U. KATVIO (Fractum Release Signing) | |
| ### Verify Release Authenticity | |
| ```bash | |
| # Import KATVIO public key | |
| curl -O https://fractum.katvio.com/fractum-signing-key.asc | |
| gpg --import fractum-signing-key.asc | |
| # Verify tag signature | |
| git tag -v ${{ steps.get_version.outputs.tag }} | |
| # Verify package checksum | |
| sha256sum -c checksums.txt | |
| ``` | |
| ## 📋 Release Notes | |
| ${{ steps.release_notes.outputs.notes }} | |
| ## 📦 Download Options | |
| - **Source Code:** Use git clone or download ZIP | |
| - **Verification:** Always verify GPG signatures before use | |
| files: | | |
| dist/* | |
| draft: false | |
| prerelease: false | |
| make_latest: true | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Update website release info | |
| run: | | |
| echo "🚀 Released Fractum ${STEPS_GET_VERSION_OUTPUTS_VERSION}" | |
| echo "Tag: ${STEPS_GET_VERSION_OUTPUTS_TAG}" | |
| echo "Signature verified: ✅" | |
| env: | |
| STEPS_GET_VERSION_OUTPUTS_VERSION: ${{ steps.get_version.outputs.version }} | |
| STEPS_GET_VERSION_OUTPUTS_TAG: ${{ steps.get_version.outputs.tag }} |