-
Notifications
You must be signed in to change notification settings - Fork 0
Fix CI test failures caused by inconsistent version injection logic between test and implementation #158
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix CI test failures caused by inconsistent version injection logic between test and implementation #158
Changes from all commits
368f09a
f45c364
690c87a
f89c00a
76e6e07
c9a7eaf
b5b1eab
11c0f6b
7af4fcc
9c017f1
c23a20b
94db67c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -82,39 +82,107 @@ jobs: | |||||||||||||||||||||||||
| - name: Install dependencies | ||||||||||||||||||||||||||
| run: npm ci | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # First: Build main branch content for the root | ||||||||||||||||||||||||||
| - name: Checkout and build main branch | ||||||||||||||||||||||||||
| # First: Build develop branch content for the subdirectory | ||||||||||||||||||||||||||
| - name: Build develop branch for sub-directory | ||||||||||||||||||||||||||
| run: npm run build | ||||||||||||||||||||||||||
| env: | ||||||||||||||||||||||||||
| GITVERSION_SEMVER: ${{ steps.gitversion.outputs.semVer }} | ||||||||||||||||||||||||||
| GITVERSION_FULLSEMVER: ${{ steps.gitversion.outputs.fullSemVer }} | ||||||||||||||||||||||||||
| GITVERSION_INFORMATIONALVERSION: ${{ steps.gitversion.outputs.informationalVersion }} | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Save develop build | ||||||||||||||||||||||||||
| - name: Save develop build | ||||||||||||||||||||||||||
| run: mv dist develop-dist | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Second: Build main branch content for the root | ||||||||||||||||||||||||||
| - name: Checkout and build main branch with test site link | ||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||
| # Save current state | ||||||||||||||||||||||||||
| git stash push -m "Save develop changes" | ||||||||||||||||||||||||||
| # Save current develop state | ||||||||||||||||||||||||||
| git stash push -m "Save develop changes" || echo "No changes to stash" | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Checkout main branch | ||||||||||||||||||||||||||
| # Checkout main branch with full history and ensure tags are available | ||||||||||||||||||||||||||
| git checkout main | ||||||||||||||||||||||||||
| git pull origin main || echo "No changes to pull" | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Build main branch content (without develop GitVersion env vars) | ||||||||||||||||||||||||||
| # This allows the inject-version script to use git-based version calculation | ||||||||||||||||||||||||||
| # which will correctly determine the main branch version | ||||||||||||||||||||||||||
| # Ensure all tags are fetched for version calculation | ||||||||||||||||||||||||||
| git fetch --tags || echo "Tags already available" | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Build main branch content with proper main branch GitVersion | ||||||||||||||||||||||||||
| npm run build | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Save main build | ||||||||||||||||||||||||||
| mv dist main-dist | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Return to develop branch | ||||||||||||||||||||||||||
| # Return to develop branch and restore state | ||||||||||||||||||||||||||
| git checkout develop | ||||||||||||||||||||||||||
| # Only pop the stash if one exists, and fail if pop fails | ||||||||||||||||||||||||||
| if git stash list | grep -q .; then | ||||||||||||||||||||||||||
| if git stash list | grep -q "Save develop changes"; then | ||||||||||||||||||||||||||
| git stash pop | ||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||
| echo "No stash to pop" | ||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||
| env: | ||||||||||||||||||||||||||
| # Pass test site info for footer link | ||||||||||||||||||||||||||
| TEST_SITE_PATH: ${{ steps.pr-info.outputs.deploy_path }} | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Second: Build develop branch content for the subdirectory | ||||||||||||||||||||||||||
| - name: Build develop branch for sub-directory | ||||||||||||||||||||||||||
| run: npm run build | ||||||||||||||||||||||||||
| # Get GitVersion for main branch after checking it out | ||||||||||||||||||||||||||
| - name: Get main branch GitVersion | ||||||||||||||||||||||||||
| id: gitversion-main | ||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||
| # Save current develop state | ||||||||||||||||||||||||||
| git stash push -m "Save develop changes" || echo "No changes to stash" | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Checkout main branch | ||||||||||||||||||||||||||
| git checkout main | ||||||||||||||||||||||||||
| git pull origin main || echo "No changes to pull" | ||||||||||||||||||||||||||
| git fetch --tags || echo "Tags already available" | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Get GitVersion for main branch | ||||||||||||||||||||||||||
| gitversion /output json | tee gitversion-main.json | ||||||||||||||||||||||||||
| MAIN_SEMVER=$(cat gitversion-main.json | grep -o '"SemVer":"[^"]*"' | cut -d'"' -f4) | ||||||||||||||||||||||||||
| MAIN_FULLSEMVER=$(cat gitversion-main.json | grep -o '"FullSemVer":"[^"]*"' | cut -d'"' -f4) | ||||||||||||||||||||||||||
| MAIN_INFORMATIONAL=$(cat gitversion-main.json | grep -o '"InformationalVersion":"[^"]*"' | cut -d'"' -f4) | ||||||||||||||||||||||||||
|
Comment on lines
+139
to
+141
|
||||||||||||||||||||||||||
| MAIN_SEMVER=$(cat gitversion-main.json | grep -o '"SemVer":"[^"]*"' | cut -d'"' -f4) | |
| MAIN_FULLSEMVER=$(cat gitversion-main.json | grep -o '"FullSemVer":"[^"]*"' | cut -d'"' -f4) | |
| MAIN_INFORMATIONAL=$(cat gitversion-main.json | grep -o '"InformationalVersion":"[^"]*"' | cut -d'"' -f4) | |
| MAIN_SEMVER=$(jq -r '.SemVer' gitversion-main.json) | |
| MAIN_FULLSEMVER=$(jq -r '.FullSemVer' gitversion-main.json) | |
| MAIN_INFORMATIONAL=$(jq -r '.InformationalVersion' gitversion-main.json) |
Copilot
AI
Aug 9, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using shell text processing with grep and cut to parse JSON is fragile and error-prone. Consider using jq for reliable JSON parsing: MAIN_INFORMATIONAL=$(jq -r '.InformationalVersion' gitversion-main.json). This approach is more robust and handles edge cases better.
| MAIN_SEMVER=$(cat gitversion-main.json | grep -o '"SemVer":"[^"]*"' | cut -d'"' -f4) | |
| MAIN_FULLSEMVER=$(cat gitversion-main.json | grep -o '"FullSemVer":"[^"]*"' | cut -d'"' -f4) | |
| MAIN_INFORMATIONAL=$(cat gitversion-main.json | grep -o '"InformationalVersion":"[^"]*"' | cut -d'"' -f4) | |
| MAIN_SEMVER=$(jq -r '.SemVer' gitversion-main.json) | |
| MAIN_FULLSEMVER=$(jq -r '.FullSemVer' gitversion-main.json) | |
| MAIN_INFORMATIONAL=$(jq -r '.InformationalVersion' gitversion-main.json) |
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -20,45 +20,98 @@ function getGitVersion(): string { | |||||||||||||||
| } catch { | ||||||||||||||||
| // Fallback to simple git tag approach | ||||||||||||||||
| try { | ||||||||||||||||
| const 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(); | ||||||||||||||||
| const commits = parseInt(commitsSince, 10); | ||||||||||||||||
|
|
||||||||||||||||
| // Parse the tag version | ||||||||||||||||
| // 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('Using default fallback version: 1.0.0'); | ||||||||||||||||
| return '1.0.0'; | ||||||||||||||||
| 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); | ||||||||||||||||
|
|
||||||||||||||||
| // Simple branch-based logic | ||||||||||||||||
| // Get current branch | ||||||||||||||||
| const branch = execSync('git branch --show-current', { encoding: 'utf-8', cwd: process.cwd() }).trim(); | ||||||||||||||||
| if (branch === 'main' && commits > 0) { | ||||||||||||||||
| 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 if (commits > 0) { | ||||||||||||||||
| } else { | ||||||||||||||||
| patch += 1; | ||||||||||||||||
| const version = `${major}.${minor}.${patch}-alpha.${commits}`; | ||||||||||||||||
| console.log(`Using fallback git logic for feature branch: ${version}`); | ||||||||||||||||
| return version; | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| const version = `${major}.${minor}.${patch}`; | ||||||||||||||||
| console.log(`Using fallback git logic for tagged commit: ${version}`); | ||||||||||||||||
| return version; | ||||||||||||||||
| } catch { | ||||||||||||||||
| // No git or tags available, use default | ||||||||||||||||
| console.log('No git available, using default version: 1.0.0'); | ||||||||||||||||
| return '1.0.0'; | ||||||||||||||||
| } 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'; | ||||||||||||||||
| } | ||||||||||||||||
| } | ||||||||||||||||
| } | ||||||||||||||||
| } | ||||||||||||||||
|
|
@@ -89,10 +142,15 @@ function injectVersionIntoHtml(): void { | |||||||||||||||
| // Inject version into footer | ||||||||||||||||
| const footerRegex = /(<footer class="footer">[\s\S]*?<div class="container">[\s\S]*?<p>)/; | ||||||||||||||||
| if (footerRegex.test(htmlContent)) { | ||||||||||||||||
| htmlContent = htmlContent.replace( | ||||||||||||||||
| footerRegex, | ||||||||||||||||
| `$1\n <span class="version">v${version}</span>\n `, | ||||||||||||||||
| ); | ||||||||||||||||
| const testSitePath = process.env.TEST_SITE_PATH; | ||||||||||||||||
| let versionHtml = `\n <span class="version">v${version}</span>\n `; | ||||||||||||||||
|
|
||||||||||||||||
| // Add test site link if this is the main site build (has TEST_SITE_PATH env var) | ||||||||||||||||
| if (testSitePath) { | ||||||||||||||||
| versionHtml += `\n - preview the <a href="https://www.everytimezone.net/${testSitePath}/" target="_blank" rel="noopener noreferrer">test site</a>\n `; | ||||||||||||||||
|
Comment on lines
+149
to
+150
|
||||||||||||||||
| if (testSitePath) { | |
| versionHtml += `\n - preview the <a href="https://www.everytimezone.net/${testSitePath}/" target="_blank" rel="noopener noreferrer">test site</a>\n `; | |
| // Only allow alphanumeric, hyphens, underscores, and slashes in testSitePath | |
| if (testSitePath && /^[a-zA-Z0-9_\-\/]+$/.test(testSitePath)) { | |
| versionHtml += `\n - preview the <a href="https://www.everytimezone.net/${testSitePath}/" target="_blank" rel="noopener noreferrer">test site</a>\n `; | |
| } else if (testSitePath) { | |
| console.warn('TEST_SITE_PATH contains invalid characters and will not be included in the HTML.'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using shell text processing with
grepandcutto parse JSON is fragile and error-prone. Consider usingjqfor reliable JSON parsing:MAIN_SEMVER=$(jq -r '.SemVer' gitversion-main.json). This approach is more robust and handles edge cases better.