3131 # The 'v' prefix helps distinguish version tags from other tags
3232 - ' *-v[0-9]+.[0-9]+.[0-9]+'
3333
34+ # Manual trigger for dry-run testing
35+ # This allows testing all validation checks without actually publishing
36+ workflow_dispatch :
37+ inputs :
38+ crate :
39+ description : ' Crate name to test (e.g., gl-client)'
40+ required : true
41+ type : string
42+ version :
43+ description : ' Version to test (e.g., 1.2.3)'
44+ required : true
45+ type : string
46+
3447jobs :
3548 publish :
3649 runs-on : ubuntu-latest
@@ -48,35 +61,46 @@ jobs:
4861 - name : Parse tag
4962 id : parse
5063 run : |
51- # Extract the full tag name from the GitHub ref
52- # GITHUB_REF format: refs/tags/mycrate-v1.2.3
53- TAG=${GITHUB_REF#refs/tags/}
54- echo "Full tag: $TAG"
55-
56- # Parse the tag to extract crate name and version
57- # Example: mycrate-v1.2.3 → CRATE=mycrate, VERSION=1.2.3
58- # This regex removes everything from '-v' onwards to get the crate name
59- CRATE=$(echo $TAG | sed -E 's/-v[0-9]+\.[0-9]+\.[0-9]+$//')
60-
61- # This regex extracts just the version numbers after '-v'
62- VERSION=$(echo $TAG | sed -E 's/.*-v([0-9]+\.[0-9]+\.[0-9]+)$/\1/')
63-
64+ # Check if this is a manual dispatch (dry-run) or tag-triggered run
65+ if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
66+ # Manual dispatch - use inputs
67+ CRATE="${{ inputs.crate }}"
68+ VERSION="${{ inputs.version }}"
69+ echo "🧪 DRY-RUN MODE: Testing $CRATE version $VERSION"
70+ echo "dry_run=true" >> $GITHUB_OUTPUT
71+ else
72+ # Tag-triggered - parse from tag
73+ # Extract the full tag name from the GitHub ref
74+ # GITHUB_REF format: refs/tags/mycrate-v1.2.3
75+ TAG=${GITHUB_REF#refs/tags/}
76+ echo "Full tag: $TAG"
77+
78+ # Parse the tag to extract crate name and version
79+ # Example: mycrate-v1.2.3 → CRATE=mycrate, VERSION=1.2.3
80+ # This regex removes everything from '-v' onwards to get the crate name
81+ CRATE=$(echo $TAG | sed -E 's/-v[0-9]+\.[0-9]+\.[0-9]+$//')
82+
83+ # This regex extracts just the version numbers after '-v'
84+ VERSION=$(echo $TAG | sed -E 's/.*-v([0-9]+\.[0-9]+\.[0-9]+)$/\1/')
85+
86+ echo "📦 Publishing $CRATE version $VERSION"
87+ echo "dry_run=false" >> $GITHUB_OUTPUT
88+ fi
89+
6490 # Make these available to subsequent steps via GITHUB_OUTPUT
6591 echo "crate=$CRATE" >> $GITHUB_OUTPUT
6692 echo "version=$VERSION" >> $GITHUB_OUTPUT
67-
93+
6894 # Parse semantic version components for later use in semver checks
6995 # We need to know if this is a major/minor/patch bump to determine
7096 # whether breaking changes are allowed
7197 MAJOR=$(echo $VERSION | cut -d. -f1)
7298 MINOR=$(echo $VERSION | cut -d. -f2)
7399 PATCH=$(echo $VERSION | cut -d. -f3)
74-
100+
75101 echo "major=$MAJOR" >> $GITHUB_OUTPUT
76102 echo "minor=$MINOR" >> $GITHUB_OUTPUT
77103 echo "patch=$PATCH" >> $GITHUB_OUTPUT
78-
79- echo "📦 Publishing $CRATE version $VERSION"
80104
81105 - uses : dtolnay/rust-toolchain@stable
82106
@@ -411,6 +435,7 @@ jobs:
411435 # ==========================================================================
412436
413437 - name : Publish to crates.io
438+ if : steps.parse.outputs.dry_run == 'false'
414439 run : |
415440 echo "🚀 Publishing ${{ steps.parse.outputs.crate }} v${{ steps.parse.outputs.version }} to crates.io..."
416441
@@ -428,28 +453,47 @@ jobs:
428453 CARGO_REGISTRY_TOKEN : ${{ secrets.CRATES_IO_TOKEN }}
429454
430455 - name : Create GitHub Release
456+ if : steps.parse.outputs.dry_run == 'false'
431457 uses : softprops/action-gh-release@v1
432458 with :
433459 # Use the tag that triggered this workflow
434460 tag_name : ${{ github.ref }}
435-
461+
436462 # Format: "mycrate v1.2.3"
437463 name : ${{ steps.parse.outputs.crate }} v${{ steps.parse.outputs.version }}
438-
464+
439465 # Release notes body
440466 # In the future, you could extract the changelog section here
441467 # to automatically populate the release notes
442468 body : |
443469 Published ${{ steps.parse.outputs.crate }} v${{ steps.parse.outputs.version }} to crates.io
444-
470+
445471 🔗 [View on crates.io](https://crates.io/crates/${{ steps.parse.outputs.crate }})
446-
472+
447473 See [CHANGELOG](https://github.com/${{ github.repository }}/blob/${{ github.ref_name }}/CHANGELOG.md) for details.
448474 env :
449475 # GITHUB_TOKEN is automatically provided by GitHub Actions
450476 # No need to create this secret manually
451477 GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
452478
479+ - name : Dry-run complete
480+ if : steps.parse.outputs.dry_run == 'true'
481+ run : |
482+ echo "✅ DRY-RUN COMPLETE!"
483+ echo ""
484+ echo "All validation checks passed for ${{ steps.parse.outputs.crate }} v${{ steps.parse.outputs.version }}"
485+ echo ""
486+ echo "The following checks were successful:"
487+ echo " ✅ Version matches Cargo.toml"
488+ echo " ✅ Changelog format is valid"
489+ echo " ✅ Changelog entry exists"
490+ echo " ✅ Semver compatibility check passed"
491+ echo " ✅ All tests passed"
492+ echo ""
493+ echo "To publish for real, push a tag:"
494+ echo " git tag ${{ steps.parse.outputs.crate }}-v${{ steps.parse.outputs.version }}"
495+ echo " git push origin ${{ steps.parse.outputs.crate }}-v${{ steps.parse.outputs.version }}"
496+
453497# ==============================================================================
454498# MAINTENANCE NOTES
455499# ==============================================================================
0 commit comments