Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .github/version.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,12 @@ on:
- kind: regexp
file: setup/action.yml
pattern: "(?<=default: ).*"
- kind: regexp
file: manifests/installer.yaml
pattern: "(?<=PackageVersion: ).*"
- kind: regexp
file: manifests/locale.en-US.yaml
pattern: "(?<=PackageVersion: ).*"
- kind: regexp
file: manifests/version.yaml
pattern: "(?<=PackageVersion: ).*"
33 changes: 33 additions & 0 deletions .github/workflows/checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -168,3 +168,36 @@ jobs:
push: false
tags: optum/semver-cli:pr
platforms: linux/amd64

winget-check:
runs-on: windows-latest
permissions:
contents: read
needs:
- check
steps:
- uses: actions/checkout@v4
- uses: denoland/setup-deno@v2
with:
deno-version: v2.x

- name: Install Dependencies
run: |
rm deno.lock
deno install --no-lock

- name: Compile Windows Binary
run: |
deno compile --allow-run --allow-env --allow-read --allow-write -o bin/semver --target x86_64-pc-windows-msvc main.ts

- name: Test Winget Package Script
shell: bash
run: |
chmod +x scripts/winget-package.sh
./scripts/winget-package.sh

- name: Test Winget Publish Script (Dry Run)
shell: bash
run: |
chmod +x scripts/winget-publish.sh
./scripts/winget-publish.sh --dry-run
52 changes: 52 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,57 @@ jobs:
--head "${branch_name}" \
--base main

winget:
if: ${{ github.event_name == 'release' && github.event.release.prerelease == false }}
runs-on: windows-latest
needs:
- version
- assets
permissions:
contents: write
pull-requests: write
env:
GH_TOKEN: ${{ secrets.SEMVER_PUBLISH_TOKEN }}
GITHUB_TOKEN: ${{ secrets.SEMVER_PUBLISH_TOKEN }}
steps:
- uses: actions/checkout@v4

- name: Configure Git
run: |
git config --global user.name 'github-actions[bot]'
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
gh auth setup-git

- name: Package for Winget
env:
VERSION: ${{ needs.version.outputs.version }}
shell: bash
run: |
chmod +x scripts/winget-package.sh
./scripts/winget-package.sh --release --version "${VERSION}"

- name: Upload ZIP as Release Asset
shell: bash
run: |
VERSION="${{ needs.version.outputs.version }}"
ZIP_FILE="dist/winget/semver.x86_64-pc-windows-msvc.zip"

if [ -f "$ZIP_FILE" ]; then
echo "Uploading $ZIP_FILE to release $VERSION"
gh release upload "${VERSION}" "$ZIP_FILE" --repo Optum/semver-cli --clobber
else
echo "Error: ZIP file not found at $ZIP_FILE"
exit 1
fi

- name: Publish to Winget
env:
VERSION: ${{ needs.version.outputs.version }}
shell: bash
run: |
chmod +x scripts/winget-publish.sh
./scripts/winget-publish.sh --release

tags:
if: ${{ github.event.release.prerelease == false }}
runs-on: ubuntu-latest
Expand All @@ -285,6 +336,7 @@ jobs:
- assets
- docker
- homebrew
- winget
permissions:
contents: write
id-token: write
Expand Down
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@ brew install optum/tap/semver

