|
23 | 23 | import javax.inject.Named; |
24 | 24 |
|
25 | 25 | import java.io.File; |
| 26 | +import java.io.IOException; |
26 | 27 | import java.nio.file.Path; |
27 | 28 | import java.util.HashSet; |
28 | 29 | import java.util.List; |
@@ -142,33 +143,58 @@ public void execute( |
142 | 143 |
|
143 | 144 | boolean restorable = result.isSuccess() || result.isPartialSuccess(); |
144 | 145 | boolean restored = false; // if partially restored need to save increment |
| 146 | + |
145 | 147 | if (restorable) { |
146 | 148 | CacheRestorationStatus cacheRestorationStatus = |
147 | 149 | restoreProject(result, mojoExecutions, mojoExecutionRunner, cacheConfig); |
148 | 150 | restored = CacheRestorationStatus.SUCCESS == cacheRestorationStatus; |
149 | 151 | executeExtraCleanPhaseIfNeeded(cacheRestorationStatus, cleanPhase, mojoExecutionRunner); |
150 | 152 | } |
151 | | - if (!restored) { |
152 | | - for (MojoExecution mojoExecution : mojoExecutions) { |
153 | | - if (source == Source.CLI |
154 | | - || mojoExecution.getLifecyclePhase() == null |
155 | | - || lifecyclePhasesHelper.isLaterPhaseThanClean(mojoExecution.getLifecyclePhase())) { |
156 | | - mojoExecutionRunner.run(mojoExecution); |
| 153 | + |
| 154 | + try { |
| 155 | + if (!restored && !forkedExecution) { |
| 156 | + // Move pre-existing artifacts to staging directory to prevent caching stale files |
| 157 | + // from previous builds (e.g., after source changes or from cache restored |
| 158 | + // with clock skew). This ensures save() only sees fresh files built during this session. |
| 159 | + // Skip for forked executions since they don't cache and shouldn't modify artifacts. |
| 160 | + try { |
| 161 | + cacheController.stagePreExistingArtifacts(session, project); |
| 162 | + } catch (IOException e) { |
| 163 | + LOGGER.debug("Failed to stage pre-existing artifacts: {}", e.getMessage()); |
| 164 | + // Continue build - if staging fails, we'll just cache what exists |
157 | 165 | } |
158 | 166 | } |
159 | | - } |
160 | 167 |
|
161 | | - if (cacheState == INITIALIZED && (!result.isSuccess() || !restored)) { |
162 | | - if (cacheConfig.isSkipSave()) { |
163 | | - LOGGER.info("Cache saving is disabled."); |
164 | | - } else if (cacheConfig.isMandatoryClean() |
165 | | - && lifecyclePhasesHelper |
166 | | - .getCleanSegment(project, mojoExecutions) |
167 | | - .isEmpty()) { |
168 | | - LOGGER.info("Cache storing is skipped since there was no \"clean\" phase."); |
169 | | - } else { |
170 | | - final Map<String, MojoExecutionEvent> executionEvents = mojoListener.getProjectExecutions(project); |
171 | | - cacheController.save(result, mojoExecutions, executionEvents); |
| 168 | + if (!restored) { |
| 169 | + for (MojoExecution mojoExecution : mojoExecutions) { |
| 170 | + if (source == Source.CLI |
| 171 | + || mojoExecution.getLifecyclePhase() == null |
| 172 | + || lifecyclePhasesHelper.isLaterPhaseThanClean(mojoExecution.getLifecyclePhase())) { |
| 173 | + mojoExecutionRunner.run(mojoExecution); |
| 174 | + } |
| 175 | + } |
| 176 | + } |
| 177 | + |
| 178 | + if (cacheState == INITIALIZED && (!result.isSuccess() || !restored)) { |
| 179 | + if (cacheConfig.isSkipSave()) { |
| 180 | + LOGGER.debug("Cache saving is disabled."); |
| 181 | + } else if (cacheConfig.isMandatoryClean() |
| 182 | + && lifecyclePhasesHelper |
| 183 | + .getCleanSegment(project, mojoExecutions) |
| 184 | + .isEmpty()) { |
| 185 | + LOGGER.debug("Cache storing is skipped since there was no \"clean\" phase."); |
| 186 | + } else { |
| 187 | + final Map<String, MojoExecutionEvent> executionEvents = |
| 188 | + mojoListener.getProjectExecutions(project); |
| 189 | + cacheController.save(result, mojoExecutions, executionEvents); |
| 190 | + } |
| 191 | + } |
| 192 | + } finally { |
| 193 | + // Always restore staged files after build completes (whether save ran or not). |
| 194 | + // Files that were rebuilt are discarded; files that weren't rebuilt are restored. |
| 195 | + // Skip for forked executions since they don't stage artifacts. |
| 196 | + if (!restored && !forkedExecution) { |
| 197 | + cacheController.restoreStagedArtifacts(session, project); |
172 | 198 | } |
173 | 199 | } |
174 | 200 |
|
|
0 commit comments