threadlines 0.1.18 → 0.1.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/check.js +15 -5
- package/dist/git/diff.js +14 -4
- package/dist/git/vercel-diff.js +42 -0
- package/dist/utils/context.js +15 -12
- package/dist/utils/environment.js +1 -3
- package/dist/utils/git-diff-executor.js +34 -4
- package/package.json +1 -1
package/dist/commands/check.js
CHANGED
|
@@ -126,11 +126,21 @@ async function checkCommand(options) {
|
|
|
126
126
|
gitDiff = await (0, git_diff_executor_1.getDiffForContext)(context, repoRoot, environment);
|
|
127
127
|
}
|
|
128
128
|
else {
|
|
129
|
-
// Auto-detect
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
129
|
+
// Auto-detect: Use environment-specific implementation
|
|
130
|
+
if (environment === 'vercel') {
|
|
131
|
+
// Vercel: Direct environment-based routing (single implementation)
|
|
132
|
+
console.log(chalk_1.default.gray(`📝 Collecting git changes for Vercel commit...`));
|
|
133
|
+
gitDiff = await (0, git_diff_executor_1.getDiffForEnvironment)(environment, repoRoot);
|
|
134
|
+
// Vercel uses commit context, but we don't need to create it explicitly
|
|
135
|
+
context = { type: 'commit', commitSha: process.env.VERCEL_GIT_COMMIT_SHA };
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
// Other environments: Use context-based routing (legacy)
|
|
139
|
+
context = (0, context_1.detectContext)(environment);
|
|
140
|
+
const contextDesc = (0, git_diff_executor_1.getContextDescription)(context);
|
|
141
|
+
console.log(chalk_1.default.gray(`📝 Collecting git changes for ${contextDesc}...`));
|
|
142
|
+
gitDiff = await (0, git_diff_executor_1.getDiffForContext)(context, repoRoot, environment);
|
|
143
|
+
}
|
|
134
144
|
}
|
|
135
145
|
// 3. Collect metadata (commit SHA, commit message, PR title)
|
|
136
146
|
const metadata = await (0, metadata_1.collectMetadata)(context, environment, repoRoot);
|
package/dist/git/diff.js
CHANGED
|
@@ -96,8 +96,9 @@ async function getBranchDiff(repoRoot, branchName, baseBranch) {
|
|
|
96
96
|
// Helper function to detect base branch
|
|
97
97
|
// Returns the branch name to use in git commands (may be local or remote)
|
|
98
98
|
// In CI environments, prioritizes remote refs since local branches often don't exist
|
|
99
|
+
// Note: Vercel is excluded here because it uses commit context, not branch context
|
|
99
100
|
async function detectBaseBranch(git, branchName) {
|
|
100
|
-
const isCI = !!(process.env.CI || process.env.GITHUB_ACTIONS || process.env.
|
|
101
|
+
const isCI = !!(process.env.CI || process.env.GITHUB_ACTIONS || process.env.GITLAB_CI);
|
|
101
102
|
// Strategy 1: Try upstream tracking branch (most reliable if set)
|
|
102
103
|
try {
|
|
103
104
|
const upstream = await git.revparse(['--abbrev-ref', '--symbolic-full-name', `${branchName}@{u}`]);
|
|
@@ -156,15 +157,15 @@ async function getBranchDiff(repoRoot, branchName, baseBranch) {
|
|
|
156
157
|
catch (error) {
|
|
157
158
|
console.log(`[DEBUG] Default branch (refs/remotes/origin/HEAD) not configured: ${error.message || 'not found'}`);
|
|
158
159
|
}
|
|
159
|
-
// Strategy 3: Try common branch names by checking remote refs first
|
|
160
|
+
// Strategy 3: Try common branch names by checking remote refs first, then local branches
|
|
160
161
|
// This works reliably in CI with fetch-depth: 0, and also works locally
|
|
161
162
|
const commonBases = ['main', 'master', 'develop'];
|
|
162
163
|
for (const candidate of commonBases) {
|
|
163
164
|
if (candidate.toLowerCase() === branchName.toLowerCase()) {
|
|
164
165
|
continue; // Skip if it's the same branch
|
|
165
166
|
}
|
|
167
|
+
// Try remote ref first
|
|
166
168
|
try {
|
|
167
|
-
// Always check remote ref first (this is reliable in CI with fetch-depth: 0)
|
|
168
169
|
await git.revparse([`origin/${candidate}`]);
|
|
169
170
|
// In CI, prefer remote refs since local branches often don't exist
|
|
170
171
|
if (isCI) {
|
|
@@ -184,7 +185,16 @@ async function getBranchDiff(repoRoot, branchName, baseBranch) {
|
|
|
184
185
|
}
|
|
185
186
|
catch (error) {
|
|
186
187
|
console.log(`[DEBUG] Remote branch 'origin/${candidate}' not found: ${error.message || 'does not exist'}`);
|
|
187
|
-
//
|
|
188
|
+
// If remote doesn't exist, also try local branch (especially for CI like Vercel)
|
|
189
|
+
try {
|
|
190
|
+
await git.revparse([candidate]);
|
|
191
|
+
console.log(`[DEBUG] Remote 'origin/${candidate}' not available, but local branch '${candidate}' found - using local`);
|
|
192
|
+
return candidate;
|
|
193
|
+
}
|
|
194
|
+
catch (localError) {
|
|
195
|
+
console.log(`[DEBUG] Local branch '${candidate}' also not found: ${localError.message || 'does not exist'}`);
|
|
196
|
+
// Continue to next candidate
|
|
197
|
+
}
|
|
188
198
|
}
|
|
189
199
|
}
|
|
190
200
|
// All strategies failed - provide clear error with context
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.getVercelDiff = getVercelDiff;
|
|
7
|
+
const simple_git_1 = __importDefault(require("simple-git"));
|
|
8
|
+
/**
|
|
9
|
+
* Get diff for Vercel CI environment
|
|
10
|
+
*
|
|
11
|
+
* Vercel provides VERCEL_GIT_COMMIT_SHA which contains the commit being deployed.
|
|
12
|
+
* This function gets the diff for that specific commit using git show.
|
|
13
|
+
*
|
|
14
|
+
* This is the ONLY implementation for Vercel - no fallbacks, no alternatives.
|
|
15
|
+
* If this doesn't work, we fail with a clear error.
|
|
16
|
+
*/
|
|
17
|
+
async function getVercelDiff(repoRoot) {
|
|
18
|
+
const git = (0, simple_git_1.default)(repoRoot);
|
|
19
|
+
// Check if we're in a git repo
|
|
20
|
+
const isRepo = await git.checkIsRepo();
|
|
21
|
+
if (!isRepo) {
|
|
22
|
+
throw new Error('Not a git repository. Threadline requires a git repository.');
|
|
23
|
+
}
|
|
24
|
+
// Get commit SHA from Vercel environment variable
|
|
25
|
+
const commitSha = process.env.VERCEL_GIT_COMMIT_SHA;
|
|
26
|
+
if (!commitSha) {
|
|
27
|
+
throw new Error('VERCEL_GIT_COMMIT_SHA environment variable is not set. ' +
|
|
28
|
+
'This should be automatically provided by Vercel CI.');
|
|
29
|
+
}
|
|
30
|
+
// Get diff using git show - this is the ONLY way we get diff in Vercel
|
|
31
|
+
const diff = await git.show([commitSha, '--format=', '--no-color', '-U200']);
|
|
32
|
+
// Get changed files using git show --name-only
|
|
33
|
+
const commitFiles = await git.show([commitSha, '--name-only', '--format=', '--pretty=format:']);
|
|
34
|
+
const changedFiles = commitFiles
|
|
35
|
+
.split('\n')
|
|
36
|
+
.filter(line => line.trim().length > 0)
|
|
37
|
+
.map(line => line.trim());
|
|
38
|
+
return {
|
|
39
|
+
diff: diff || '',
|
|
40
|
+
changedFiles
|
|
41
|
+
};
|
|
42
|
+
}
|
package/dist/utils/context.js
CHANGED
|
@@ -29,9 +29,6 @@ function detectContext(environment) {
|
|
|
29
29
|
return detectVercelContext();
|
|
30
30
|
case 'local':
|
|
31
31
|
return { type: 'local' };
|
|
32
|
-
case 'azure-devops':
|
|
33
|
-
// Future: return detectAzureDevOpsContext();
|
|
34
|
-
return { type: 'local' };
|
|
35
32
|
default:
|
|
36
33
|
return { type: 'local' };
|
|
37
34
|
}
|
|
@@ -124,22 +121,28 @@ function detectGitLabContext() {
|
|
|
124
121
|
* Environment Variables:
|
|
125
122
|
* - Branch: VERCEL_GIT_COMMIT_REF
|
|
126
123
|
* - Commit: VERCEL_GIT_COMMIT_SHA
|
|
124
|
+
*
|
|
125
|
+
* Vercel Limitation:
|
|
126
|
+
* Vercel performs shallow clones of the repository, typically fetching only the
|
|
127
|
+
* specific commit being deployed. The git repository in Vercel's build environment
|
|
128
|
+
* does not contain the full git history or remote branch references (e.g., origin/main).
|
|
129
|
+
* This means branch-based diff operations (comparing feature branch against base branch)
|
|
130
|
+
* are not possible because the base branch refs are not available in the repository.
|
|
131
|
+
*
|
|
132
|
+
* Solution:
|
|
133
|
+
* We hardcode commit context for Vercel, using VERCEL_GIT_COMMIT_SHA to get a
|
|
134
|
+
* commit-based diff (comparing the commit against its parent). This works within
|
|
135
|
+
* Vercel's constraints since we only need the commit SHA, not branch references.
|
|
127
136
|
*/
|
|
128
137
|
function detectVercelContext() {
|
|
129
|
-
//
|
|
130
|
-
|
|
131
|
-
return {
|
|
132
|
-
type: 'branch',
|
|
133
|
-
branchName: process.env.VERCEL_GIT_COMMIT_REF
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
// 2. Check for commit context
|
|
138
|
+
// Hardcode commit context for Vercel due to shallow clone limitations
|
|
139
|
+
// Vercel's git repository doesn't have base branch refs available
|
|
137
140
|
if (process.env.VERCEL_GIT_COMMIT_SHA) {
|
|
138
141
|
return {
|
|
139
142
|
type: 'commit',
|
|
140
143
|
commitSha: process.env.VERCEL_GIT_COMMIT_SHA
|
|
141
144
|
};
|
|
142
145
|
}
|
|
143
|
-
//
|
|
146
|
+
// Fallback to local
|
|
144
147
|
return { type: 'local' };
|
|
145
148
|
}
|
|
@@ -15,8 +15,7 @@ exports.isCIEnvironment = isCIEnvironment;
|
|
|
15
15
|
* 1. Vercel: VERCEL=1
|
|
16
16
|
* 2. GitHub Actions: GITHUB_ACTIONS=1
|
|
17
17
|
* 3. GitLab CI: GITLAB_CI=1 or (CI=1 + CI_COMMIT_SHA)
|
|
18
|
-
* 4.
|
|
19
|
-
* 5. Local: None of the above
|
|
18
|
+
* 4. Local: None of the above
|
|
20
19
|
*/
|
|
21
20
|
function detectEnvironment() {
|
|
22
21
|
if (process.env.VERCEL)
|
|
@@ -25,7 +24,6 @@ function detectEnvironment() {
|
|
|
25
24
|
return 'github';
|
|
26
25
|
if (process.env.GITLAB_CI || (process.env.CI && process.env.CI_COMMIT_SHA))
|
|
27
26
|
return 'gitlab';
|
|
28
|
-
// Future: if (process.env.TF_BUILD) return 'azure-devops';
|
|
29
27
|
return 'local';
|
|
30
28
|
}
|
|
31
29
|
/**
|
|
@@ -2,19 +2,49 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Git Diff Execution
|
|
4
4
|
*
|
|
5
|
-
* Executes the appropriate git diff function based on
|
|
6
|
-
*
|
|
7
|
-
* handle environment-specific details (like base branch detection).
|
|
5
|
+
* Executes the appropriate git diff function based on environment.
|
|
6
|
+
* Each environment has ONE SINGLE IMPLEMENTATION - no fallbacks, no alternatives.
|
|
8
7
|
*/
|
|
9
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.getDiffForEnvironment = getDiffForEnvironment;
|
|
10
10
|
exports.getDiffForContext = getDiffForContext;
|
|
11
11
|
exports.getContextDescription = getContextDescription;
|
|
12
12
|
const diff_1 = require("../git/diff");
|
|
13
|
+
const vercel_diff_1 = require("../git/vercel-diff");
|
|
14
|
+
/**
|
|
15
|
+
* Executes the appropriate git diff function based on environment.
|
|
16
|
+
*
|
|
17
|
+
* Each environment has a single, specific implementation:
|
|
18
|
+
* - Vercel: Uses VERCEL_GIT_COMMIT_SHA, gets commit diff via git show
|
|
19
|
+
* - GitHub: Uses branch/PR context with base branch detection
|
|
20
|
+
* - GitLab: Uses branch/MR context with base branch detection
|
|
21
|
+
* - Local: Uses staged/unstaged changes
|
|
22
|
+
*
|
|
23
|
+
* No fallbacks - if the environment-specific implementation fails, we fail clearly.
|
|
24
|
+
*/
|
|
25
|
+
async function getDiffForEnvironment(environment, repoRoot, context) {
|
|
26
|
+
switch (environment) {
|
|
27
|
+
case 'vercel':
|
|
28
|
+
// Vercel: Single implementation using commit SHA
|
|
29
|
+
return await (0, vercel_diff_1.getVercelDiff)(repoRoot);
|
|
30
|
+
case 'github':
|
|
31
|
+
case 'gitlab':
|
|
32
|
+
case 'local':
|
|
33
|
+
// For other environments, use context-based routing (legacy, will be refactored)
|
|
34
|
+
if (!context) {
|
|
35
|
+
throw new Error(`Context required for ${environment} environment`);
|
|
36
|
+
}
|
|
37
|
+
return await getDiffForContext(context, repoRoot, environment);
|
|
38
|
+
default:
|
|
39
|
+
const _exhaustive = environment;
|
|
40
|
+
throw new Error(`Unknown environment: ${_exhaustive}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
13
43
|
/**
|
|
14
44
|
* Executes the appropriate git diff function based on context.
|
|
15
45
|
*
|
|
46
|
+
* This is the legacy context-based routing. New code should use getDiffForEnvironment().
|
|
16
47
|
* This function maps context types to their corresponding git diff functions.
|
|
17
|
-
* The actual git diff functions handle environment-specific details internally.
|
|
18
48
|
*/
|
|
19
49
|
async function getDiffForContext(context, repoRoot, environment) {
|
|
20
50
|
switch (context.type) {
|