@vzn/vx-ci 0.0.649 → 0.0.651

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/README.md CHANGED
@@ -111,8 +111,12 @@ variables, as `github()` does on Actions. The default branch
111
111
  subgroup's project is `group/sub/app:feat-x`, the scope a laptop on
112
112
  `feat-x` derives. A merge request pipeline names its source branch
113
113
  (`CI_MERGE_REQUEST_SOURCE_BRANCH_NAME`) in the project it lives in (a
114
- fork's `CI_MERGE_REQUEST_SOURCE_PROJECT_PATH`) and its diff base
115
- (`CI_MERGE_REQUEST_DIFF_BASE_SHA`), the base of a bare `--affected`.
114
+ fork's `CI_MERGE_REQUEST_SOURCE_PROJECT_PATH`) and the base of a bare
115
+ `--affected`: its diff base (`CI_MERGE_REQUEST_DIFF_BASE_SHA`); in a
116
+ merged results pipeline the target head it merged onto
117
+ (`CI_MERGE_REQUEST_TARGET_BRANCH_SHA`), so changes the target took
118
+ since are not run again; in a merge train the car ahead (`HEAD^1`),
119
+ whose own pipeline runs its changes.
116
120
  A merge train's pipeline (`CI_MERGE_REQUEST_EVENT_TYPE=merge_train`)
117
121
  builds what lands on the target, so it is trusted: no scope. As on
118
122
  Actions, the scope keys only plugin entries. A remote reads the tag, else
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vzn/vx-ci",
3
- "version": "0.0.649",
3
+ "version": "0.0.651",
4
4
  "license": "MIT",
5
5
  "description": "GitHub Actions and GitLab CI integration for vx — a job summary on Actions and the branch cache scope on both.",
6
6
  "keywords": [
@@ -33,7 +33,7 @@
33
33
  "access": "public"
34
34
  },
35
35
  "peerDependencies": {
36
- "@vzn/vx": "^0.0.649"
36
+ "@vzn/vx": "^0.0.651"
37
37
  },
38
38
  "repository": {
39
39
  "type": "git",
package/src/gitlab.ts CHANGED
@@ -10,7 +10,8 @@ export interface GitlabPluginOptions {
10
10
  * Name the run's cache scope and base commit from GitLab's predefined
11
11
  * variables: none on the default branch or a merge train, else
12
12
  * `<project path>:<branch>`; a merge request is compared with its diff
13
- * base. The scope keys plugin entries only. `VX_CACHE_SCOPE` beats it.
13
+ * base, a merged results pipeline with the target head, a train car
14
+ * with the car ahead. The scope keys plugin entries only. `VX_CACHE_SCOPE` beats it.
14
15
  * Default: on; `false` opts out.
15
16
  */
16
17
  cacheScope?: boolean
@@ -41,7 +42,7 @@ export function gitlab(options: GitlabPluginOptions = {}): VxPlugin | undefined
41
42
  /**
42
43
  * What a GitLab CI job knows of its branch. A merge request pipeline names
43
44
  * its source branch in the project it lives in (a fork's own,
44
- * `CI_MERGE_REQUEST_SOURCE_PROJECT_PATH`) and its diff base; a merge
45
+ * `CI_MERGE_REQUEST_SOURCE_PROJECT_PATH`) and its base (`baseOf`); a merge
45
46
  * train's pipeline builds what lands on the target, so it is trusted; a
46
47
  * branch or tag pipeline names its ref, none on the default branch.
47
48
  * `refs`, what a remote reads (2026-10-25): a merge train's only its
@@ -80,8 +81,24 @@ function gitlabBranch(
80
81
  return refs.length === 0 ? facts : { ...facts, refs }
81
82
  }
82
83
 
84
+ /**
85
+ * The commit a bare `--affected` compares with. A merged results pipeline
86
+ * runs the merge onto the target's head, so it is compared with that head:
87
+ * the diff base took in every change the target got since the branch
88
+ * forked. A train's car is merged onto the car ahead (its first parent,
89
+ * GitLab's `first_parent_ref`), whose pipeline runs that car's changes.
90
+ * Any other merge request pipeline runs its source branch: the diff base.
91
+ */
92
+ function baseOf(value: (key: string) => string | undefined): string | undefined {
93
+ const event = value('CI_MERGE_REQUEST_EVENT_TYPE')
94
+ if (event === 'merge_train') return 'HEAD^1'
95
+ const diffBase = value('CI_MERGE_REQUEST_DIFF_BASE_SHA')
96
+ if (event === 'merged_result') return value('CI_MERGE_REQUEST_TARGET_BRANCH_SHA') ?? diffBase
97
+ return diffBase
98
+ }
99
+
83
100
  function scopeOf(value: (key: string) => string | undefined): BranchFacts {
84
- const base = value('CI_MERGE_REQUEST_DIFF_BASE_SHA')
101
+ const base = baseOf(value)
85
102
  const withBase = (facts: BranchFacts): BranchFacts =>
86
103
  base === undefined ? facts : { ...facts, base }
87
104
  if (value('CI_MERGE_REQUEST_EVENT_TYPE') === 'merge_train') return withBase({ trusted: true })