via [optum](https://github.com/Optum/homebrew-tap)

## Winget (Windows Package Manager)

```sh
winget install Optum.semver-cli
```

via [microsoft/winget-pkgs](https://github.com/microsoft/winget-pkgs)

## From Source

Installation from source will require
Expand Down
19 changes: 19 additions & 0 deletions manifests/installer.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# yaml-language-server: $schema=https://aka.ms/winget-manifest.installer.1.6.0.schema.json

PackageIdentifier: Optum.semver-cli
PackageVersion: __VERSION__
InstallerType: zip
UpgradeBehavior: install
Commands:
- semver
ReleaseDate: __RELEASE_DATE__
Installers:
- Architecture: x64
NestedInstallerType: portable
NestedInstallerFiles:
- RelativeFilePath: semver.exe
PortableCommandAlias: semver
InstallerUrl: __INSTALLER_URL__
InstallerSha256: __INSTALLER_SHA256__
ManifestType: installer
ManifestVersion: 1.6.0
26 changes: 26 additions & 0 deletions manifests/locale.en-US.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# yaml-language-server: $schema=https://aka.ms/winget-manifest.defaultLocale.1.6.0.schema.json

PackageIdentifier: Optum.semver-cli
PackageVersion: __VERSION__
PackageLocale: en-US
Publisher: Optum
PublisherUrl: https://github.com/Optum
PublisherSupportUrl: https://github.com/Optum/semver-cli/issues
Author: Optum
PackageName: semver-cli
PackageUrl: https://github.com/Optum/semver-cli
License: Apache-2.0
LicenseUrl: https://github.com/Optum/semver-cli/blob/HEAD/LICENSE
Copyright: Copyright (c) Optum
ShortDescription: A technology agnostic cli for common semantic versioning operations
Description: A technology agnostic cli for common semantic versioning operations. Built with Deno.
Moniker: semver
Tags:
- cli
- semver
- semantic-version
- versioning
- deno
ReleaseNotesUrl: https://github.com/Optum/semver-cli/releases/tag/__VERSION__
ManifestType: defaultLocale
ManifestVersion: 1.6.0
7 changes: 7 additions & 0 deletions manifests/version.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# yaml-language-server: $schema=https://aka.ms/winget-manifest.version.1.6.0.schema.json

PackageIdentifier: Optum.semver-cli
PackageVersion: __VERSION__
DefaultLocale: en-US
ManifestType: version
ManifestVersion: 1.6.0
185 changes: 185 additions & 0 deletions scripts/winget-package.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
#!/usr/bin/env bash
set -euo pipefail

# winget-package.sh - Package semver-cli for winget
# Creates ZIP file and generates winget manifest files

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"

# Default values
RELEASE_MODE=false
VERSION=""
PACKAGE_DIR="${REPO_ROOT}/dist/winget"

# Parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
--release)
RELEASE_MODE=true
shift
;;
--version)
VERSION="$2"
shift 2
;;
*)
echo "Unknown option: $1"
echo "Usage: $0 [--release] [--version VERSION]"
exit 1
;;
esac
done

# Get version if not provided
if [ -z "$VERSION" ]; then
if [ -f "$REPO_ROOT/VERSION" ]; then
VERSION=$(cat "$REPO_ROOT/VERSION")
else
echo "Error: VERSION file not found and --version not provided"
exit 1
fi
fi

echo "Packaging semver-cli version ${VERSION} for winget"
echo "Release mode: ${RELEASE_MODE}"

# Create output directory
mkdir -p "$PACKAGE_DIR"

# Function to package from local build
package_local() {
echo "Packaging from local build..."

# Check if binary exists
if [ ! -f "$REPO_ROOT/bin/semver.exe" ]; then
echo "Error: bin/semver.exe not found. Please build the Windows binary first."
exit 1
fi

# Create ZIP file
echo "Creating ZIP file..."
cd "$REPO_ROOT/bin"
zip -q "${PACKAGE_DIR}/semver.x86_64-pc-windows-msvc.zip" semver.exe
cd - > /dev/null

echo "ZIP created: ${PACKAGE_DIR}/semver.x86_64-pc-windows-msvc.zip"
}

# Function to package from GitHub release
package_release() {
echo "Downloading from GitHub release ${VERSION}..."

# Download the Windows exe asset
asset_name="semver.x86_64-pc-windows-msvc.tar.gz"
echo "Downloading ${asset_name}..."

if ! gh release download "${VERSION}" --pattern "${asset_name}" --dir "${PACKAGE_DIR}" --repo Optum/semver-cli 2>/dev/null; then
echo "Error: Failed to download ${asset_name} from release ${VERSION}"
echo "Make sure the release exists and contains the Windows binary"
exit 1
fi

# Extract the exe from tar.gz
echo "Extracting exe from tar.gz..."
cd "$PACKAGE_DIR"
tar -xzf "$asset_name" semver.exe

# Create ZIP file
echo "Creating ZIP file..."
zip -q "semver.x86_64-pc-windows-msvc.zip" semver.exe

# Clean up
rm -f "$asset_name" semver.exe
cd - > /dev/null

echo "ZIP created: ${PACKAGE_DIR}/semver.x86_64-pc-windows-msvc.zip"
}

