@@ -636,22 +636,60 @@ publish-test venv="":
636636 ${VENV_PYTHON} -m twine upload --repository testpypi dist/*
637637 echo " --> Published to Test PyPI"
638638
639- # Download GitHub release artifacts (nightly or tagged release)
640- download-github-release release_type = " nightly":
639+ # Download GitHub release artifacts to /tmp/release-artifacts/<tag> with checksum verification
640+ download-github-release tag = " nightly":
641641 #!/usr/bin/env bash
642642 set -e
643- echo " ==> Downloading GitHub release artifacts ({{release_type}})..."
644- rm -rf ./dist
645- mkdir -p ./dist
646- if [ " {{release_type}}" = " nightly" ]; then
647- gh release download nightly --repo crossbario/cfxdb --dir ./dist --pattern ' *.whl' --pattern ' *.tar.gz' || \
643+
644+ TAG=" {{ tag }}"
645+ DOWNLOAD_DIR=" /tmp/release-artifacts/${TAG} "
646+
647+ echo " ==> Downloading GitHub release artifacts for ${TAG} ..."
648+ echo " Target directory: ${DOWNLOAD_DIR} "
649+
650+ # Check gh CLI is authenticated
651+ if ! gh auth status & > /dev/null; then
652+ echo " ❌ Error: gh CLI is not authenticated"
653+ echo " Run: gh auth login"
654+ exit 1
655+ fi
656+
657+ # Create fresh download directory
658+ rm -rf " ${DOWNLOAD_DIR} "
659+ mkdir -p " ${DOWNLOAD_DIR} "
660+
661+ # Download artifacts
662+ if [ " ${TAG} " = " nightly" ]; then
663+ gh release download nightly --repo crossbario/cfxdb --dir " ${DOWNLOAD_DIR} " \
664+ --pattern ' *.whl' --pattern ' *.tar.gz' --pattern ' CHECKSUMS.sha256' 2> /dev/null || \
648665 echo " Note: No nightly release found or no artifacts available"
649666 else
650- gh release download " {{release_type}}" --repo crossbario/cfxdb --dir ./dist --pattern ' *.whl' --pattern ' *.tar.gz'
667+ gh release download " ${TAG} " --repo crossbario/cfxdb --dir " ${DOWNLOAD_DIR} " \
668+ --pattern ' *.whl' --pattern ' *.tar.gz' --pattern ' CHECKSUMS.sha256'
651669 fi
670+
671+ # Verify checksums if available
672+ if [ -f " ${DOWNLOAD_DIR} /CHECKSUMS.sha256" ]; then
673+ echo " "
674+ echo " ==> Verifying checksums..."
675+ cd " ${DOWNLOAD_DIR} "
676+ if sha256sum -c CHECKSUMS.sha256; then
677+ echo " ✅ All checksums verified"
678+ else
679+ echo " ❌ Checksum verification failed!"
680+ exit 1
681+ fi
682+ cd - > /dev/null
683+ else
684+ echo " "
685+ echo " ⚠️ Warning: No CHECKSUMS.sha256 file found in release"
686+ fi
687+
652688 echo " "
653689 echo " Downloaded artifacts:"
654- ls -la ./dist/ || echo " No artifacts downloaded"
690+ ls -la " ${DOWNLOAD_DIR} /" || echo " No artifacts downloaded"
691+ echo " "
692+ echo " ==> Artifacts available at: ${DOWNLOAD_DIR} "
655693
656694# Download release artifacts from GitHub and publish to PyPI
657695publish-pypi venv = " " tag = " ": (install-tools venv)
@@ -667,13 +705,16 @@ publish-pypi venv="" tag="": (install-tools venv)
667705 echo " Usage: just publish-pypi cpy311 v24.1.1"
668706 exit 1
669707 fi
708+
709+ DOWNLOAD_DIR=" /tmp/release-artifacts/${TAG} "
710+
670711 echo " ==> Publishing ${TAG} to PyPI..."
671712 echo " "
672713 echo " Step 1: Download release artifacts from GitHub..."
673714 just download-github-release " ${TAG} "
674715 echo " "
675716 echo " Step 2: Verify packages with twine..."
676- " ${VENV_PATH} /bin/twine" check dist/ *
717+ " ${VENV_PATH} /bin/twine" check " ${DOWNLOAD_DIR} " / * .whl " ${DOWNLOAD_DIR} " / * .tar.gz
677718 echo " "
678719 echo " Note: This is a pure Python package (py3-none-any wheel)."
679720 echo " auditwheel verification is not applicable (no native extensions)."
@@ -683,7 +724,7 @@ publish-pypi venv="" tag="": (install-tools venv)
683724 echo " WARNING: This will upload to PyPI!"
684725 echo " Press Ctrl+C to cancel, or Enter to continue..."
685726 read
686- " ${VENV_PATH} /bin/twine" upload dist/ *
727+ " ${VENV_PATH} /bin/twine" upload " ${DOWNLOAD_DIR} " / * .whl " ${DOWNLOAD_DIR} " / * .tar.gz
687728 echo " "
688729 echo " ==> Successfully published ${TAG} to PyPI"
689730
@@ -710,6 +751,119 @@ publish-rtd tag="":
710751 echo " "
711752
712753
754+ # Generate release notes from GitHub release for documentation integration
755+ generate-release-notes tag :
756+ #!/usr/bin/env bash
757+ set -e
758+
759+ TAG=" {{ tag }}"
760+ DOWNLOAD_DIR=" /tmp/release-artifacts/${TAG} "
761+
762+ echo " ==> Generating release notes for ${TAG} ..."
763+
764+ # Check gh CLI is authenticated
765+ if ! gh auth status & > /dev/null; then
766+ echo " ❌ Error: gh CLI is not authenticated"
767+ echo " Run: gh auth login"
768+ exit 1
769+ fi
770+
771+ # Get release info from GitHub
772+ echo " "
773+ echo " ==> Fetching release information from GitHub..."
774+ gh release view " ${TAG} " --repo crossbario/cfxdb --json tagName,name,body,createdAt,assets \
775+ > " ${DOWNLOAD_DIR} /release-info.json" 2> /dev/null || {
776+ echo " ❌ Error: Could not fetch release ${TAG} "
777+ exit 1
778+ }
779+
780+ # Extract release body (notes)
781+ echo " "
782+ echo " ==> Release notes for ${TAG} :"
783+ echo " ----------------------------------------"
784+ gh release view " ${TAG} " --repo crossbario/cfxdb --json body -q ' .body'
785+ echo " ----------------------------------------"
786+ echo " "
787+ echo " ==> Release info saved to: ${DOWNLOAD_DIR} /release-info.json"
788+
789+ # Integrate GitHub release artifacts into documentation (chain-of-custody)
790+ docs-integrate-github-release tag :
791+ #!/usr/bin/env bash
792+ set -e
793+
794+ TAG=" {{ tag }}"
795+ DOWNLOAD_DIR=" /tmp/release-artifacts/${TAG} "
796+ DOCS_RELEASE_DIR=" docs/_releases/${TAG} "
797+
798+ echo " ==> Integrating GitHub release ${TAG} into documentation..."
799+
800+ # Ensure artifacts are downloaded
801+ if [ ! -d " ${DOWNLOAD_DIR} " ] || [ -z " $( ls -A ${DOWNLOAD_DIR} 2> /dev/null) " ]; then
802+ echo " ==> Artifacts not found, downloading..."
803+ just download-github-release " ${TAG} "
804+ fi
805+
806+ # Create docs release directory
807+ mkdir -p " ${DOCS_RELEASE_DIR} "
808+
809+ # Copy chain-of-custody files
810+ echo " "
811+ echo " ==> Copying chain-of-custody files..."
812+
813+ if [ -f " ${DOWNLOAD_DIR} /CHECKSUMS.sha256" ]; then
814+ cp " ${DOWNLOAD_DIR} /CHECKSUMS.sha256" " ${DOCS_RELEASE_DIR} /"
815+ echo " ✓ CHECKSUMS.sha256"
816+ fi
817+
818+ if [ -f " ${DOWNLOAD_DIR} /release-info.json" ]; then
819+ cp " ${DOWNLOAD_DIR} /release-info.json" " ${DOCS_RELEASE_DIR} /"
820+ echo " ✓ release-info.json"
821+ fi
822+
823+ # Generate build-info.txt with download metadata
824+ echo " ==> Generating build-info.txt..."
825+ TIMESTAMP=$( date -u +" %Y-%m-%dT%H:%M:%SZ" )
826+ ARTIFACTS=$( ls -la " ${DOWNLOAD_DIR} " /* .whl " ${DOWNLOAD_DIR} " /* .tar.gz 2> /dev/null | awk ' {print " " $NF ": " $5 " bytes"}' )
827+ {
828+ echo " Release: ${TAG} "
829+ echo " Downloaded: ${TIMESTAMP} "
830+ echo " Source: GitHub Releases (crossbario/cfxdb)"
831+ echo " Verification: Checksums verified during download"
832+ echo " "
833+ echo " Artifacts:"
834+ echo " ${ARTIFACTS} "
835+ } > " ${DOCS_RELEASE_DIR} /build-info.txt"
836+ echo " ✓ build-info.txt"
837+
838+ # Generate VALIDATION.txt
839+ echo " ==> Generating VALIDATION.txt..."
840+ CHECKSUM_STATUS=" NO CHECKSUMS AVAILABLE"
841+ if [ -f " ${DOWNLOAD_DIR} /CHECKSUMS.sha256" ]; then
842+ CHECKSUM_STATUS=" PASSED"
843+ fi
844+ ARTIFACT_LIST=$( ls " ${DOWNLOAD_DIR} " /* .whl " ${DOWNLOAD_DIR} " /* .tar.gz 2> /dev/null | while read f; do echo " - $( basename " $f " ) " ; done)
845+ {
846+ echo " Validation Report for ${TAG} "
847+ echo " Generated: ${TIMESTAMP} "
848+ echo " "
849+ echo " Source Verification:"
850+ echo " - Downloaded from: GitHub Releases (crossbario/cfxdb)"
851+ echo " - Release tag: ${TAG} "
852+ echo " - Checksum verification: ${CHECKSUM_STATUS} "
853+ echo " "
854+ echo " Artifact List:"
855+ echo " ${ARTIFACT_LIST} "
856+ echo " "
857+ echo " This package is a pure Python wheel (py3-none-any)."
858+ echo " No native code compilation or platform-specific verification required."
859+ } > " ${DOCS_RELEASE_DIR} /VALIDATION.txt"
860+ echo " ✓ VALIDATION.txt"
861+
862+ echo " "
863+ echo " ==> Documentation integration complete."
864+ echo " Files written to: ${DOCS_RELEASE_DIR} /"
865+ ls -la " ${DOCS_RELEASE_DIR} /"
866+
713867# -----------------------------------------------------------------------------
714868# -- Release workflow recipes
715869# -----------------------------------------------------------------------------
0 commit comments