This is an automated email from the ASF dual-hosted git repository.
dspavlov pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite-teamcity-bot.git
The following commit(s) were added to refs/heads/master by this push:
new 5a8889d7 IGNITE-28729: Treat 403 as permanent failure (#237)
5a8889d7 is described below
commit 5a8889d7ccdca75c97eeb09e4512275ea65c5bbc
Author: ignitetcbot <[email protected]>
AuthorDate: Thu May 28 11:25:58 2026 +0300
IGNITE-28729: Treat 403 as permanent failure (#237)
Codex co-authored-by: Dmitriy Pavlov <[email protected]>
---
.../IgnitedTcInMemoryIntegrationTest.java | 42 ++++++++++++++++++++++
.../tcignited/build/ProactiveFatBuildSync.java | 20 ++++++++++-
2 files changed, 61 insertions(+), 1 deletion(-)
diff --git
a/ignite-tc-helper-web/src/test/java/org/apache/ignite/tcignited/IgnitedTcInMemoryIntegrationTest.java
b/ignite-tc-helper-web/src/test/java/org/apache/ignite/tcignited/IgnitedTcInMemoryIntegrationTest.java
index 46cba821..8a90f646 100644
---
a/ignite-tc-helper-web/src/test/java/org/apache/ignite/tcignited/IgnitedTcInMemoryIntegrationTest.java
+++
b/ignite-tc-helper-web/src/test/java/org/apache/ignite/tcignited/IgnitedTcInMemoryIntegrationTest.java
@@ -735,6 +735,48 @@ public class IgnitedTcInMemoryIntegrationTest {
assertTrue(checkNotNull(running4).isEmpty());
}
+ @Test
+ public void testForbiddenBuildAccessCreatesPermanentFakeBuild() {
+ TeamcityIgnitedModule module = new TeamcityIgnitedModule();
+ module.overrideHttp((basicAuthTok, url) -> {
+ throw new IllegalStateException("Service " + url + " returned
Invalid Response Code : 403:\n" +
+ "HTTP 403 | Host: ci2.ignite.apache.org | " + url + "\n" +
+ "Not enough permissions to access build");
+ });
+ Injector injector = Guice.createInjector(module, new
IgniteAndSchedulerTestModule());
+
+ IStringCompactor c = injector.getInstance(IStringCompactor.class);
+ BuildRefDao buildRefDao =
injector.getInstance(BuildRefDao.class).init();
+ FatBuildDao fatBuildDao =
injector.getInstance(FatBuildDao.class).init();
+
+ int buildId = 1000044;
+ BuildRef ref = new BuildRef();
+ ref.buildTypeId = "Testbuild";
+ ref.branchName = ITeamcity.REFS_HEADS_MASTER;
+ ref.state = BuildRef.STATE_FINISHED;
+ ref.status = BuildRef.STATUS_SUCCESS;
+ ref.setId(buildId);
+
+ String srvCode = APACHE;
+ int srvIdInt = ITeamcityIgnited.serverIdToInt(srvCode);
+ final TeamcityServiceConnection srvConn =
injector.getInstance(TeamcityServiceConnection.class);
+ srvConn.init(srvCode);
+
+ buildRefDao.saveChunk(srvIdInt, Lists.newArrayList(ref));
+
+ assertTrue(fatBuildDao.getMissingBuilds(srvIdInt, new int[]
{buildId}).contains(buildId));
+
+ ProactiveFatBuildSync buildSync =
injector.getInstance(ProactiveFatBuildSync.class);
+ buildSync.ensureActualizationRequested(srvCode, srvConn);
+
+ FatBuildCompacted fatBuild = fatBuildDao.getFatBuild(srvIdInt,
buildId);
+
+ assertNotNull(fatBuild);
+ assertTrue(fatBuild.isFakeStub());
+ assertTrue(fatBuild.isCancelled(c));
+ assertTrue(fatBuildDao.getMissingBuilds(srvIdInt, new int[]
{buildId}).isEmpty());
+ }
+
public void putOldFashionFakeBuild(IStringCompactor c, FatBuildDao
fatBuildDao, int buildId, int srvIdInt) {
FatBuildCompacted fb = fatBuildDao.getFatBuild(srvIdInt, buildId);
diff --git
a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/build/ProactiveFatBuildSync.java
b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/build/ProactiveFatBuildSync.java
index 8eb33d6b..a024ba37 100644
---
a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/build/ProactiveFatBuildSync.java
+++
b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/build/ProactiveFatBuildSync.java
@@ -419,7 +419,8 @@ public class ProactiveFatBuildSync {
catch (Exception e) {
Throwable cause = Throwables.getRootCause(e);
- if (cause instanceof FileNotFoundException || cause instanceof
ServiceConflictException) {
+ if (cause instanceof FileNotFoundException || cause instanceof
ServiceConflictException ||
+ isPermanentBuildAccessDenied(e)) {
logger.info("Loading build [" + buildId + "] for server [" +
srvName + "] failed:" + e.getMessage(), e);
if (existingBuild != null) {
@@ -456,6 +457,23 @@ public class ProactiveFatBuildSync {
return fatBuildDao.saveBuild(srvIdMask, buildId, build, tests,
problems, statistics, changesList, existingBuild);
}
+ private boolean isPermanentBuildAccessDenied(Throwable e) {
+ for (Throwable cur = e; cur != null; cur = cur.getCause()) {
+ String msg = cur.getMessage();
+
+ if (msg == null)
+ continue;
+
+ String msgLower = msg.toLowerCase();
+
+ if (msgLower.contains("403") && msgLower.contains("not enough
permissions") &&
+ msgLower.contains("access build"))
+ return true;
+ }
+
+ return false;
+ }
+
@Nullable
public FatBuildCompacted transformV5Build(int srvIdMask, int buildId,
@Nonnull FatBuildCompacted existingBuild) {
if (Objects.equals(buildId, existingBuild.id())) {