commit 7e458f30f6df3f1b19ccbaf5fdc8274ac58f2d00 Author: Cal Corum Date: Wed Feb 18 11:41:36 2026 -0600 Add shared composite actions: calver, gitea-tag, discord-notify Centralizes duplicated CI/CD steps from Paper Dynasty, Major Domo, and Vagabond workflows into reusable composite actions. Co-Authored-By: Claude Opus 4.6 diff --git a/calver/action.yml b/calver/action.yml new file mode 100644 index 0000000..9014ec2 --- /dev/null +++ b/calver/action.yml @@ -0,0 +1,50 @@ +# CalVer Version Generator +# Generates YYYY.MM.BUILD version from git tags +# BUILD = count of tags matching current month + 1 + +name: CalVer Version +description: Generate a CalVer (YYYY.MM.BUILD) version from git tags + +outputs: + version: + description: CalVer version (e.g., 2026.2.5) + value: ${{ steps.calver.outputs.version }} + sha_short: + description: Short commit SHA (7 chars) + value: ${{ steps.calver.outputs.sha_short }} + version_sha: + description: Version with SHA suffix (e.g., 2026.2.5-abc1234) + value: ${{ steps.calver.outputs.version_sha }} + branch: + description: Current branch name + value: ${{ steps.calver.outputs.branch }} + timestamp: + description: UTC timestamp in ISO 8601 format + value: ${{ steps.calver.outputs.timestamp }} + +runs: + using: composite + steps: + - name: Generate CalVer version + id: calver + shell: bash + run: | + YEAR=$(date -u +%Y) + MONTH=$(date -u +%-m) + PREFIX="${YEAR}.${MONTH}." + + # Count existing tags for this month + git fetch --tags + BUILD=$(git tag -l "${PREFIX}*" | wc -l) + BUILD=$((BUILD + 1)) + + VERSION="${PREFIX}${BUILD}" + SHA_SHORT=$(echo "$GITHUB_SHA" | cut -c1-7) + + echo "version=${VERSION}" >> $GITHUB_OUTPUT + echo "sha_short=${SHA_SHORT}" >> $GITHUB_OUTPUT + echo "version_sha=${VERSION}-${SHA_SHORT}" >> $GITHUB_OUTPUT + echo "branch=${GITHUB_REF_NAME}" >> $GITHUB_OUTPUT + echo "timestamp=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT + + echo "CalVer version: ${VERSION}" diff --git a/discord-notify/action.yml b/discord-notify/action.yml new file mode 100644 index 0000000..d36878c --- /dev/null +++ b/discord-notify/action.yml @@ -0,0 +1,97 @@ +# Discord Webhook Notification +# Sends a success or failure embed to a Discord channel + +name: Discord Notification +description: Send a build notification embed to Discord + +inputs: + webhook_url: + description: Discord webhook URL + required: true + title: + description: Embed title (e.g., "Paper Dynasty Bot") + required: true + status: + description: Build status - "success" or "failure" + required: false + default: success + version: + description: CalVer version string + required: false + default: "" + image_tag: + description: Docker image tag (version-sha) + required: false + default: "" + commit_sha: + description: Short commit SHA + required: false + default: "" + author: + description: Commit author + required: false + default: ${{ github.actor }} + run_url: + description: URL to the Actions run + required: false + default: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + branch: + description: Branch name + required: false + default: ${{ github.ref_name }} + timestamp: + description: ISO 8601 timestamp + required: false + default: "" + +runs: + using: composite + steps: + - name: Send Discord notification + shell: bash + run: | + if [ "${{ inputs.status }}" = "success" ]; then + COLOR=3066993 + DESCRIPTION="Docker image built and pushed to Docker Hub" + LINK_LABEL="View Run" + + # Build fields JSON for success + FIELDS='[ + {"name": "Version", "value": "`${{ inputs.version }}`", "inline": true}, + {"name": "Image Tag", "value": "`${{ inputs.image_tag }}`", "inline": true}, + {"name": "Commit", "value": "`${{ inputs.commit_sha }}`", "inline": true}, + {"name": "Author", "value": "${{ inputs.author }}", "inline": true}, + {"name": "'"$LINK_LABEL"'", "value": "[Click here](${{ inputs.run_url }})", "inline": false} + ]' + else + COLOR=15158332 + DESCRIPTION="Docker build encountered an error." + LINK_LABEL="View Logs" + + # Build fields JSON for failure + FIELDS='[ + {"name": "Branch", "value": "`${{ inputs.branch }}`", "inline": true}, + {"name": "Commit", "value": "`'"$GITHUB_SHA"'`", "inline": true}, + {"name": "Author", "value": "${{ inputs.author }}", "inline": true}, + {"name": "'"$LINK_LABEL"'", "value": "[Click here](${{ inputs.run_url }})", "inline": false} + ]' + fi + + # Use provided timestamp or generate one + TS="${{ inputs.timestamp }}" + if [ -z "$TS" ]; then + TS=$(date -u +%Y-%m-%dT%H:%M:%SZ) + fi + + # Send the webhook + curl -s -H "Content-Type: application/json" \ + -d "{ + \"embeds\": [{ + \"title\": \"${{ inputs.title }} - Build $([ '${{ inputs.status }}' = 'success' ] && echo 'Successful' || echo 'Failed')\", + \"description\": \"${DESCRIPTION}\", + \"color\": ${COLOR}, + \"fields\": ${FIELDS}, + \"timestamp\": \"${TS}\" + }] + }" \ + "${{ inputs.webhook_url }}" diff --git a/gitea-tag/action.yml b/gitea-tag/action.yml new file mode 100644 index 0000000..a2c9afb --- /dev/null +++ b/gitea-tag/action.yml @@ -0,0 +1,38 @@ +# Gitea Tag Creator +# Creates a git tag via the Gitea API (avoids branch protection issues) + +name: Create Gitea Tag +description: Create a git tag via the Gitea API + +inputs: + version: + description: Tag name / version string + required: true + token: + description: Gitea API token (usually github.token) + required: true + server_url: + description: Gitea server URL + required: false + default: ${{ github.server_url }} + repository: + description: Repository path (owner/repo) + required: false + default: ${{ github.repository }} + sha: + description: Commit SHA to tag + required: false + default: ${{ github.sha }} + +runs: + using: composite + steps: + - name: Create tag via Gitea API + shell: bash + run: | + curl -s -X POST \ + -H "Authorization: token ${{ inputs.token }}" \ + -H "Content-Type: application/json" \ + -d "{\"tag_name\": \"${{ inputs.version }}\", \"target\": \"${{ inputs.sha }}\", \"name\": \"${{ inputs.version }}\"}" \ + "${{ inputs.server_url }}/api/v1/repos/${{ inputs.repository }}/tags" + echo "Created tag ${{ inputs.version }}"