diff --git a/README.md b/README.md index 3ab96df..c83991d 100644 --- a/README.md +++ b/README.md @@ -59,11 +59,35 @@ dotnet pack lib/csharp/Octopus/Octopus.Kubernetes.Monitor.MessageContracts -o .. ### Go SDK You can use a local version of the Go SDK by using a replace directive in the Kubernete's monitor Go module file. -``` -replace github.com/octopusdeploy/kubernetes-monitor-contracts => {PATH_TO_LOCAL_REPO} +```go +replace github.com/octopusdeploy/kubernetes-monitor-contracts/go => {PATH_TO_LOCAL_REPO} // Example -replace github.com/octopusdeploy/kubernetes-monitor-contracts => ../kubernetes-monitor-contracts/lib/go +replace github.com/octopusdeploy/kubernetes-monitor-contracts/go => ../kubernetes-monitor-contracts/go +``` + +### `build-local` script +Two scripts have been provided to automate generating and installing local packages. The scripts will do the following by default: +1. Run `buf generate` to generate the gRPC SDKs from the Proto files - This will generate the SDKs for all of the languages +2. Add a replace directive to the Kubernetes Monitor `go.mod` file assuming that the Kubernetes Project folder is at `../lobster-watcher` +3. Update all the versions of any package references for to `Octopus.Kubernetes.Monitor.MessageContracts` to the local nuget package. + +**This script assumes that a local nuget package source has been configured already, the default location is `../LocalPackages`** + +#### Usage +```bash +# Bash +./build-local.sh +./build-local.sh --languages=go + +# For more detailed information about available parameters +./build-local.sh --help + +# Powershell +./build-local.ps1 +./build-local.ps1 --languages=go +# For more detailed information about available parameters +get-help .\build-local.ps1 -full ``` # Configuration diff --git a/build-local.ps1 b/build-local.ps1 new file mode 100755 index 0000000..72517f2 --- /dev/null +++ b/build-local.ps1 @@ -0,0 +1,186 @@ +#!/usr/bin/env pwsh + +<# +.SYNOPSIS + Automates local development experience for Kubernetes Monitor Message Contracts. +.DESCRIPTION + Generates SDKs, builds packages, and updates project references. +.PARAMETER Languages + Comma-separated list of languages to generate SDKs for (default: go,csharp) +.PARAMETER OutputLocation + Path where built packages should be moved to (default: ../LocalPackages) +.PARAMETER OctopusLocation + Path to the Octopus Deploy project (default: ../OctopusDeploy) +.PARAMETER K8sMonitorLocation + Path to the Kubernetes Monitor project (default: ../lobster-watcher) +.PARAMETER OctopusProjects + Comma-separated list of specific Octopus projects to update +#> + +param ( + [string]$Languages = "go,csharp", + [string]$OutputLocation = "../LocalPackages", + [string]$OctopusLocation = "../OctopusDeploy", + [string]$K8sMonitorLocation = "../lobster-watcher", + [string]$OctopusProjects = "" +) + +# Colors for prettier output +$Green = [System.ConsoleColor]::Green +$Yellow = [System.ConsoleColor]::Yellow +$Red = [System.ConsoleColor]::Red +$Cyan = [System.ConsoleColor]::Cyan +$Blue = [System.ConsoleColor]::Blue +$DefaultColor = [Console]::ForegroundColor + +# Create output directory if it doesn't exist +if (-not (Test-Path $OutputLocation)) { + New-Item -ItemType Directory -Path $OutputLocation | Out-Null +} + +# Get absolute path of current directory (repository root) +$RepoPath = (Get-Location).Path + +# Split languages into array +$LanguageArray = $Languages.Split(",") + +Write-Host "`n=== Generating SDKs ===" -ForegroundColor $Blue +Write-Host "Running buf generate..." -ForegroundColor $Yellow +try { + buf generate + if ($LASTEXITCODE -ne 0) { + Write-Host "āŒ Failed to generate SDKs" -ForegroundColor $Red + exit 1 + } + Write-Host "āœ… SDKs generated successfully" -ForegroundColor $Green +} catch { + Write-Host "āŒ Failed to generate SDKs: $_" -ForegroundColor $Red + exit 1 +} + +# Process each language +foreach ($lang in $LanguageArray) { + switch ($lang) { + "csharp" { + Write-Host "`n=== Processing C# SDK ===" -ForegroundColor $Blue + + # Get the current version from csproj + $CsprojPath = "csharp/Octopus/Octopus.Kubernetes.Monitor.MessageContracts/Octopus.Kubernetes.Monitor.MessageContracts.csproj" + $CsprojContent = Get-Content $CsprojPath -Raw + if ($CsprojContent -match '(.*?)') { + $BaseVersion = $Matches[1] + } else { + $BaseVersion = "1.0.0" + } + + # Get the current branch name + $BranchName = (git branch --show-current) -replace "/", "-" + + # Generate a timestamp + $Timestamp = Get-Date -Format "yyyyMMddHHmmss" + + # Create prerelease version string + $PrereleaseVersion = "${BaseVersion}-${BranchName}-${Timestamp}" + + Write-Host "šŸ“¦ Packing C# SDK with version: $PrereleaseVersion" -ForegroundColor $Yellow + + try { + dotnet pack $CsprojPath -c Debug -p:Version=$PrereleaseVersion -o $OutputLocation + if ($LASTEXITCODE -ne 0) { + Write-Host "āŒ Failed to pack C# SDK" -ForegroundColor $Red + exit 1 + } + Write-Host "āœ… C# SDK packaged to $OutputLocation" -ForegroundColor $Green + } catch { + Write-Host "āŒ Failed to pack C# SDK: $_" -ForegroundColor $Red + exit 1 + } + + # Update dependent projects in Octopus Deploy repository + if (Test-Path $OctopusLocation) { + $DependentProjects = @() + + # Check if specific projects were specified + if ($OctopusProjects) { + Write-Host "šŸŽÆ Updating specified projects..." -ForegroundColor $Yellow + $ProjectArray = $OctopusProjects.Split(",") + + # Find csproj files for specified projects + foreach ($projectName in $ProjectArray) { + $ProjectPaths = Get-ChildItem -Path $OctopusLocation -Recurse -Filter "${projectName}.csproj" -ErrorAction SilentlyContinue + if ($ProjectPaths) { + $DependentProjects += $ProjectPaths + } else { + Write-Host "āš ļø Project not found: $projectName" -ForegroundColor $Yellow + } + } + } else { + # Search for all projects that reference the package + Write-Host "šŸ” Searching for projects referencing Octopus.Kubernetes.Monitor.MessageContracts..." -ForegroundColor $Yellow + $AllProjects = Get-ChildItem -Path $OctopusLocation -Recurse -Filter "*.csproj" -ErrorAction SilentlyContinue + foreach ($project in $AllProjects) { + $content = Get-Content $project.FullName -Raw + if ($content -match 'Octopus\.Kubernetes\.Monitor\.MessageContracts') { + $DependentProjects += $project + } + } + } + + # Update each project file + $UpdatedCount = 0 + foreach ($project in $DependentProjects) { + Write-Host "šŸ“ Updating $($project.FullName) to use version $PrereleaseVersion" -ForegroundColor $Yellow + + $content = Get-Content $project.FullName -Raw + $updatedContent = $content -replace '' ) { + # Update existing directive + $GoModContent = $GoModContent -replace 'replace github\.com/OctopusDeploy/kubernetes-monitor-contracts/go =>.*', $ReplaceDirective + } else { + # Add new directive at the end of the file + $GoModContent = $GoModContent + "`n$ReplaceDirective`n" + } + + Set-Content -Path $GoModFile -Value $GoModContent + Write-Host "āœ… Added Go module replace directive to $GoModFile" -ForegroundColor $Green + } + + default { + Write-Host "āš ļø Unsupported language: $lang" -ForegroundColor $Yellow + } + } +} + +Write-Host "`n✨ Local development setup complete!" -ForegroundColor $Green \ No newline at end of file diff --git a/build-local.sh b/build-local.sh new file mode 100755 index 0000000..a744bed --- /dev/null +++ b/build-local.sh @@ -0,0 +1,188 @@ +#!/bin/bash + +# Colors for prettier output +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +RED='\033[0;31m' +CYAN='\033[0;36m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Default values +LANGUAGES="go,csharp" +OUTPUT_LOCATION="../LocalPackages" +OCTOPUS_DEPLOY_LOCATION="../OctopusDeploy" +K8S_MONITOR_LOCATION="../lobster-watcher" +OCTOPUS_PROJECTS="" + +# Parse command line arguments +while [[ $# -gt 0 ]]; do + case $1 in + --languages=*) + LANGUAGES="${1#*=}" + shift + ;; + --output=*) + OUTPUT_LOCATION="${1#*=}" + shift + ;; + --octopus=*) + OCTOPUS_DEPLOY_LOCATION="${1#*=}" + shift + ;; + --k8s-monitor=*) + K8S_MONITOR_LOCATION="${1#*=}" + shift + ;; + --octopus-projects=*) + OCTOPUS_PROJECTS="${1#*=}" + shift + ;; + -h|--help) + echo -e "${CYAN}Usage: $0 [options]${NC}" + echo "Options:" + echo " --languages=LANGS Comma-separated list of languages (default: go,csharp)" + echo " --output=PATH Output location for built packages (default: ../LocalPackages)" + echo " --octopus=PATH Octopus Deploy project location (default: ../OctopusDeploy)" + echo " --k8s-monitor=PATH Kubernetes Monitor project location (default: ../lobster-watcher)" + echo " --octopus-projects=LIST Comma-separated list of specific Octopus projects to update" + echo " -h, --help Show this help message" + exit 0 + ;; + *) + echo -e "${RED}Unknown option: $1${NC}" + echo "Use -h or --help for usage information" + exit 1 + ;; + esac +done + +# Convert languages string to array +IFS=',' read -ra LANGUAGE_ARRAY <<< "$LANGUAGES" + +# Create output directory if it doesn't exist +mkdir -p "$OUTPUT_LOCATION" + +# Get absolute path of current directory (repository root) +REPO_PATH=$(pwd) + +echo -e "\n${BLUE}=== Generating SDKs ===${NC}" +echo -e "${YELLOW}Running buf generate...${NC}" +buf generate || { echo -e "${RED}āŒ Failed to generate SDKs${NC}"; exit 1; } +echo -e "${GREEN}āœ… SDKs generated successfully${NC}\n" + +# Process each language +for lang in "${LANGUAGE_ARRAY[@]}"; do + case "$lang" in + "csharp") + echo -e "${BLUE}=== Processing C# SDK ===${NC}" + + # Get the current version from csproj + CSPROJ_PATH="csharp/Octopus/Octopus.Kubernetes.Monitor.MessageContracts/Octopus.Kubernetes.Monitor.MessageContracts.csproj" + BASE_VERSION=$(grep -o '[^<]*' "$CSPROJ_PATH" | sed 's/\(.*\)<\/Version>/\1/') + + if [ -z "$BASE_VERSION" ]; then + BASE_VERSION="1.0.0" + fi + + # Get the current branch name + BRANCH_NAME=$(git branch --show-current | sed 's/\//-/g') + + # Generate a timestamp + TIMESTAMP=$(date +"%Y%m%d%H%M%S") + + # Create prerelease version string + PRERELEASE_VERSION="${BASE_VERSION}-${BRANCH_NAME}-${TIMESTAMP}" + + echo -e "${YELLOW}šŸ“¦ Packing C# SDK with version: ${PRERELEASE_VERSION}${NC}" + + # Pack with debug configuration and prerelease version + dotnet pack "$CSPROJ_PATH" -c Debug -p:Version="$PRERELEASE_VERSION" -o "$OUTPUT_LOCATION" || { + echo -e "${RED}āŒ Failed to pack C# SDK${NC}"; + exit 1; + } + echo -e "${GREEN}āœ… C# SDK packaged to $OUTPUT_LOCATION${NC}\n" + + # Update dependent projects in Octopus Deploy repository + if [ -d "$OCTOPUS_DEPLOY_LOCATION" ]; then + DEPENDENT_PROJECTS="" + + # Check if specific projects were specified + if [ -n "$OCTOPUS_PROJECTS" ]; then + echo -e "${YELLOW}šŸŽÆ Updating specified projects...${NC}" + # Convert projects string to array + IFS=',' read -ra PROJECT_ARRAY <<< "$OCTOPUS_PROJECTS" + + # Find csproj files for specified projects + for project_name in "${PROJECT_ARRAY[@]}"; do + PROJECT_PATHS=$(find "$OCTOPUS_DEPLOY_LOCATION" -name "${project_name}.csproj" 2>/dev/null) + if [ -n "$PROJECT_PATHS" ]; then + # Add to the list of dependent projects if found + DEPENDENT_PROJECTS="${DEPENDENT_PROJECTS}${PROJECT_PATHS}"$'\n' + else + echo -e "${YELLOW}āš ļø Project not found: $project_name${NC}" + fi + done + else + # Search for all projects that reference the package + echo -e "${YELLOW}šŸ” Searching for projects referencing Octopus.Kubernetes.Monitor.MessageContracts...${NC}" + DEPENDENT_PROJECTS=$(find "$OCTOPUS_DEPLOY_LOCATION" -name "*.csproj" -exec grep -l "Octopus.Kubernetes.Monitor.MessageContracts" {} \;) + fi + + # Trim trailing newline + DEPENDENT_PROJECTS=$(echo "$DEPENDENT_PROJECTS" | sed '/^$/d') + + # Update each project file + for project in $DEPENDENT_PROJECTS; do + echo -e "${YELLOW}šŸ“ Updating $project to use version $PRERELEASE_VERSION${NC}" + + # Different sed syntax for macOS vs Linux + if [[ "$OSTYPE" == "darwin"* ]]; then + # macOS version + sed -i '' -E "s|.*|$REPLACE_DIRECTIVE|" "$GO_MOD_FILE" && rm -f "${GO_MOD_FILE}.bak" + else + # Add new directive at the end of the file + echo "" >> "$GO_MOD_FILE" + echo "$REPLACE_DIRECTIVE" >> "$GO_MOD_FILE" + fi + echo -e "${GREEN}āœ… Added Go module replace directive to $GO_MOD_FILE${NC}\n" + ;; + *) + echo -e "${YELLOW}āš ļø Unsupported language: $lang${NC}\n" + ;; + esac +done + +echo -e "${GREEN}✨ Local development setup complete!${NC}" \ No newline at end of file