Redirect legacy page names to the new routes (v0.9.4)

The retired legacy instance now blanket-redirects its old host to the new
one, so pre-rewrite deep links like /index.html or /branches.html arrive
here — they answer 301 to the new routes instead of 404; about/license had
no successor pages and land on the start page.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
mhoennig
2026-08-10 16:55:11 +02:00
co-authored by Claude Fable 5
parent fbdc6f54b7
commit eb49387c97
3 changed files with 40 additions and 1 deletions
+1 -1
View File
@@ -11,7 +11,7 @@ plugins {
group = "de.hoennig"
// bump at least the patch version for every deployment, so the UI footer
// (BuildProperties) and --version identify what is actually running
version = "0.9.3"
version = "0.9.4"
java {
toolchain {
@@ -7,6 +7,7 @@ import de.hoennig.gittally.build.BuildResultRepository
import de.hoennig.gittally.build.BuildStatus
import de.hoennig.gittally.config.ConfigLoader
import de.hoennig.gittally.metrics.SystemMetricsCollector
import jakarta.servlet.http.HttpServletRequest
import org.springframework.beans.factory.ObjectProvider
import org.springframework.boot.info.BuildProperties
import org.springframework.http.HttpStatus
@@ -15,6 +16,7 @@ import org.springframework.ui.Model
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.server.ResponseStatusException
import org.springframework.web.servlet.view.RedirectView
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths
@@ -41,6 +43,16 @@ class UiController(
) {
var workingDir: Path = Paths.get(".")
/**
* Permanent redirects for the legacy script's static page names, so bookmarks
* and links from before the rewrite (e.g. via the old host's redirect) keep working.
*/
@GetMapping("/index.html", "/branches.html", "/history.html", "/system.html", "/about.html", "/license.html")
fun legacyPageName(request: HttpServletRequest): RedirectView =
RedirectView(LEGACY_PAGE_TARGETS.getValue(request.requestURI)).apply {
setStatusCode(HttpStatus.MOVED_PERMANENTLY)
}
@GetMapping("/")
fun latest(model: Model): String {
val links = baseModel(model, view = "latest", pageTitle = "Latest Builds")
@@ -256,5 +268,16 @@ class UiController(
companion object {
private val FAILURES_COUNTER = Regex("""id="failures">\s*<div class="counter">(\d+)""")
/** Legacy page name → new route; about/license had no successor pages and land on the start page. */
private val LEGACY_PAGE_TARGETS =
mapOf(
"/index.html" to "/",
"/branches.html" to "/branches",
"/history.html" to "/history",
"/system.html" to "/system",
"/about.html" to "/",
"/license.html" to "/",
)
}
}
@@ -28,6 +28,7 @@ import org.springframework.http.HttpStatus
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.content
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.header
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status
import org.springframework.web.server.ResponseStatusException
import java.nio.file.Files
@@ -270,6 +271,21 @@ class UiControllerTest : FunSpec() {
Regex(""" failed</span>""").findAll(page).count() shouldBe 1
}
test("legacy page names redirect permanently to the new routes") {
mockMvc
.perform(get("/index.html"))
.andExpect(status().isMovedPermanently)
.andExpect(header().string("Location", "/"))
mockMvc
.perform(get("/branches.html"))
.andExpect(status().isMovedPermanently)
.andExpect(header().string("Location", "/branches"))
mockMvc
.perform(get("/history.html"))
.andExpect(status().isMovedPermanently)
.andExpect(header().string("Location", "/history"))
}
test("artifact index of a pruned build explains the missing artifacts") {
every { repository.history() } returns listOf(successResult)
every { artifactStore.artifactDir("main-abc123-key") } returns null