# Package based on mode
if [ "$RELEASE_MODE" = true ]; then
package_release
else
package_local
fi

# Calculate SHA256
echo "Calculating SHA256..."
if command -v sha256sum &> /dev/null; then
SHA256=$(sha256sum "${PACKAGE_DIR}/semver.x86_64-pc-windows-msvc.zip" | cut -d' ' -f1)
elif command -v shasum &> /dev/null; then
SHA256=$(shasum -a 256 "${PACKAGE_DIR}/semver.x86_64-pc-windows-msvc.zip" | cut -d' ' -f1)
else
echo "Error: No SHA256 tool found (sha256sum or shasum)"
exit 1
fi

echo "SHA256: ${SHA256}"

# Determine installer URL
if [ "$RELEASE_MODE" = true ]; then
INSTALLER_URL="https://github.com/Optum/semver-cli/releases/download/${VERSION}/semver.x86_64-pc-windows-msvc.zip"
else
# For local builds, we'll upload the ZIP as an asset later
INSTALLER_URL="__INSTALLER_URL__"
fi

# Get release date
if [ "$RELEASE_MODE" = true ]; then
# Try to get from GitHub release
RELEASE_DATE=$(gh release view "${VERSION}" --repo Optum/semver-cli --json publishedAt --jq '.publishedAt' 2>/dev/null | cut -d'T' -f1 || date -u +%Y-%m-%d)
else
RELEASE_DATE=$(date -u +%Y-%m-%d)
fi

echo "Release date: ${RELEASE_DATE}"

# Generate manifest files
MANIFEST_DIR="${PACKAGE_DIR}/manifests/o/Optum/semver-cli/${VERSION}"
mkdir -p "$MANIFEST_DIR"

echo "Generating manifest files in ${MANIFEST_DIR}..."

# Copy and update installer manifest
sed -e "s|__VERSION__|${VERSION}|g" \
-e "s|__RELEASE_DATE__|${RELEASE_DATE}|g" \
-e "s|__INSTALLER_URL__|${INSTALLER_URL}|g" \
-e "s|__INSTALLER_SHA256__|${SHA256}|g" \
"${REPO_ROOT}/manifests/installer.yaml" > "${MANIFEST_DIR}/Optum.semver-cli.installer.yaml"

# Copy and update locale manifest
sed -e "s|__VERSION__|${VERSION}|g" \
"${REPO_ROOT}/manifests/locale.en-US.yaml" > "${MANIFEST_DIR}/Optum.semver-cli.locale.en-US.yaml"

# Copy and update version manifest
sed -e "s|__VERSION__|${VERSION}|g" \
"${REPO_ROOT}/manifests/version.yaml" > "${MANIFEST_DIR}/Optum.semver-cli.yaml"

echo "Manifest files generated:"
ls -la "${MANIFEST_DIR}"

# Output summary
cat << EOF

=================================================================
Winget Package Created Successfully
=================================================================
Version: ${VERSION}
Package: ${PACKAGE_DIR}/semver.x86_64-pc-windows-msvc.zip
SHA256: ${SHA256}
Installer URL: ${INSTALLER_URL}
Manifests: ${MANIFEST_DIR}
=================================================================

EOF

# Save metadata for publish script
cat > "${PACKAGE_DIR}/metadata.env" << EOF
VERSION=${VERSION}
SHA256=${SHA256}
INSTALLER_URL=${INSTALLER_URL}
RELEASE_DATE=${RELEASE_DATE}
MANIFEST_DIR=${MANIFEST_DIR}
EOF

echo "Metadata saved to ${PACKAGE_DIR}/metadata.env"
Loading