diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1a5aeba..b73341b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,6 +19,17 @@ jobs: steps: - uses: actions/checkout@v4 + with: + fetch-depth: 0 # Full history for gitversion + + - name: Install GitVersion + uses: gittools/actions/gitversion/setup@v4 + with: + versionSpec: '6.x.x' + + - name: Determine Version + id: gitversion + uses: gittools/actions/gitversion/execute@v4 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v4 @@ -31,6 +42,14 @@ jobs: - name: Build project run: npm run build + env: + GITVERSION_SEMVER: ${{ steps.gitversion.outputs.semVer }} + GITVERSION_FULLSEMVER: ${{ steps.gitversion.outputs.fullSemVer }} + GITVERSION_INFORMATIONALVERSION: ${{ steps.gitversion.outputs.informationalVersion }} - name: Run tests (includes linting, formatting, and type checking) - run: npm test \ No newline at end of file + run: npm test + env: + GITVERSION_SEMVER: ${{ steps.gitversion.outputs.semVer }} + GITVERSION_FULLSEMVER: ${{ steps.gitversion.outputs.fullSemVer }} + GITVERSION_INFORMATIONALVERSION: ${{ steps.gitversion.outputs.informationalVersion }} \ No newline at end of file diff --git a/src/build/inject-version.ts b/src/build/inject-version.ts index 25a0800..a1b5beb 100644 --- a/src/build/inject-version.ts +++ b/src/build/inject-version.ts @@ -3,116 +3,33 @@ import { join } from 'path'; import { execSync } from 'child_process'; function getGitVersion(): string { - // First, check if GitVersion environment variables are available (from CI) + // Check GitVersion environment variables (from CI) const envSemVer = process.env.GITVERSION_SEMVER; + const envFullSemVer = process.env.GITVERSION_FULLSEMVER; - if (envSemVer) { - console.log(`Using GitVersion from environment: ${envSemVer}`); - return envSemVer; + // Check if environment variables are defined (even if empty) + if (envSemVer !== undefined || envFullSemVer !== undefined) { + const version = envSemVer || envFullSemVer; + if (!version || version.trim() === '') { + throw new Error('GitVersion environment variables are present but empty. Expected valid version string.'); + } + console.log(`Using GitVersion from environment: ${version}`); + return version; } + // Try GitVersion CLI try { - // Try GitVersion CLI tool (if available locally) const gitVersionOutput = execSync('gitversion', { encoding: 'utf-8', cwd: process.cwd() }); const gitVersionData = JSON.parse(gitVersionOutput); - console.log(`Using GitVersion from CLI: ${gitVersionData.SemVer || gitVersionData.FullSemVer}`); - return gitVersionData.SemVer || gitVersionData.FullSemVer; - } catch { - // Fallback to simple git tag approach - try { - // Ensure tags are fetched (helpful in CI environments) - try { - execSync('git fetch --tags', { stdio: 'pipe', cwd: process.cwd() }); - console.log('Tags fetched successfully'); - } catch { - console.log('Failed to fetch tags, continuing anyway'); - } - - // Try to get the last tag - if no tags exist, handle gracefully - let lastTag: string; - let commits: number; - - try { - lastTag = execSync('git describe --tags --abbrev=0', { encoding: 'utf-8', cwd: process.cwd() }).trim(); - const commitsSince = execSync(`git rev-list ${lastTag}..HEAD --count`, { - encoding: 'utf-8', - cwd: process.cwd(), - }).trim(); - commits = parseInt(commitsSince, 10); - console.log(`Last tag: ${lastTag}, commits since: ${commits}`); - } catch (tagError) { - console.log(`No tags found: ${tagError}, generating version from scratch`); - // No tags exist, generate a proper version based on branch - const branch = execSync('git branch --show-current', { encoding: 'utf-8', cwd: process.cwd() }).trim(); - const shortHash = execSync('git rev-parse --short HEAD', { encoding: 'utf-8', cwd: process.cwd() }).trim(); - if (branch === 'main') { - console.log(`No tags available, using default main version: 1.0.0+${shortHash}`); - return `1.0.0+${shortHash}`; - } else { - console.log(`No tags available, using default feature branch version: 0.0.1-alpha.${shortHash}`); - return `0.0.1-alpha.${shortHash}`; - } - } - - // Parse the tag version - handle both normal and pre-release tags - const match = lastTag.match(/^v?(\d+)\.(\d+)\.(\d+)(?:-(.+))?$/); - if (!match || !match[1] || !match[2] || !match[3]) { - console.log(`Tag format not recognized: ${lastTag}, falling back to generated version`); - // Generate a proper version format instead of using git describe - const branch = execSync('git branch --show-current', { encoding: 'utf-8', cwd: process.cwd() }).trim(); - const shortHash = execSync('git rev-parse --short HEAD', { encoding: 'utf-8', cwd: process.cwd() }).trim(); - if (branch === 'main') { - return `1.0.0+${shortHash}`; - } else { - return `0.0.1-alpha.${shortHash}`; - } - } - - const major = parseInt(match[1], 10); - const minor = parseInt(match[2], 10); - let patch = parseInt(match[3], 10); - - // Get current branch - const branch = execSync('git branch --show-current', { encoding: 'utf-8', cwd: process.cwd() }).trim(); - console.log(`Current branch: ${branch}`); - - // If we're exactly on a tag, use the tag directly - if (commits === 0) { - const cleanTag = lastTag.replace(/^v/, ''); - console.log(`Using exact tag version: ${cleanTag}`); - return cleanTag; - } - - // For commits beyond the tag, increment appropriately based on branch - if (branch === 'main') { - patch += 1; - const version = `${major}.${minor}.${patch}`; - console.log(`Using fallback git logic for main branch: ${version}`); - return version; - } else { - patch += 1; - const version = `${major}.${minor}.${patch}-alpha.${commits}`; - console.log(`Using fallback git logic for feature branch: ${version}`); - return version; - } - } catch (gitError) { - console.log(`Git operations failed: ${gitError}`); - // Last resort - generate a proper version format - try { - const branch = execSync('git branch --show-current', { encoding: 'utf-8', cwd: process.cwd() }).trim(); - const shortHash = execSync('git rev-parse --short HEAD', { encoding: 'utf-8', cwd: process.cwd() }).trim(); - if (branch === 'main') { - console.log(`Using basic fallback for main: 1.0.0+${shortHash}`); - return `1.0.0+${shortHash}`; - } else { - console.log(`Using basic fallback for feature branch: 0.0.1-alpha.${shortHash}`); - return `0.0.1-alpha.${shortHash}`; - } - } catch { - console.log('All git operations failed, using minimal fallback'); - return '0.0.1-unknown'; - } - } + const version = gitVersionData.SemVer || gitVersionData.FullSemVer; + console.log(`Using GitVersion from CLI: ${version}`); + return version; + } catch (gitVersionError) { + throw new Error( + `GitVersion is required but was not available. ` + + `Expected GITVERSION_SEMVER environment variable or working 'gitversion' CLI tool. ` + + `Error: ${gitVersionError}`, + ); } } @@ -139,18 +56,19 @@ function injectVersionIntoHtml(): void { htmlContent = htmlContent.replace(metaTagRegex, `$1\n `); } - // Inject version into footer - const footerRegex = /(