Renaming gitTally to Werkator because there is another git-related tool named gittally (#1)
* renaming from gitTally to Werkator * Rename GitTally to Werkator `gitTally` is the name of another product in the git space, so the rename is a precaution; nothing about what the build system does changes. The name follows one rule: `Werkator` where it is prose, capitalized where it is a Kotlin type and its file, lowercase everywhere a machine reads it — the command, packages, paths, configuration keys and values, the Gitea check context. Environment variables keep their convention and are uppercase throughout. Every configuration file is still found under its pre-rename name (`ConfigFiles`): `.gittally.yml` at the repository root, in a build worktree and as committed on a branch, `.git/gittally/.gittally.yml` for the machine layer. The current name wins where both exist, and the old file is then ignored rather than merged — two files side by side are a half-done rename, not a layering. Without the fallback an installation that updated without renaming would not fail: a configuration that is not found leaves every setting at its default, so it would come up looking healthy while having forgotten its credentials and its builds. `docs/werkator-migrationsplan.md` lists what the fallback does not cover and has to be moved by hand — above all the state directory `.git/werkator/`, which holds the build history, the control token and the worktrees, and has no fallback of its own. `docs/migration-from-legacy.md` is deleted with this: it mapped the legacy script's environment variables, and every host it addressed has long since moved to the YAML configuration. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Move the pre-rename state directory at the first start The configuration is found under either name, the state is not: build history, control token, auto-build slots and worktrees live at one fixed path. An installation that updates without moving `.git/gittally` would not fail — it would come up with an empty history and a fresh control token, quietly. So the first start moves it instead of the release notes asking for it. Only when the old directory exists and the new one does not. Where both exist nothing is touched and a warning names the leftover: which of the two is the live state is not something to guess. A failed move is an error in the log, never an abort — a CI must not hang on it. The worktrees are dropped rather than moved, since they point at their old path in both directions; `GitWorktreeWorkspaces` prunes the stale admin entry and recreates each on its branch's next build. A generated systemd unit moves with the directory and leaves its symlink dangling, which is warned about — the running service is unaffected, the next start is not. Runs from `CliRunner`, before any command resolves a path under the directory, and so before the second context of `server` exists. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Document PR#1: the rename to Werkator Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Drop the legacy env-to-YAML conversion from the setup tool The old bash script configured itself through `GITTALLY_*` environment variables. The blanket rename rewrote those literals, so the converter was looking for `WERKATOR_*` — a spelling no host has ever written. Fed a real legacy file it would have found nothing and written an almost empty configuration, without an error, which is the same silent failure this rename is otherwise careful to avoid. The conversion has served its purpose with the vm2176 to vm4006 migration, so it goes instead of being repaired. What remains is the setup of a new instance: the preconditions, the credential prompt, and the machine configuration written mode 600 — now carrying the host's public URL as well, since that is host-specific too. Everything the repository builds comes from `init` and its templates. It also stops emitting a legacy `branches:` section, which step 18 is about to reject outright. `docs/plan/00-legacy-analysis.md` and `13-nginx-tls.md` get the real `GITTALLY_*` spelling back: they record what the old script read. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Describe this repository's build with a build definition Its own `.werkator.yml` still used the deprecated `branches` section with an `autoBuild` schedule that was switched off. That section is read only while nothing defines a build at all, and step 18 rejects it by name — so this repository would have blocked the precondition of that step, which asks that no configuration still in play carries it. Nothing about the build changes: `builds.default` with `trigger.onPush` is a build of every new commit on every branch, which is what the branch section said. `config:print --full` resolves the definition completely and logs no deprecation warning any more. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Stop documenting the pre-rename fallback for users Exactly one repository is configured with the old names, and it is migrated by hand in the same move as this release. The fallback is therefore a transition of days, not a feature anyone reading the release notes or the configuration reference has to plan around. Removed from `releases.html` and `docs/configuration.md`. The mechanism itself is unchanged and stays described where it is worked on: in `ConfigFiles`, in `StateDirMigration`, and in the migration plan. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Bring the PR-doc to its final state The `statusContext` question is answered and marked as decided rather than left standing: it is the one value a human reads as a label, and it stays lowercase because Gitea matches it and the client reads it back, which makes it a value. Also records that the pre-rename fallback is deliberately absent from the release notes and the configuration reference. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Release v1.0.0: Werkator The release after 0.9.21 is 1.0.0, because a product that changes its name is better off counting from one under it. The release note says as much, so the jump is not read as a claim about maturity — plan steps 14, 17 and 18 are still open. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Correct the PR-doc about the version It claimed the PR carries no version bump, which the release commit made untrue, and records why the number is 1.0.0 instead of 0.9.22. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Point the legacy references at the history `legacy/gitTally` was removed from the tree with the rename, but the README still described it as a reference kept in the repository, and the plan told an executing session to read parts of it — including step 14, which is open. The README section is gone; `docs/plan/README.md`, step 14 and the legacy analysis now say where the script actually is (`git show 7f55068^:legacy/gitTally`). Executed steps and ADR 0004 keep their wording: they record what was true when they ran. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Retarget the links in the historic PR-docs The package rename moved every file the older PR-docs link to, leaving 60 dead links. Only the link targets are rewritten, never the visible text and never a statement: those documents record what was true when they were written, GitTally in the prose included. A snapshot may be outdated; it should still be navigable. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Add the v1.0.0 deployment procedure for vm4006 Measured, not estimated: the state directory is 878 MB, of which 878 MB are the nine build worktrees. What cannot be recreated is 84 KB, so the snapshot before an in-place switch is instant and the rollback is one sequence of moves. Records the three expected non-failures — a cold Gradle volume, one image rebuild, containers left under the old label — and that `gitea.statusContext` needs no attention because it comes from the watched repository's committed configuration. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Rename the machine configuration along with its directory Found by the deployment to vm4006: the move renames the directory and leaves the file inside it alone, so the machine configuration ended up at `.git/werkator/.gittally.yml` — a pair of names the lookup did not expect, because it pairs directory and file name. The instance resolved empty credentials, no public URL and none of the host's build definitions, and said nothing about it. That is the exact failure this change exists to prevent, produced by the change itself. `StateDirMigration` now renames the configuration with the directory, unless one under the current name is already there. `ConfigFiles` carries `.git/werkator/.gittally.yml` as a third candidate as well, for a directory somebody moved by hand, where the migration never runs and so can rename nothing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Let init see a configuration under its previous name `init --systemd` runs `init`, and its "already exists" check knew only the current name. On the one repository still carrying `.gittally.yml` it therefore wrote a fresh template `.werkator.yml` beside it — and since the current name wins, that repository would have built the template's `./gradlew test` instead of what its own configuration says. Found on vm4006, where the file was created in the watched working tree and removed again by hand. Both checks now ask `ConfigFiles`, so init decides existence by the same rule the loader uses to read. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Record the v1.0.0 deployment to vm4006 Deployed from the branch as the final test of PR#1, and it did what a final test is for: it found two silent-failure defects before the service was started, both fixed and redeployed in the same window. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Drop the control token left under the old localStorage key The key is named after the product, so the rename left every browser with a token under `gittally.controlToken`, which nothing reads any more and which "forget token" can no longer reach. It is a write-scope token in a browser store, not a password, but a secret nobody owns is worth one line to remove. Removed on load. The token on the server is unchanged, so re-entering it once per browser is all the rename costs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
4d76744721
commit
d0169e57bc
+5
-5
@@ -1,8 +1,8 @@
|
||||
package de.hoennig.gittally
|
||||
package de.hoennig.werkator
|
||||
|
||||
import de.hoennig.gittally.commands.ConfigPrintCommand
|
||||
import de.hoennig.gittally.commands.InitCommand
|
||||
import de.hoennig.gittally.commands.ServerCommand
|
||||
import de.hoennig.werkator.commands.ConfigPrintCommand
|
||||
import de.hoennig.werkator.commands.InitCommand
|
||||
import de.hoennig.werkator.commands.ServerCommand
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.shouldNotBe
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
@@ -11,7 +11,7 @@ import org.springframework.boot.test.context.SpringBootTest
|
||||
@SpringBootTest
|
||||
class ApplicationContextTest : FunSpec() {
|
||||
@Autowired
|
||||
lateinit var rootCommand: GitTallyCommand
|
||||
lateinit var rootCommand: WerkatorCommand
|
||||
|
||||
@Autowired
|
||||
lateinit var initCommand: InitCommand
|
||||
+3
-3
@@ -1,8 +1,8 @@
|
||||
package de.hoennig.gittally
|
||||
package de.hoennig.werkator
|
||||
|
||||
import com.ninjasquad.springmockk.MockkBean
|
||||
import de.hoennig.gittally.metrics.SystemMetricsCollector
|
||||
import de.hoennig.gittally.watcher.Watcher
|
||||
import de.hoennig.werkator.metrics.SystemMetricsCollector
|
||||
import de.hoennig.werkator.watcher.Watcher
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.booleans.shouldBeTrue
|
||||
import io.mockk.verify
|
||||
@@ -0,0 +1,81 @@
|
||||
package de.hoennig.werkator
|
||||
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.booleans.shouldBeFalse
|
||||
import io.kotest.matchers.booleans.shouldBeTrue
|
||||
import io.kotest.matchers.shouldBe
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
|
||||
class StateDirMigrationTest : FunSpec() {
|
||||
private fun repoWithLegacyState(): Path {
|
||||
val dir = Files.createTempDirectory("werkator-state")
|
||||
Files.createDirectories(dir.resolve(".git/gittally"))
|
||||
dir.resolve(".git/gittally/build-results.json").toFile().writeText("[]")
|
||||
return dir
|
||||
}
|
||||
|
||||
init {
|
||||
test("moves the pre-rename state directory to its current path") {
|
||||
val dir = repoWithLegacyState()
|
||||
|
||||
StateDirMigration.migrateIfNeeded(dir)
|
||||
|
||||
Files.exists(dir.resolve(".git/gittally")).shouldBeFalse()
|
||||
dir.resolve(".git/werkator/build-results.json").toFile().readText() shouldBe "[]"
|
||||
}
|
||||
|
||||
test("renames the machine configuration inside the moved directory") {
|
||||
val dir = repoWithLegacyState()
|
||||
dir.resolve(".git/gittally/.gittally.yml").toFile().writeText("git:\n account: ci-user\n")
|
||||
|
||||
StateDirMigration.migrateIfNeeded(dir)
|
||||
|
||||
Files.exists(dir.resolve(".git/werkator/.gittally.yml")).shouldBeFalse()
|
||||
dir.resolve(".git/werkator/.werkator.yml").toFile().readText() shouldBe "git:\n account: ci-user\n"
|
||||
}
|
||||
|
||||
test("never overwrites a machine configuration that already carries the current name") {
|
||||
val dir = repoWithLegacyState()
|
||||
dir.resolve(".git/gittally/.gittally.yml").toFile().writeText("git:\n account: old\n")
|
||||
dir.resolve(".git/gittally/.werkator.yml").toFile().writeText("git:\n account: current\n")
|
||||
|
||||
StateDirMigration.migrateIfNeeded(dir)
|
||||
|
||||
dir.resolve(".git/werkator/.werkator.yml").toFile().readText() shouldBe "git:\n account: current\n"
|
||||
Files.exists(dir.resolve(".git/werkator/.gittally.yml")).shouldBeTrue()
|
||||
}
|
||||
|
||||
test("drops the moved worktrees, because they point at their old path") {
|
||||
val dir = repoWithLegacyState()
|
||||
Files.createDirectories(dir.resolve(".git/gittally/worktrees/main"))
|
||||
|
||||
StateDirMigration.migrateIfNeeded(dir)
|
||||
|
||||
Files.exists(dir.resolve(".git/werkator/worktrees")).shouldBeFalse()
|
||||
// the rest of the state survives the drop
|
||||
Files.exists(dir.resolve(".git/werkator/build-results.json")).shouldBeTrue()
|
||||
}
|
||||
|
||||
test("leaves both alone when the current directory already exists") {
|
||||
val dir = repoWithLegacyState()
|
||||
Files.createDirectories(dir.resolve(".git/werkator"))
|
||||
dir.resolve(".git/werkator/build-results.json").toFile().writeText("[\"live\"]")
|
||||
|
||||
StateDirMigration.migrateIfNeeded(dir)
|
||||
|
||||
// which of the two is the live state is not guessed
|
||||
dir.resolve(".git/werkator/build-results.json").toFile().readText() shouldBe "[\"live\"]"
|
||||
Files.exists(dir.resolve(".git/gittally")).shouldBeTrue()
|
||||
}
|
||||
|
||||
test("does nothing where there is no pre-rename directory") {
|
||||
val dir = Files.createTempDirectory("werkator-state")
|
||||
Files.createDirectories(dir.resolve(".git"))
|
||||
|
||||
StateDirMigration.migrateIfNeeded(dir)
|
||||
|
||||
Files.exists(dir.resolve(".git/werkator")).shouldBeFalse()
|
||||
}
|
||||
}
|
||||
}
|
||||
+9
-9
@@ -1,11 +1,11 @@
|
||||
package de.hoennig.gittally.artifacts
|
||||
package de.hoennig.werkator.artifacts
|
||||
|
||||
import de.hoennig.gittally.build.BranchWorkspaces
|
||||
import de.hoennig.gittally.build.BuildExecutor
|
||||
import de.hoennig.gittally.build.FileBuildResultRepository
|
||||
import de.hoennig.gittally.build.ProcessBuildRunner
|
||||
import de.hoennig.gittally.config.ConfigLoader
|
||||
import de.hoennig.gittally.gitea.GiteaClient
|
||||
import de.hoennig.werkator.build.BranchWorkspaces
|
||||
import de.hoennig.werkator.build.BuildExecutor
|
||||
import de.hoennig.werkator.build.FileBuildResultRepository
|
||||
import de.hoennig.werkator.build.ProcessBuildRunner
|
||||
import de.hoennig.werkator.config.ConfigLoader
|
||||
import de.hoennig.werkator.gitea.GiteaClient
|
||||
import io.kotest.assertions.nondeterministic.eventually
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.nulls.shouldNotBeNull
|
||||
@@ -20,10 +20,10 @@ import kotlin.time.Duration.Companion.seconds
|
||||
class BuildExecutorArtifactIntegrationTest : FunSpec() {
|
||||
init {
|
||||
test("the executor persists a successful build's logs and reports through the real store") {
|
||||
val workingDir = Files.createTempDirectory("gittally-artifact-integration-test")
|
||||
val workingDir = Files.createTempDirectory("werkator-artifact-integration-test")
|
||||
val root = workingDir.resolve("artifact-root")
|
||||
Files.writeString(
|
||||
workingDir.resolve(".gittally.yml"),
|
||||
workingDir.resolve(".werkator.yml"),
|
||||
"""
|
||||
artifacts:
|
||||
rootDir: "$root"
|
||||
+12
-12
@@ -1,9 +1,9 @@
|
||||
package de.hoennig.gittally.artifacts
|
||||
package de.hoennig.werkator.artifacts
|
||||
|
||||
import de.hoennig.gittally.build.ArtifactKeys
|
||||
import de.hoennig.gittally.build.BuildResult
|
||||
import de.hoennig.gittally.build.BuildStatus
|
||||
import de.hoennig.gittally.config.ConfigLoader
|
||||
import de.hoennig.werkator.build.ArtifactKeys
|
||||
import de.hoennig.werkator.build.BuildResult
|
||||
import de.hoennig.werkator.build.BuildStatus
|
||||
import de.hoennig.werkator.config.ConfigLoader
|
||||
import io.kotest.assertions.throwables.shouldThrow
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.collections.shouldContainExactly
|
||||
@@ -22,13 +22,13 @@ class FileArtifactStoreTest : FunSpec() {
|
||||
private val startedAt = Instant.parse("2026-07-07T10:00:00Z")
|
||||
|
||||
private class Harness {
|
||||
val workingDir: Path = Files.createTempDirectory("gittally-store-test")
|
||||
val workingDir: Path = Files.createTempDirectory("werkator-store-test")
|
||||
val root: Path = workingDir.resolve("artifact-root")
|
||||
val store = FileArtifactStore(ConfigLoader(), workingDir)
|
||||
|
||||
init {
|
||||
Files.writeString(
|
||||
workingDir.resolve(".gittally.yml"),
|
||||
workingDir.resolve(".werkator.yml"),
|
||||
"""
|
||||
artifacts:
|
||||
rootDir: "$root"
|
||||
@@ -57,7 +57,7 @@ class FileArtifactStoreTest : FunSpec() {
|
||||
)
|
||||
|
||||
private fun stagingDir(): Path {
|
||||
val dir = Files.createTempDirectory("gittally-staging-test")
|
||||
val dir = Files.createTempDirectory("werkator-staging-test")
|
||||
Files.writeString(dir.resolve("build.stdout.log"), "out")
|
||||
Files.writeString(dir.resolve("build.stderr.log"), "err")
|
||||
Files.writeString(dir.resolve("build.log"), "live")
|
||||
@@ -133,8 +133,8 @@ class FileArtifactStoreTest : FunSpec() {
|
||||
}
|
||||
|
||||
test("the artifact root defaults to XDG_STATE_HOME plus the repo key") {
|
||||
val workingDir = Files.createTempDirectory("gittally-store-test")
|
||||
val stateHome = Files.createTempDirectory("gittally-state-home-test")
|
||||
val workingDir = Files.createTempDirectory("werkator-store-test")
|
||||
val stateHome = Files.createTempDirectory("werkator-state-home-test")
|
||||
val store =
|
||||
FileArtifactStore(ConfigLoader(), workingDir) { name ->
|
||||
if (name == "XDG_STATE_HOME") stateHome.toString() else null
|
||||
@@ -145,7 +145,7 @@ class FileArtifactStoreTest : FunSpec() {
|
||||
|
||||
val expectedDir =
|
||||
stateHome
|
||||
.resolve("gittally/artifacts")
|
||||
.resolve("werkator/artifacts")
|
||||
.resolve(ArtifactKeys.repoKey(workingDir))
|
||||
.resolve("branches")
|
||||
.resolve(build.artifactKey)
|
||||
@@ -183,7 +183,7 @@ class FileArtifactStoreTest : FunSpec() {
|
||||
|
||||
test("prune deletes a symlink without touching its target outside the root") {
|
||||
val h = Harness()
|
||||
val outside = Files.createTempDirectory("gittally-outside-test")
|
||||
val outside = Files.createTempDirectory("werkator-outside-test")
|
||||
Files.writeString(outside.resolve("keep-me.txt"), "precious")
|
||||
Files.createDirectories(h.branchesDir())
|
||||
val link = h.branchesDir().resolve("evil-link")
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package de.hoennig.gittally.build
|
||||
package de.hoennig.werkator.build
|
||||
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.shouldBe
|
||||
+6
-6
@@ -1,7 +1,7 @@
|
||||
package de.hoennig.gittally.build
|
||||
package de.hoennig.werkator.build
|
||||
|
||||
import de.hoennig.gittally.config.ConfigLoader
|
||||
import de.hoennig.gittally.gitea.GiteaClient
|
||||
import de.hoennig.werkator.config.ConfigLoader
|
||||
import de.hoennig.werkator.gitea.GiteaClient
|
||||
import io.kotest.assertions.nondeterministic.eventually
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.booleans.shouldBeFalse
|
||||
@@ -33,7 +33,7 @@ class BuildExecutorTest : FunSpec() {
|
||||
workspaceSubdir: String? = null,
|
||||
val buildRunner: BuildRunner = ProcessBuildRunner(),
|
||||
) {
|
||||
val workingDir: Path = Files.createTempDirectory("gittally-executor-test")
|
||||
val workingDir: Path = Files.createTempDirectory("werkator-executor-test")
|
||||
val repository = FileBuildResultRepository(workingDir.resolve("build-results.json"))
|
||||
val giteaClient = mockk<GiteaClient>(relaxed = true)
|
||||
val artifactStore = mockk<ArtifactStore>(relaxed = true)
|
||||
@@ -65,7 +65,7 @@ class BuildExecutorTest : FunSpec() {
|
||||
)
|
||||
|
||||
init {
|
||||
Files.writeString(workingDir.resolve(".gittally.yml"), configYaml)
|
||||
Files.writeString(workingDir.resolve(".werkator.yml"), configYaml)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,7 +195,7 @@ class BuildExecutorTest : FunSpec() {
|
||||
workingDir: java.nio.file.Path,
|
||||
environment: Map<String, String>,
|
||||
repoDir: java.nio.file.Path,
|
||||
branchConfig: de.hoennig.gittally.config.BranchConfig,
|
||||
branchConfig: de.hoennig.werkator.config.BranchConfig,
|
||||
onAuxProcess: (Process) -> Unit,
|
||||
): Process {
|
||||
val aux = ProcessBuilder("bash", "-c", "sleep 60").directory(workingDir.toFile()).start()
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package de.hoennig.gittally.build
|
||||
package de.hoennig.werkator.build
|
||||
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.shouldBe
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
package de.hoennig.gittally.build
|
||||
package de.hoennig.werkator.build
|
||||
|
||||
import de.hoennig.gittally.config.BranchConfig
|
||||
import de.hoennig.gittally.config.DockerConfig
|
||||
import de.hoennig.werkator.config.BranchConfig
|
||||
import de.hoennig.werkator.config.DockerConfig
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.shouldBe
|
||||
import io.mockk.Called
|
||||
+20
-20
@@ -1,9 +1,9 @@
|
||||
package de.hoennig.gittally.build
|
||||
package de.hoennig.werkator.build
|
||||
|
||||
import de.hoennig.gittally.config.BranchConfig
|
||||
import de.hoennig.gittally.config.DockerConfig
|
||||
import de.hoennig.gittally.git.GitCommandResult
|
||||
import de.hoennig.gittally.git.GitCommandRunner
|
||||
import de.hoennig.werkator.config.BranchConfig
|
||||
import de.hoennig.werkator.config.DockerConfig
|
||||
import de.hoennig.werkator.git.GitCommandResult
|
||||
import de.hoennig.werkator.git.GitCommandRunner
|
||||
import io.kotest.assertions.throwables.shouldThrow
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.collections.shouldContain
|
||||
@@ -47,7 +47,7 @@ class DockerBuildRunnerTest : FunSpec() {
|
||||
beforeEach {
|
||||
clearMocks(commandRunner, socketLocator)
|
||||
captured.clear()
|
||||
repoDir = Files.createTempDirectory("gittally-docker-runner")
|
||||
repoDir = Files.createTempDirectory("werkator-docker-runner")
|
||||
workspace = repoDir.resolve("workspace")
|
||||
every { commandRunner.run(any(), any(), any(), any()) } returns GitCommandResult(0, "", "")
|
||||
every { commandRunner.runOrThrow(any(), any(), any(), any()) } returns GitCommandResult(0, "", "")
|
||||
@@ -77,19 +77,19 @@ class DockerBuildRunnerTest : FunSpec() {
|
||||
"--rm",
|
||||
"--init",
|
||||
"--name",
|
||||
"gittally-build-$repoKey-${ArtifactKeys.branchKey("main")}",
|
||||
"werkator-build-$repoKey-${ArtifactKeys.branchKey("main")}",
|
||||
"--label",
|
||||
"org.hoennig.gittally=true",
|
||||
"org.hoennig.werkator=true",
|
||||
"--label",
|
||||
"org.hoennig.gittally.repository=$repoKey",
|
||||
"org.hoennig.werkator.repository=$repoKey",
|
||||
"--label",
|
||||
"org.hoennig.gittally.role=build",
|
||||
"org.hoennig.werkator.role=build",
|
||||
"--workdir",
|
||||
"$workspace",
|
||||
"--volume",
|
||||
"$workspace:$workspace",
|
||||
"--volume",
|
||||
"gittally-gradle-$repoKey:/gradle-user-home",
|
||||
"werkator-gradle-$repoKey:/gradle-user-home",
|
||||
"--env",
|
||||
"HOME=/tmp/docker-home",
|
||||
"--env",
|
||||
@@ -150,11 +150,11 @@ class DockerBuildRunnerTest : FunSpec() {
|
||||
}
|
||||
}
|
||||
|
||||
test("exposes git metadata read-only with the gittally dir masked for a worktree workspace") {
|
||||
test("exposes git metadata read-only with the werkator dir masked for a worktree workspace") {
|
||||
val gitDir = repoDir.resolve(".git")
|
||||
val adminDir = gitDir.resolve("worktrees/workspace")
|
||||
Files.createDirectories(adminDir)
|
||||
Files.createDirectories(gitDir.resolve("gittally"))
|
||||
Files.createDirectories(gitDir.resolve("werkator"))
|
||||
Files.createDirectories(workspace)
|
||||
Files.writeString(workspace.resolve(".git"), "gitdir: $adminDir\n")
|
||||
|
||||
@@ -162,7 +162,7 @@ class DockerBuildRunnerTest : FunSpec() {
|
||||
|
||||
val args = captured.single()
|
||||
args shouldContain "$gitDir:$gitDir:ro"
|
||||
args[args.indexOf("--tmpfs") + 1] shouldBe "${gitDir.resolve("gittally")}"
|
||||
args[args.indexOf("--tmpfs") + 1] shouldBe "${gitDir.resolve("werkator")}"
|
||||
args shouldContain "$adminDir:$adminDir"
|
||||
}
|
||||
|
||||
@@ -209,13 +209,13 @@ class DockerBuildRunnerTest : FunSpec() {
|
||||
"docker",
|
||||
"build",
|
||||
"--label",
|
||||
"org.gittally.dockerfile=Dockerfile",
|
||||
"org.werkator.dockerfile=Dockerfile",
|
||||
"--label",
|
||||
"org.gittally.dockerfile-sha256=$dockerfileHash",
|
||||
"org.werkator.dockerfile-sha256=$dockerfileHash",
|
||||
"--label",
|
||||
"org.gittally.build-context=.",
|
||||
"org.werkator.build-context=.",
|
||||
"--label",
|
||||
"org.gittally.build-inputs-sha256=$inputsHash",
|
||||
"org.werkator.build-inputs-sha256=$inputsHash",
|
||||
"-t",
|
||||
"build-env:latest",
|
||||
"-f",
|
||||
@@ -251,11 +251,11 @@ class DockerBuildRunnerTest : FunSpec() {
|
||||
|
||||
val repoKey = ArtifactKeys.repoKey(repoDir)
|
||||
verify(exactly = 1) {
|
||||
commandRunner.runOrThrow(listOf("docker", "volume", "create", "gittally-gradle-$repoKey"), repoDir, any(), any())
|
||||
commandRunner.runOrThrow(listOf("docker", "volume", "create", "werkator-gradle-$repoKey"), repoDir, any(), any())
|
||||
}
|
||||
verify(exactly = 2) {
|
||||
commandRunner.run(
|
||||
listOf("docker", "rm", "-f", "gittally-build-$repoKey-${ArtifactKeys.branchKey("main")}"),
|
||||
listOf("docker", "rm", "-f", "werkator-build-$repoKey-${ArtifactKeys.branchKey("main")}"),
|
||||
repoDir,
|
||||
any(),
|
||||
any(),
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
package de.hoennig.gittally.build
|
||||
package de.hoennig.werkator.build
|
||||
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.shouldBe
|
||||
@@ -9,7 +9,7 @@ import java.nio.file.Files
|
||||
class DockerImageInputsTest : FunSpec() {
|
||||
init {
|
||||
test("dockerfileSha256 is a stable hex checksum of the file contents") {
|
||||
val dir = Files.createTempDirectory("gittally-docker-inputs")
|
||||
val dir = Files.createTempDirectory("werkator-docker-inputs")
|
||||
val dockerfile = dir.resolve("Dockerfile")
|
||||
Files.writeString(dockerfile, "FROM eclipse-temurin:21\n")
|
||||
|
||||
@@ -20,7 +20,7 @@ class DockerImageInputsTest : FunSpec() {
|
||||
}
|
||||
|
||||
test("inputs checksum changes when the Dockerfile contents change") {
|
||||
val dir = Files.createTempDirectory("gittally-docker-inputs")
|
||||
val dir = Files.createTempDirectory("werkator-docker-inputs")
|
||||
val dockerfile = dir.resolve("Dockerfile")
|
||||
Files.writeString(dockerfile, "FROM eclipse-temurin:21\n")
|
||||
val before =
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
package de.hoennig.gittally.build
|
||||
package de.hoennig.werkator.build
|
||||
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.booleans.shouldBeFalse
|
||||
@@ -16,7 +16,7 @@ import java.time.Instant
|
||||
class FileBuildResultRepositoryTest : FunSpec() {
|
||||
private val baseTime = Instant.parse("2026-07-07T10:00:00Z")
|
||||
|
||||
private fun newFile(): Path = Files.createTempDirectory("gittally-results-test").resolve("build-results.json")
|
||||
private fun newFile(): Path = Files.createTempDirectory("werkator-results-test").resolve("build-results.json")
|
||||
|
||||
private fun result(
|
||||
branch: String = "main",
|
||||
+7
-7
@@ -1,8 +1,8 @@
|
||||
package de.hoennig.gittally.build
|
||||
package de.hoennig.werkator.build
|
||||
|
||||
import de.hoennig.gittally.config.ConfigLoader
|
||||
import de.hoennig.gittally.git.GitCommandRunner
|
||||
import de.hoennig.gittally.git.GitService
|
||||
import de.hoennig.werkator.config.ConfigLoader
|
||||
import de.hoennig.werkator.git.GitCommandRunner
|
||||
import de.hoennig.werkator.git.GitService
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.nulls.shouldBeNull
|
||||
import io.kotest.matchers.shouldBe
|
||||
@@ -20,16 +20,16 @@ class GitWorktreeWorkspacesTest : FunSpec() {
|
||||
// hermetic git: fixed identity, no user/system config (hooks, gpg signing, ...)
|
||||
private val gitEnvironment =
|
||||
mapOf(
|
||||
"GIT_AUTHOR_NAME" to "GitTally Test",
|
||||
"GIT_AUTHOR_NAME" to "Werkator Test",
|
||||
"GIT_AUTHOR_EMAIL" to "test@example.com",
|
||||
"GIT_COMMITTER_NAME" to "GitTally Test",
|
||||
"GIT_COMMITTER_NAME" to "Werkator Test",
|
||||
"GIT_COMMITTER_EMAIL" to "test@example.com",
|
||||
"GIT_CONFIG_GLOBAL" to "/dev/null",
|
||||
"GIT_CONFIG_SYSTEM" to "/dev/null",
|
||||
)
|
||||
|
||||
private inner class Fixture {
|
||||
val repo: Path = Files.createTempDirectory("gittally-workspaces-test").resolve("repo")
|
||||
val repo: Path = Files.createTempDirectory("werkator-workspaces-test").resolve("repo")
|
||||
|
||||
init {
|
||||
Files.createDirectories(repo)
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
package de.hoennig.gittally.build
|
||||
package de.hoennig.werkator.build
|
||||
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.shouldBe
|
||||
@@ -9,7 +9,7 @@ import java.nio.file.Path
|
||||
class ProcessBuildRunnerTest : FunSpec() {
|
||||
private val runner = ProcessBuildRunner()
|
||||
|
||||
private fun tempDir(): Path = Files.createTempDirectory("gittally-runner-test")
|
||||
private fun tempDir(): Path = Files.createTempDirectory("werkator-runner-test")
|
||||
|
||||
init {
|
||||
test("propagates the exit code") {
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package de.hoennig.gittally.commands
|
||||
package de.hoennig.werkator.commands
|
||||
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.shouldBe
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
package de.hoennig.gittally.commands
|
||||
package de.hoennig.werkator.commands
|
||||
|
||||
import de.hoennig.gittally.build.BuildStatus
|
||||
import de.hoennig.gittally.git.GitService
|
||||
import de.hoennig.werkator.build.BuildStatus
|
||||
import de.hoennig.werkator.git.GitService
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.shouldBe
|
||||
import io.kotest.matchers.string.shouldContain
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package de.hoennig.gittally.commands
|
||||
package de.hoennig.werkator.commands
|
||||
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.PrintStream
|
||||
+5
-5
@@ -1,8 +1,8 @@
|
||||
package de.hoennig.gittally.commands
|
||||
package de.hoennig.werkator.commands
|
||||
|
||||
import de.hoennig.gittally.config.ConfigLoader
|
||||
import de.hoennig.gittally.config.GitConfig
|
||||
import de.hoennig.gittally.config.GitTallyConfig
|
||||
import de.hoennig.werkator.config.ConfigLoader
|
||||
import de.hoennig.werkator.config.GitConfig
|
||||
import de.hoennig.werkator.config.WerkatorConfig
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.string.shouldContain
|
||||
import io.kotest.matchers.string.shouldNotContain
|
||||
@@ -26,7 +26,7 @@ class ConfigPrintCommandTest : FunSpec() {
|
||||
clearMocks(configLoader)
|
||||
every { configLoader.toYaml(any()) } answers { yamlWriter.toYaml(firstArg()) }
|
||||
every { configLoader.loadRaw() } returns rawConfig
|
||||
every { configLoader.load() } returns GitTallyConfig(git = GitConfig(account = "ci-user", token = "s3cr3t-token"))
|
||||
every { configLoader.load() } returns WerkatorConfig(git = GitConfig(account = "ci-user", token = "s3cr3t-token"))
|
||||
command.full = false
|
||||
command.showSecrets = false
|
||||
}
|
||||
+8
-8
@@ -1,11 +1,11 @@
|
||||
package de.hoennig.gittally.commands
|
||||
package de.hoennig.werkator.commands
|
||||
|
||||
import de.hoennig.gittally.build.ArtifactStore
|
||||
import de.hoennig.gittally.build.BuildExecutor
|
||||
import de.hoennig.gittally.build.BuildResult
|
||||
import de.hoennig.gittally.build.BuildResultRepository
|
||||
import de.hoennig.gittally.build.BuildStatus
|
||||
import de.hoennig.gittally.build.RunningBuild
|
||||
import de.hoennig.werkator.build.ArtifactStore
|
||||
import de.hoennig.werkator.build.BuildExecutor
|
||||
import de.hoennig.werkator.build.BuildResult
|
||||
import de.hoennig.werkator.build.BuildResultRepository
|
||||
import de.hoennig.werkator.build.BuildStatus
|
||||
import de.hoennig.werkator.build.RunningBuild
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.shouldBe
|
||||
import io.kotest.matchers.string.shouldContain
|
||||
@@ -55,7 +55,7 @@ class ConsoleBuildRunnerTest : FunSpec() {
|
||||
init {
|
||||
beforeEach {
|
||||
clearMocks(buildExecutor, repository, artifactStore)
|
||||
tempDir = Files.createTempDirectory("gittally-console-build-test")
|
||||
tempDir = Files.createTempDirectory("werkator-console-build-test")
|
||||
}
|
||||
|
||||
afterEach {
|
||||
+48
-28
@@ -1,7 +1,8 @@
|
||||
package de.hoennig.gittally.commands
|
||||
package de.hoennig.werkator.commands
|
||||
|
||||
import de.hoennig.gittally.git.GitService
|
||||
import de.hoennig.werkator.git.GitService
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.booleans.shouldBeFalse
|
||||
import io.kotest.matchers.file.shouldExist
|
||||
import io.kotest.matchers.shouldBe
|
||||
import io.kotest.matchers.string.shouldContain
|
||||
@@ -17,7 +18,7 @@ class InitCommandTest : FunSpec() {
|
||||
|
||||
init {
|
||||
test("creates config files with auto-detected values") {
|
||||
val tempDir = Files.createTempDirectory("gittally-init-test")
|
||||
val tempDir = Files.createTempDirectory("werkator-init-test")
|
||||
initCommand.workingDir = tempDir
|
||||
|
||||
every { gitService.getTopLevel(tempDir) } returns tempDir
|
||||
@@ -25,21 +26,40 @@ class InitCommandTest : FunSpec() {
|
||||
|
||||
initCommand.run()
|
||||
|
||||
val projectConfig = tempDir.resolve(".gittally.yml")
|
||||
val projectConfig = tempDir.resolve(".werkator.yml")
|
||||
projectConfig.toFile().shouldExist()
|
||||
val projectContent = projectConfig.toFile().readText()
|
||||
projectContent shouldContain "baseUrl: https://git.example.org"
|
||||
projectContent shouldContain "owner: my-org"
|
||||
projectContent shouldContain "repo: my-repo"
|
||||
|
||||
val repoConfig = tempDir.resolve(".git/gittally/.gittally.yml")
|
||||
val repoConfig = tempDir.resolve(".git/werkator/.werkator.yml")
|
||||
repoConfig.toFile().shouldExist()
|
||||
val repoContent = repoConfig.toFile().readText()
|
||||
repoContent shouldContain "account: \"\"" // no user in https URL
|
||||
}
|
||||
|
||||
test("does not write a second config beside one under the previous name") {
|
||||
val tempDir = Files.createTempDirectory("werkator-init-test")
|
||||
initCommand.workingDir = tempDir
|
||||
Files.createDirectories(tempDir.resolve(".git/gittally"))
|
||||
tempDir.resolve(".gittally.yml").toFile().writeText("gitea:\n owner: kept\n")
|
||||
tempDir.resolve(".git/gittally/.gittally.yml").toFile().writeText("git:\n account: kept\n")
|
||||
|
||||
every { gitService.getTopLevel(tempDir) } returns tempDir
|
||||
every { gitService.getOriginUrl(tempDir) } returns "https://git.example.org/my-org/my-repo.git"
|
||||
|
||||
initCommand.run()
|
||||
|
||||
// a second file would shadow the first one, and the repository would
|
||||
// silently build something else than what its configuration says
|
||||
Files.exists(tempDir.resolve(".werkator.yml")).shouldBeFalse()
|
||||
Files.exists(tempDir.resolve(".git/werkator/.werkator.yml")).shouldBeFalse()
|
||||
tempDir.resolve(".gittally.yml").toFile().readText() shouldContain "owner: kept"
|
||||
}
|
||||
|
||||
test("creates the secrets config and its directory readable only by the owner") {
|
||||
val tempDir = Files.createTempDirectory("gittally-init-test")
|
||||
val tempDir = Files.createTempDirectory("werkator-init-test")
|
||||
initCommand.workingDir = tempDir
|
||||
|
||||
every { gitService.getTopLevel(tempDir) } returns tempDir
|
||||
@@ -47,13 +67,13 @@ class InitCommandTest : FunSpec() {
|
||||
|
||||
initCommand.run()
|
||||
|
||||
val repoConfig = tempDir.resolve(".git/gittally/.gittally.yml")
|
||||
val repoConfig = tempDir.resolve(".git/werkator/.werkator.yml")
|
||||
PosixFilePermissions.toString(Files.getPosixFilePermissions(repoConfig)) shouldBe "rw-------"
|
||||
PosixFilePermissions.toString(Files.getPosixFilePermissions(repoConfig.parent)) shouldBe "rwx------"
|
||||
}
|
||||
|
||||
test("detects account from https url") {
|
||||
val tempDir = Files.createTempDirectory("gittally-init-test")
|
||||
val tempDir = Files.createTempDirectory("werkator-init-test")
|
||||
initCommand.workingDir = tempDir
|
||||
|
||||
every { gitService.getTopLevel(tempDir) } returns tempDir
|
||||
@@ -61,13 +81,13 @@ class InitCommandTest : FunSpec() {
|
||||
|
||||
initCommand.run()
|
||||
|
||||
val repoConfig = tempDir.resolve(".git/gittally/.gittally.yml")
|
||||
val repoConfig = tempDir.resolve(".git/werkator/.werkator.yml")
|
||||
val repoContent = repoConfig.toFile().readText()
|
||||
repoContent shouldContain "account: \"ci-user\""
|
||||
}
|
||||
|
||||
test("parses ssh url") {
|
||||
val tempDir = Files.createTempDirectory("gittally-init-test")
|
||||
val tempDir = Files.createTempDirectory("werkator-init-test")
|
||||
initCommand.workingDir = tempDir
|
||||
|
||||
every { gitService.getTopLevel(tempDir) } returns tempDir
|
||||
@@ -75,7 +95,7 @@ class InitCommandTest : FunSpec() {
|
||||
|
||||
initCommand.run()
|
||||
|
||||
val projectConfig = tempDir.resolve(".gittally.yml")
|
||||
val projectConfig = tempDir.resolve(".werkator.yml")
|
||||
val projectContent = projectConfig.toFile().readText()
|
||||
projectContent shouldContain "baseUrl: https://git.example.org" // fallback to https
|
||||
projectContent shouldContain "owner: my-org"
|
||||
@@ -83,10 +103,10 @@ class InitCommandTest : FunSpec() {
|
||||
}
|
||||
|
||||
test("does not overwrite existing files") {
|
||||
val tempDir = Files.createTempDirectory("gittally-init-test")
|
||||
val tempDir = Files.createTempDirectory("werkator-init-test")
|
||||
initCommand.workingDir = tempDir
|
||||
|
||||
val projectConfig = tempDir.resolve(".gittally.yml")
|
||||
val projectConfig = tempDir.resolve(".werkator.yml")
|
||||
projectConfig.toFile().writeText("existing: content")
|
||||
|
||||
every { gitService.getTopLevel(tempDir) } returns tempDir
|
||||
@@ -98,10 +118,10 @@ class InitCommandTest : FunSpec() {
|
||||
}
|
||||
|
||||
test("--systemd generates unit and environment file with install instructions") {
|
||||
val tempDir = Files.createTempDirectory("gittally-init-test")
|
||||
val tempDir = Files.createTempDirectory("werkator-init-test")
|
||||
initCommand.workingDir = tempDir
|
||||
initCommand.systemd = true
|
||||
initCommand.jarPathResolver = { Paths.get("/home/ci/bin/gittally.jar") }
|
||||
initCommand.jarPathResolver = { Paths.get("/home/ci/bin/werkator.jar") }
|
||||
initCommand.javaExecutableResolver = { Paths.get("/usr/bin/java") }
|
||||
|
||||
every { gitService.getTopLevel(tempDir) } returns tempDir
|
||||
@@ -110,20 +130,20 @@ class InitCommandTest : FunSpec() {
|
||||
initCommand.run()
|
||||
|
||||
val unitName = SystemdServiceFiles.unitName(tempDir)
|
||||
val unitFile = tempDir.resolve(".git/gittally/$unitName")
|
||||
val unitFile = tempDir.resolve(".git/werkator/$unitName")
|
||||
unitFile.toFile().shouldExist()
|
||||
val unitContent = unitFile.toFile().readText()
|
||||
unitContent shouldContain "WorkingDirectory=$tempDir"
|
||||
unitContent shouldContain """ExecStart="/usr/bin/java" ${'$'}JAVA_OPTS -jar "/home/ci/bin/gittally.jar" server"""
|
||||
unitContent shouldContain """ExecStart="/usr/bin/java" ${'$'}JAVA_OPTS -jar "/home/ci/bin/werkator.jar" server"""
|
||||
|
||||
tempDir.resolve(".git/gittally/gittally.env").toFile().shouldExist()
|
||||
tempDir.resolve(".git/werkator/werkator.env").toFile().shouldExist()
|
||||
}
|
||||
|
||||
test("--systemd also generates the nightly Docker cleanup timer") {
|
||||
val tempDir = Files.createTempDirectory("gittally-init-test")
|
||||
val tempDir = Files.createTempDirectory("werkator-init-test")
|
||||
initCommand.workingDir = tempDir
|
||||
initCommand.systemd = true
|
||||
initCommand.jarPathResolver = { Paths.get("/home/ci/bin/gittally.jar") }
|
||||
initCommand.jarPathResolver = { Paths.get("/home/ci/bin/werkator.jar") }
|
||||
initCommand.javaExecutableResolver = { Paths.get("/usr/bin/java") }
|
||||
|
||||
every { gitService.getTopLevel(tempDir) } returns tempDir
|
||||
@@ -131,22 +151,22 @@ class InitCommandTest : FunSpec() {
|
||||
|
||||
initCommand.run()
|
||||
|
||||
val pruneService = tempDir.resolve(".git/gittally/gittally-docker-prune.service")
|
||||
val pruneService = tempDir.resolve(".git/werkator/werkator-docker-prune.service")
|
||||
pruneService.toFile().shouldExist()
|
||||
pruneService.toFile().readText() shouldContain "docker system prune -af"
|
||||
val pruneTimer = tempDir.resolve(".git/gittally/gittally-docker-prune.timer")
|
||||
val pruneTimer = tempDir.resolve(".git/werkator/werkator-docker-prune.timer")
|
||||
pruneTimer.toFile().shouldExist()
|
||||
pruneTimer.toFile().readText() shouldContain "OnCalendar=*-*-* 02:00:00"
|
||||
}
|
||||
|
||||
test("--systemd keeps an existing environment file") {
|
||||
val tempDir = Files.createTempDirectory("gittally-init-test")
|
||||
val tempDir = Files.createTempDirectory("werkator-init-test")
|
||||
initCommand.workingDir = tempDir
|
||||
initCommand.systemd = true
|
||||
initCommand.jarPathResolver = { Paths.get("/home/ci/bin/gittally.jar") }
|
||||
initCommand.jarPathResolver = { Paths.get("/home/ci/bin/werkator.jar") }
|
||||
initCommand.javaExecutableResolver = { Paths.get("/usr/bin/java") }
|
||||
|
||||
val envFile = tempDir.resolve(".git/gittally/gittally.env")
|
||||
val envFile = tempDir.resolve(".git/werkator/werkator.env")
|
||||
Files.createDirectories(envFile.parent)
|
||||
envFile.toFile().writeText("JAVA_OPTS=-Xmx1g\n")
|
||||
|
||||
@@ -159,7 +179,7 @@ class InitCommandTest : FunSpec() {
|
||||
}
|
||||
|
||||
test("--systemd without a resolvable jar path generates no unit file") {
|
||||
val tempDir = Files.createTempDirectory("gittally-init-test")
|
||||
val tempDir = Files.createTempDirectory("werkator-init-test")
|
||||
initCommand.workingDir = tempDir
|
||||
initCommand.systemd = true
|
||||
initCommand.jarPathResolver = { null }
|
||||
@@ -169,12 +189,12 @@ class InitCommandTest : FunSpec() {
|
||||
|
||||
initCommand.run()
|
||||
|
||||
val unitFile = tempDir.resolve(".git/gittally/${SystemdServiceFiles.unitName(tempDir)}")
|
||||
val unitFile = tempDir.resolve(".git/werkator/${SystemdServiceFiles.unitName(tempDir)}")
|
||||
unitFile.toFile().exists() shouldBe false
|
||||
}
|
||||
|
||||
test("reproduces path root mismatch issue") {
|
||||
val tempDir = Files.createTempDirectory("gittally-init-test").toAbsolutePath().normalize()
|
||||
val tempDir = Files.createTempDirectory("werkator-init-test").toAbsolutePath().normalize()
|
||||
initCommand.workingDir = Paths.get(".") // Set to relative path as in real app
|
||||
|
||||
// We need to mock getTopLevel to return the absolute path
|
||||
+5
-5
@@ -1,9 +1,9 @@
|
||||
package de.hoennig.gittally.commands
|
||||
package de.hoennig.werkator.commands
|
||||
|
||||
import de.hoennig.gittally.build.BuildResult
|
||||
import de.hoennig.gittally.build.BuildResultRepository
|
||||
import de.hoennig.gittally.build.BuildStatus
|
||||
import de.hoennig.gittally.git.GitService
|
||||
import de.hoennig.werkator.build.BuildResult
|
||||
import de.hoennig.werkator.build.BuildResultRepository
|
||||
import de.hoennig.werkator.build.BuildStatus
|
||||
import de.hoennig.werkator.git.GitService
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.shouldBe
|
||||
import io.kotest.matchers.string.shouldContain
|
||||
+4
-4
@@ -1,8 +1,8 @@
|
||||
package de.hoennig.gittally.commands
|
||||
package de.hoennig.werkator.commands
|
||||
|
||||
import de.hoennig.gittally.build.BuildResult
|
||||
import de.hoennig.gittally.build.BuildResultRepository
|
||||
import de.hoennig.gittally.build.BuildStatus
|
||||
import de.hoennig.werkator.build.BuildResult
|
||||
import de.hoennig.werkator.build.BuildResultRepository
|
||||
import de.hoennig.werkator.build.BuildStatus
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.shouldBe
|
||||
import io.kotest.matchers.string.shouldContain
|
||||
+13
-13
@@ -1,4 +1,4 @@
|
||||
package de.hoennig.gittally.commands
|
||||
package de.hoennig.werkator.commands
|
||||
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.shouldBe
|
||||
@@ -9,8 +9,8 @@ import java.nio.file.Paths
|
||||
class SystemdServiceFilesTest : FunSpec() {
|
||||
init {
|
||||
test("unit name is derived from the sanitized repository directory name") {
|
||||
SystemdServiceFiles.unitName(Paths.get("/srv/repos/my-repo")) shouldBe "gittally-my-repo.service"
|
||||
SystemdServiceFiles.unitName(Paths.get("/srv/repos/my repo!")) shouldBe "gittally-my-repo-.service"
|
||||
SystemdServiceFiles.unitName(Paths.get("/srv/repos/my-repo")) shouldBe "werkator-my-repo.service"
|
||||
SystemdServiceFiles.unitName(Paths.get("/srv/repos/my repo!")) shouldBe "werkator-my-repo-.service"
|
||||
}
|
||||
|
||||
test("unit file runs the server jar in the repository with restart and environment file") {
|
||||
@@ -18,16 +18,16 @@ class SystemdServiceFilesTest : FunSpec() {
|
||||
SystemdServiceFiles.unitFileContent(
|
||||
repoRoot = Paths.get("/srv/repos/my-repo"),
|
||||
javaExecutable = Paths.get("/usr/lib/jvm/java-21/bin/java"),
|
||||
jarPath = Paths.get("/home/ci/bin/gittally.jar"),
|
||||
envFile = Paths.get("/srv/repos/my-repo/.git/gittally/gittally.env"),
|
||||
jarPath = Paths.get("/home/ci/bin/werkator.jar"),
|
||||
envFile = Paths.get("/srv/repos/my-repo/.git/werkator/werkator.env"),
|
||||
)
|
||||
|
||||
content shouldContain "Description=GitTally CI for my-repo"
|
||||
content shouldContain "Description=Werkator CI for my-repo"
|
||||
content shouldContain "After=network-online.target docker.service"
|
||||
content shouldContain "WorkingDirectory=/srv/repos/my-repo"
|
||||
content shouldContain "EnvironmentFile=-/srv/repos/my-repo/.git/gittally/gittally.env"
|
||||
content shouldContain "EnvironmentFile=-/srv/repos/my-repo/.git/werkator/werkator.env"
|
||||
content shouldContain
|
||||
"""ExecStart="/usr/lib/jvm/java-21/bin/java" ${'$'}JAVA_OPTS -jar "/home/ci/bin/gittally.jar" server"""
|
||||
"""ExecStart="/usr/lib/jvm/java-21/bin/java" ${'$'}JAVA_OPTS -jar "/home/ci/bin/werkator.jar" server"""
|
||||
content shouldContain "Restart=always"
|
||||
content shouldContain "RestartSec=30"
|
||||
content shouldContain "WantedBy=default.target"
|
||||
@@ -38,13 +38,13 @@ class SystemdServiceFilesTest : FunSpec() {
|
||||
SystemdServiceFiles.unitFileContent(
|
||||
repoRoot = Paths.get("/srv/100%-repo"),
|
||||
javaExecutable = Paths.get("/usr/bin/java"),
|
||||
jarPath = Paths.get("/srv/100%-repo/gittally.jar"),
|
||||
envFile = Paths.get("/srv/100%-repo/gittally.env"),
|
||||
jarPath = Paths.get("/srv/100%-repo/werkator.jar"),
|
||||
envFile = Paths.get("/srv/100%-repo/werkator.env"),
|
||||
)
|
||||
|
||||
content shouldContain "WorkingDirectory=/srv/100%%-repo"
|
||||
content shouldContain "EnvironmentFile=-/srv/100%%-repo/gittally.env"
|
||||
content shouldContain """-jar "/srv/100%%-repo/gittally.jar" server"""
|
||||
content shouldContain "EnvironmentFile=-/srv/100%%-repo/werkator.env"
|
||||
content shouldContain """-jar "/srv/100%%-repo/werkator.jar" server"""
|
||||
}
|
||||
|
||||
test("prune service cleans containers and images but never volumes") {
|
||||
@@ -69,7 +69,7 @@ class SystemdServiceFilesTest : FunSpec() {
|
||||
val content = SystemdServiceFiles.envFileContent()
|
||||
|
||||
content shouldContain "#JAVA_OPTS="
|
||||
content shouldContain ".gittally.yml"
|
||||
content shouldContain ".werkator.yml"
|
||||
}
|
||||
}
|
||||
}
|
||||
+162
-102
@@ -1,4 +1,4 @@
|
||||
package de.hoennig.gittally.config
|
||||
package de.hoennig.werkator.config
|
||||
|
||||
import io.kotest.assertions.throwables.shouldThrow
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
@@ -18,7 +18,7 @@ import java.util.Properties
|
||||
class ConfigLoaderTest : FunSpec() {
|
||||
private val loader = ConfigLoader()
|
||||
|
||||
/** A loader that knows which GitTally it is, for the `gitTally.version` checks. */
|
||||
/** A loader that knows which Werkator it is, for the `werkator.version` checks. */
|
||||
private fun loaderRunning(version: String): ConfigLoader {
|
||||
val provider = mockk<ObjectProvider<BuildProperties>>()
|
||||
every { provider.getIfAvailable() } returns BuildProperties(Properties().apply { setProperty("version", version) })
|
||||
@@ -27,18 +27,18 @@ class ConfigLoaderTest : FunSpec() {
|
||||
|
||||
init {
|
||||
test("returns defaults when no config files exist") {
|
||||
val dir = Files.createTempDirectory("gittally-test")
|
||||
loader.load(dir) shouldBe GitTallyConfig()
|
||||
val dir = Files.createTempDirectory("werkator-test")
|
||||
loader.load(dir) shouldBe WerkatorConfig()
|
||||
}
|
||||
|
||||
test("loadRaw returns empty map when no config files exist") {
|
||||
val dir = Files.createTempDirectory("gittally-test")
|
||||
val dir = Files.createTempDirectory("werkator-test")
|
||||
loader.loadRaw(dir).shouldBeEmpty()
|
||||
}
|
||||
|
||||
test("reads gitea config from .gittally.yml") {
|
||||
val dir = Files.createTempDirectory("gittally-test")
|
||||
dir.resolve(".gittally.yml").toFile().writeText(
|
||||
test("reads gitea config from .werkator.yml") {
|
||||
val dir = Files.createTempDirectory("werkator-test")
|
||||
dir.resolve(".werkator.yml").toFile().writeText(
|
||||
"""
|
||||
gitea:
|
||||
owner: my-org
|
||||
@@ -50,11 +50,71 @@ class ConfigLoaderTest : FunSpec() {
|
||||
config.gitea.repo shouldBe "my-repo"
|
||||
}
|
||||
|
||||
test("falls back to the pre-rename .gittally.yml at the repository root") {
|
||||
val dir = Files.createTempDirectory("werkator-test")
|
||||
dir.resolve(".gittally.yml").toFile().writeText(
|
||||
"""
|
||||
gitea:
|
||||
owner: my-org
|
||||
repo: my-repo
|
||||
""".trimIndent(),
|
||||
)
|
||||
loader.load(dir).gitea.owner shouldBe "my-org"
|
||||
}
|
||||
|
||||
test("falls back to the pre-rename machine config under .git/gittally") {
|
||||
val dir = Files.createTempDirectory("werkator-test")
|
||||
Files.createDirectories(dir.resolve(".git/gittally"))
|
||||
dir.resolve(".git/gittally/.gittally.yml").toFile().writeText(
|
||||
"""
|
||||
git:
|
||||
account: ci-user
|
||||
""".trimIndent(),
|
||||
)
|
||||
loader.load(dir).git.account shouldBe "ci-user"
|
||||
}
|
||||
|
||||
test("finds the machine config left under its old name in an already-moved directory") {
|
||||
val dir = Files.createTempDirectory("werkator-test")
|
||||
Files.createDirectories(dir.resolve(".git/werkator"))
|
||||
dir.resolve(".git/werkator/.gittally.yml").toFile().writeText(
|
||||
"""
|
||||
git:
|
||||
account: ci-user
|
||||
""".trimIndent(),
|
||||
)
|
||||
loader.load(dir).git.account shouldBe "ci-user"
|
||||
}
|
||||
|
||||
test("the current name wins where both exist, so a half-done rename is not merged") {
|
||||
val dir = Files.createTempDirectory("werkator-test")
|
||||
dir.resolve(".werkator.yml").toFile().writeText("gitea:\n owner: current\n")
|
||||
dir.resolve(".gittally.yml").toFile().writeText("gitea:\n owner: legacy\n repo: legacy-repo\n")
|
||||
val config = loader.load(dir)
|
||||
config.gitea.owner shouldBe "current"
|
||||
// not merged: the old file is a leftover, not a layer
|
||||
config.gitea.repo shouldBe ""
|
||||
}
|
||||
|
||||
test("a branch whose config is committed under the pre-rename name is still read as the branch layer") {
|
||||
val dir = Files.createTempDirectory("werkator-test")
|
||||
val worktree = Files.createTempDirectory("werkator-worktree")
|
||||
worktree.resolve(".gittally.yml").toFile().writeText(
|
||||
"""
|
||||
builds:
|
||||
default:
|
||||
buildCommand: ./gradlew fromBranch
|
||||
""".trimIndent(),
|
||||
)
|
||||
loader.loadForWorktree(dir, worktree).buildSettings("any-branch", "default").buildCommand shouldBe
|
||||
"./gradlew fromBranch"
|
||||
}
|
||||
|
||||
test("reads executor.maxConcurrent and defaults it to 1") {
|
||||
val dir = Files.createTempDirectory("gittally-test")
|
||||
val dir = Files.createTempDirectory("werkator-test")
|
||||
loader.load(dir).executor.maxConcurrent shouldBe 1
|
||||
|
||||
dir.resolve(".gittally.yml").toFile().writeText(
|
||||
dir.resolve(".werkator.yml").toFile().writeText(
|
||||
"""
|
||||
executor:
|
||||
maxConcurrent: 3
|
||||
@@ -64,8 +124,8 @@ class ConfigLoaderTest : FunSpec() {
|
||||
}
|
||||
|
||||
test("the builds section holds named build definitions") {
|
||||
val dir = Files.createTempDirectory("gittally-test")
|
||||
dir.resolve(".gittally.yml").toFile().writeText(
|
||||
val dir = Files.createTempDirectory("werkator-test")
|
||||
dir.resolve(".werkator.yml").toFile().writeText(
|
||||
"""
|
||||
executor:
|
||||
maxConcurrent: 2
|
||||
@@ -100,8 +160,8 @@ class ConfigLoaderTest : FunSpec() {
|
||||
}
|
||||
|
||||
test("an explicit builds.default entry overrides the implicit default build") {
|
||||
val dir = Files.createTempDirectory("gittally-test")
|
||||
dir.resolve(".gittally.yml").toFile().writeText(
|
||||
val dir = Files.createTempDirectory("werkator-test")
|
||||
dir.resolve(".werkator.yml").toFile().writeText(
|
||||
"""
|
||||
builds:
|
||||
default:
|
||||
@@ -113,11 +173,11 @@ class ConfigLoaderTest : FunSpec() {
|
||||
loader.load(dir).effectiveBuildDefinitions()["default"] shouldBe BuildDefinition(trigger = TriggerConfig(onPush = false))
|
||||
}
|
||||
|
||||
test("a config that needs a newer GitTally is refused, naming the file and both versions") {
|
||||
val dir = Files.createTempDirectory("gittally-test")
|
||||
dir.resolve(".gittally.yml").toFile().writeText(
|
||||
test("a config that needs a newer Werkator is refused, naming the file and both versions") {
|
||||
val dir = Files.createTempDirectory("werkator-test")
|
||||
dir.resolve(".werkator.yml").toFile().writeText(
|
||||
"""
|
||||
gitTally:
|
||||
werkator:
|
||||
version:
|
||||
since: "0.9.16"
|
||||
""".trimIndent(),
|
||||
@@ -126,7 +186,7 @@ class ConfigLoaderTest : FunSpec() {
|
||||
val error = shouldThrow<ConfigVersionException> { loaderRunning("0.9.15").load(dir) }
|
||||
|
||||
error.message.shouldNotBeNull().let {
|
||||
it shouldContain ".gittally.yml"
|
||||
it shouldContain ".werkator.yml"
|
||||
it shouldContain "0.9.16"
|
||||
it shouldContain "0.9.15"
|
||||
it shouldContain "roll back"
|
||||
@@ -134,10 +194,10 @@ class ConfigLoaderTest : FunSpec() {
|
||||
}
|
||||
|
||||
test("a config within its declared range loads, and exceeding only the ceiling still loads") {
|
||||
val dir = Files.createTempDirectory("gittally-test")
|
||||
dir.resolve(".gittally.yml").toFile().writeText(
|
||||
val dir = Files.createTempDirectory("werkator-test")
|
||||
dir.resolve(".werkator.yml").toFile().writeText(
|
||||
"""
|
||||
gitTally:
|
||||
werkator:
|
||||
version:
|
||||
since: "0.9.16"
|
||||
below: "1.0"
|
||||
@@ -149,20 +209,20 @@ class ConfigLoaderTest : FunSpec() {
|
||||
loaderRunning("0.9.16").load(dir).gitea.owner shouldBe "my-org"
|
||||
// beyond `below`: a warning, never a refusal — an unmaintained marker must not stop a CI
|
||||
loaderRunning("1.4.0").load(dir).gitea.owner shouldBe "my-org"
|
||||
loaderRunning("0.9.16").load(dir).gitTally.version shouldBe
|
||||
loaderRunning("0.9.16").load(dir).werkator.version shouldBe
|
||||
VersionRequirement(since = "0.9.16", below = "1.0")
|
||||
}
|
||||
|
||||
test("an incompatible branch config is refused as the branch's problem, not the server's") {
|
||||
val dir = Files.createTempDirectory("gittally-test")
|
||||
dir.resolve(".gittally.yml").toFile().writeText("gitea:\n owner: my-org")
|
||||
val dir = Files.createTempDirectory("werkator-test")
|
||||
dir.resolve(".werkator.yml").toFile().writeText("gitea:\n owner: my-org")
|
||||
|
||||
val error =
|
||||
shouldThrow<ConfigVersionException> {
|
||||
loaderRunning("0.9.15").loadWithBranchLayer(
|
||||
dir,
|
||||
"""
|
||||
gitTally:
|
||||
werkator:
|
||||
version:
|
||||
since: "2.0.0"
|
||||
""".trimIndent(),
|
||||
@@ -178,11 +238,11 @@ class ConfigLoaderTest : FunSpec() {
|
||||
}
|
||||
|
||||
test("the machine config is checked as its own file") {
|
||||
val dir = Files.createTempDirectory("gittally-test")
|
||||
dir.resolve(".git/gittally").toFile().mkdirs()
|
||||
dir.resolve(".git/gittally/.gittally.yml").toFile().writeText(
|
||||
val dir = Files.createTempDirectory("werkator-test")
|
||||
dir.resolve(".git/werkator").toFile().mkdirs()
|
||||
dir.resolve(".git/werkator/.werkator.yml").toFile().writeText(
|
||||
"""
|
||||
gitTally:
|
||||
werkator:
|
||||
version:
|
||||
since: "1.0.0"
|
||||
""".trimIndent(),
|
||||
@@ -190,12 +250,12 @@ class ConfigLoaderTest : FunSpec() {
|
||||
|
||||
shouldThrow<ConfigVersionException> {
|
||||
loaderRunning("0.9.16").load(dir)
|
||||
}.message.shouldNotBeNull() shouldContain ".git/gittally/.gittally.yml"
|
||||
}.message.shouldNotBeNull() shouldContain ".git/werkator/.werkator.yml"
|
||||
}
|
||||
|
||||
test("a leftover builds.maxConcurrent is ignored instead of failing the config") {
|
||||
val dir = Files.createTempDirectory("gittally-test")
|
||||
dir.resolve(".gittally.yml").toFile().writeText(
|
||||
val dir = Files.createTempDirectory("werkator-test")
|
||||
dir.resolve(".werkator.yml").toFile().writeText(
|
||||
"""
|
||||
builds:
|
||||
maxConcurrent: 1
|
||||
@@ -211,8 +271,8 @@ class ConfigLoaderTest : FunSpec() {
|
||||
}
|
||||
|
||||
test("a branch may redefine the builds section for its own builds") {
|
||||
val dir = Files.createTempDirectory("gittally-test")
|
||||
dir.resolve(".gittally.yml").toFile().writeText(
|
||||
val dir = Files.createTempDirectory("werkator-test")
|
||||
dir.resolve(".werkator.yml").toFile().writeText(
|
||||
"""
|
||||
builds:
|
||||
pitest:
|
||||
@@ -221,8 +281,8 @@ class ConfigLoaderTest : FunSpec() {
|
||||
buildCommand: ./gradlew piTestPartial
|
||||
""".trimIndent(),
|
||||
)
|
||||
val worktree = Files.createTempDirectory("gittally-test-worktree")
|
||||
worktree.resolve(".gittally.yml").toFile().writeText(
|
||||
val worktree = Files.createTempDirectory("werkator-test-worktree")
|
||||
worktree.resolve(".werkator.yml").toFile().writeText(
|
||||
"""
|
||||
builds:
|
||||
pitest:
|
||||
@@ -246,21 +306,21 @@ class ConfigLoaderTest : FunSpec() {
|
||||
}
|
||||
|
||||
test("a branch cannot raise the concurrency limit or reach the sandbox policy through a build definition") {
|
||||
val dir = Files.createTempDirectory("gittally-test")
|
||||
dir.resolve(".gittally.yml").toFile().writeText(
|
||||
val dir = Files.createTempDirectory("werkator-test")
|
||||
dir.resolve(".werkator.yml").toFile().writeText(
|
||||
"""
|
||||
builds:
|
||||
default:
|
||||
requirePullRequest: true
|
||||
statusContext: GitTally
|
||||
statusContext: werkator
|
||||
docker:
|
||||
enabled: true
|
||||
network: none
|
||||
image: host-image
|
||||
""".trimIndent(),
|
||||
)
|
||||
val worktree = Files.createTempDirectory("gittally-test-worktree")
|
||||
worktree.resolve(".gittally.yml").toFile().writeText(
|
||||
val worktree = Files.createTempDirectory("werkator-test-worktree")
|
||||
worktree.resolve(".werkator.yml").toFile().writeText(
|
||||
"""
|
||||
executor:
|
||||
maxConcurrent: 99
|
||||
@@ -269,7 +329,7 @@ class ConfigLoaderTest : FunSpec() {
|
||||
builds:
|
||||
default:
|
||||
requirePullRequest: false
|
||||
statusContext: GitTally/impersonated
|
||||
statusContext: werkator/impersonated
|
||||
docker:
|
||||
enabled: false
|
||||
network: host
|
||||
@@ -285,14 +345,14 @@ class ConfigLoaderTest : FunSpec() {
|
||||
settings.requirePullRequest shouldBe true
|
||||
settings.docker.enabled shouldBe true
|
||||
settings.docker.network shouldBe "none"
|
||||
settings.statusContext shouldBe "GitTally"
|
||||
settings.statusContext shouldBe "werkator"
|
||||
// everything that describes the build itself stays the branch's own business
|
||||
settings.docker.image shouldBe "attacker-image"
|
||||
}
|
||||
|
||||
test("a build the branch invents inherits the host's sandbox policy") {
|
||||
val dir = Files.createTempDirectory("gittally-test")
|
||||
dir.resolve(".gittally.yml").toFile().writeText(
|
||||
val dir = Files.createTempDirectory("werkator-test")
|
||||
dir.resolve(".werkator.yml").toFile().writeText(
|
||||
"""
|
||||
builds:
|
||||
default:
|
||||
@@ -302,8 +362,8 @@ class ConfigLoaderTest : FunSpec() {
|
||||
network: none
|
||||
""".trimIndent(),
|
||||
)
|
||||
val worktree = Files.createTempDirectory("gittally-test-worktree")
|
||||
worktree.resolve(".gittally.yml").toFile().writeText(
|
||||
val worktree = Files.createTempDirectory("werkator-test-worktree")
|
||||
worktree.resolve(".werkator.yml").toFile().writeText(
|
||||
"""
|
||||
builds:
|
||||
invented:
|
||||
@@ -327,8 +387,8 @@ class ConfigLoaderTest : FunSpec() {
|
||||
}
|
||||
|
||||
test("an exclusion pattern takes a branch out of a build that would otherwise select it") {
|
||||
val dir = Files.createTempDirectory("gittally-test")
|
||||
dir.resolve(".gittally.yml").toFile().writeText(
|
||||
val dir = Files.createTempDirectory("werkator-test")
|
||||
dir.resolve(".werkator.yml").toFile().writeText(
|
||||
"""
|
||||
builds:
|
||||
default:
|
||||
@@ -374,8 +434,8 @@ class ConfigLoaderTest : FunSpec() {
|
||||
}
|
||||
|
||||
test("a trigger key written outside the trigger block is refused, naming the definition") {
|
||||
val dir = Files.createTempDirectory("gittally-test")
|
||||
dir.resolve(".gittally.yml").toFile().writeText(
|
||||
val dir = Files.createTempDirectory("werkator-test")
|
||||
dir.resolve(".werkator.yml").toFile().writeText(
|
||||
"""
|
||||
builds:
|
||||
nightly:
|
||||
@@ -388,14 +448,14 @@ class ConfigLoaderTest : FunSpec() {
|
||||
// stops running is worse than a configuration that refuses to load
|
||||
val thrown = shouldThrow<ConfigFormatException> { loader.load(dir) }
|
||||
|
||||
thrown.message.shouldContain(".gittally.yml")
|
||||
thrown.message.shouldContain(".werkator.yml")
|
||||
thrown.message.shouldContain("builds.nightly: atTimes")
|
||||
thrown.message.shouldContain("trigger:")
|
||||
}
|
||||
|
||||
test("a branch writing its trigger flat fails only its own builds") {
|
||||
val dir = Files.createTempDirectory("gittally-test")
|
||||
dir.resolve(".gittally.yml").toFile().writeText(
|
||||
val dir = Files.createTempDirectory("werkator-test")
|
||||
dir.resolve(".werkator.yml").toFile().writeText(
|
||||
"""
|
||||
builds:
|
||||
default:
|
||||
@@ -424,8 +484,8 @@ class ConfigLoaderTest : FunSpec() {
|
||||
}
|
||||
|
||||
test("builds.default is the base of every other build, but never its trigger") {
|
||||
val dir = Files.createTempDirectory("gittally-test")
|
||||
dir.resolve(".gittally.yml").toFile().writeText(
|
||||
val dir = Files.createTempDirectory("werkator-test")
|
||||
dir.resolve(".werkator.yml").toFile().writeText(
|
||||
"""
|
||||
builds:
|
||||
default:
|
||||
@@ -455,7 +515,7 @@ class ConfigLoaderTest : FunSpec() {
|
||||
}
|
||||
|
||||
test("branches is honored while no build is defined and ignored as soon as one is") {
|
||||
val dir = Files.createTempDirectory("gittally-test")
|
||||
val dir = Files.createTempDirectory("werkator-test")
|
||||
val legacy =
|
||||
"""
|
||||
branches:
|
||||
@@ -464,14 +524,14 @@ class ConfigLoaderTest : FunSpec() {
|
||||
docker:
|
||||
enabled: true
|
||||
""".trimIndent()
|
||||
dir.resolve(".gittally.yml").toFile().writeText(legacy)
|
||||
dir.resolve(".werkator.yml").toFile().writeText(legacy)
|
||||
|
||||
// the leftover execution key is not a definition, so the legacy section still wins
|
||||
loader.load(dir).buildSettings("main", "default").buildCommand shouldBe "from-branches"
|
||||
dir.resolve(".gittally.yml").toFile().writeText("builds:\n maxConcurrent: 1\n" + legacy)
|
||||
dir.resolve(".werkator.yml").toFile().writeText("builds:\n maxConcurrent: 1\n" + legacy)
|
||||
loader.load(dir).buildSettings("main", "default").buildCommand shouldBe "from-branches"
|
||||
|
||||
dir.resolve(".gittally.yml").toFile().writeText(
|
||||
dir.resolve(".werkator.yml").toFile().writeText(
|
||||
legacy +
|
||||
"\n" +
|
||||
"""
|
||||
@@ -487,8 +547,8 @@ class ConfigLoaderTest : FunSpec() {
|
||||
}
|
||||
|
||||
test("repo install config overrides project config for same keys") {
|
||||
val dir = Files.createTempDirectory("gittally-test")
|
||||
dir.resolve(".gittally.yml").toFile().writeText(
|
||||
val dir = Files.createTempDirectory("werkator-test")
|
||||
dir.resolve(".werkator.yml").toFile().writeText(
|
||||
"""
|
||||
gitea:
|
||||
owner: original-org
|
||||
@@ -496,8 +556,8 @@ class ConfigLoaderTest : FunSpec() {
|
||||
token: from-project
|
||||
""".trimIndent(),
|
||||
)
|
||||
dir.resolve(".git/gittally").toFile().mkdirs()
|
||||
dir.resolve(".git/gittally/.gittally.yml").toFile().writeText(
|
||||
dir.resolve(".git/werkator").toFile().mkdirs()
|
||||
dir.resolve(".git/werkator/.werkator.yml").toFile().writeText(
|
||||
"""
|
||||
gitea:
|
||||
owner: override-org
|
||||
@@ -511,8 +571,8 @@ class ConfigLoaderTest : FunSpec() {
|
||||
}
|
||||
|
||||
test("loadRaw only returns explicitly set values") {
|
||||
val dir = Files.createTempDirectory("gittally-test")
|
||||
dir.resolve(".gittally.yml").toFile().writeText(
|
||||
val dir = Files.createTempDirectory("werkator-test")
|
||||
dir.resolve(".werkator.yml").toFile().writeText(
|
||||
"""
|
||||
branches:
|
||||
default:
|
||||
@@ -528,8 +588,8 @@ class ConfigLoaderTest : FunSpec() {
|
||||
}
|
||||
|
||||
test("branch-specific config inherits from branches.default") {
|
||||
val dir = Files.createTempDirectory("gittally-test")
|
||||
dir.resolve(".gittally.yml").toFile().writeText(
|
||||
val dir = Files.createTempDirectory("werkator-test")
|
||||
dir.resolve(".werkator.yml").toFile().writeText(
|
||||
"""
|
||||
branches:
|
||||
default:
|
||||
@@ -545,8 +605,8 @@ class ConfigLoaderTest : FunSpec() {
|
||||
}
|
||||
|
||||
test("branch-specific buildCommand overrides branches.default") {
|
||||
val dir = Files.createTempDirectory("gittally-test")
|
||||
dir.resolve(".gittally.yml").toFile().writeText(
|
||||
val dir = Files.createTempDirectory("werkator-test")
|
||||
dir.resolve(".werkator.yml").toFile().writeText(
|
||||
"""
|
||||
branches:
|
||||
default:
|
||||
@@ -560,8 +620,8 @@ class ConfigLoaderTest : FunSpec() {
|
||||
}
|
||||
|
||||
test("empty publicBaseUrl defaults to https://<nginx.serverName>/ when set") {
|
||||
val dir = Files.createTempDirectory("gittally-test")
|
||||
dir.resolve(".gittally.yml").toFile().writeText(
|
||||
val dir = Files.createTempDirectory("werkator-test")
|
||||
dir.resolve(".werkator.yml").toFile().writeText(
|
||||
"""
|
||||
server:
|
||||
nginx:
|
||||
@@ -572,8 +632,8 @@ class ConfigLoaderTest : FunSpec() {
|
||||
}
|
||||
|
||||
test("explicit publicBaseUrl wins over the nginx.serverName default") {
|
||||
val dir = Files.createTempDirectory("gittally-test")
|
||||
dir.resolve(".gittally.yml").toFile().writeText(
|
||||
val dir = Files.createTempDirectory("werkator-test")
|
||||
dir.resolve(".werkator.yml").toFile().writeText(
|
||||
"""
|
||||
server:
|
||||
publicBaseUrl: https://other.example.org/
|
||||
@@ -585,29 +645,29 @@ class ConfigLoaderTest : FunSpec() {
|
||||
}
|
||||
|
||||
test("publicBaseUrl stays empty without an nginx.serverName") {
|
||||
val dir = Files.createTempDirectory("gittally-test")
|
||||
val dir = Files.createTempDirectory("werkator-test")
|
||||
loader.load(dir).server.publicBaseUrl shouldBe ""
|
||||
}
|
||||
|
||||
test("loadForWorktree lets the worktree override build config (worktree > .git > project)") {
|
||||
val dir = Files.createTempDirectory("gittally-test")
|
||||
dir.resolve(".gittally.yml").toFile().writeText(
|
||||
val dir = Files.createTempDirectory("werkator-test")
|
||||
dir.resolve(".werkator.yml").toFile().writeText(
|
||||
"""
|
||||
branches:
|
||||
default:
|
||||
buildCommand: from-project
|
||||
""".trimIndent(),
|
||||
)
|
||||
dir.resolve(".git/gittally").toFile().mkdirs()
|
||||
dir.resolve(".git/gittally/.gittally.yml").toFile().writeText(
|
||||
dir.resolve(".git/werkator").toFile().mkdirs()
|
||||
dir.resolve(".git/werkator/.werkator.yml").toFile().writeText(
|
||||
"""
|
||||
branches:
|
||||
default:
|
||||
buildCommand: from-git
|
||||
""".trimIndent(),
|
||||
)
|
||||
val worktree = Files.createTempDirectory("gittally-worktree")
|
||||
worktree.resolve(".gittally.yml").toFile().writeText(
|
||||
val worktree = Files.createTempDirectory("werkator-worktree")
|
||||
worktree.resolve(".werkator.yml").toFile().writeText(
|
||||
"""
|
||||
branches:
|
||||
default:
|
||||
@@ -618,30 +678,30 @@ class ConfigLoaderTest : FunSpec() {
|
||||
}
|
||||
|
||||
test("loadForWorktree falls back to .git over project when the worktree sets nothing") {
|
||||
val dir = Files.createTempDirectory("gittally-test")
|
||||
dir.resolve(".gittally.yml").toFile().writeText(
|
||||
val dir = Files.createTempDirectory("werkator-test")
|
||||
dir.resolve(".werkator.yml").toFile().writeText(
|
||||
"""
|
||||
branches:
|
||||
default:
|
||||
buildCommand: from-project
|
||||
""".trimIndent(),
|
||||
)
|
||||
dir.resolve(".git/gittally").toFile().mkdirs()
|
||||
dir.resolve(".git/gittally/.gittally.yml").toFile().writeText(
|
||||
dir.resolve(".git/werkator").toFile().mkdirs()
|
||||
dir.resolve(".git/werkator/.werkator.yml").toFile().writeText(
|
||||
"""
|
||||
branches:
|
||||
default:
|
||||
buildCommand: from-git
|
||||
""".trimIndent(),
|
||||
)
|
||||
val worktree = Files.createTempDirectory("gittally-worktree")
|
||||
val worktree = Files.createTempDirectory("werkator-worktree")
|
||||
loader.loadForWorktree(dir, worktree).branches["default"]!!.buildCommand shouldBe "from-git"
|
||||
}
|
||||
|
||||
test("loadForWorktree pins secrets and the docker sandbox policy to .git, but allows docker.image") {
|
||||
val dir = Files.createTempDirectory("gittally-test")
|
||||
dir.resolve(".git/gittally").toFile().mkdirs()
|
||||
dir.resolve(".git/gittally/.gittally.yml").toFile().writeText(
|
||||
val dir = Files.createTempDirectory("werkator-test")
|
||||
dir.resolve(".git/werkator").toFile().mkdirs()
|
||||
dir.resolve(".git/werkator/.werkator.yml").toFile().writeText(
|
||||
"""
|
||||
git:
|
||||
token: real-secret
|
||||
@@ -655,8 +715,8 @@ class ConfigLoaderTest : FunSpec() {
|
||||
image: trusted-image
|
||||
""".trimIndent(),
|
||||
)
|
||||
val worktree = Files.createTempDirectory("gittally-worktree")
|
||||
worktree.resolve(".gittally.yml").toFile().writeText(
|
||||
val worktree = Files.createTempDirectory("werkator-worktree")
|
||||
worktree.resolve(".werkator.yml").toFile().writeText(
|
||||
"""
|
||||
git:
|
||||
token: stolen
|
||||
@@ -681,9 +741,9 @@ class ConfigLoaderTest : FunSpec() {
|
||||
}
|
||||
|
||||
test("loadWithBranchLayer applies a branch config read from git, pinning the same keys") {
|
||||
val dir = Files.createTempDirectory("gittally-test")
|
||||
dir.resolve(".git/gittally").toFile().mkdirs()
|
||||
dir.resolve(".git/gittally/.gittally.yml").toFile().writeText(
|
||||
val dir = Files.createTempDirectory("werkator-test")
|
||||
dir.resolve(".git/werkator").toFile().mkdirs()
|
||||
dir.resolve(".git/werkator/.werkator.yml").toFile().writeText(
|
||||
"""
|
||||
git:
|
||||
token: real-secret
|
||||
@@ -717,8 +777,8 @@ class ConfigLoaderTest : FunSpec() {
|
||||
}
|
||||
|
||||
test("loadWithBranchLayer without a branch config equals load") {
|
||||
val dir = Files.createTempDirectory("gittally-test")
|
||||
dir.resolve(".gittally.yml").toFile().writeText(
|
||||
val dir = Files.createTempDirectory("werkator-test")
|
||||
dir.resolve(".werkator.yml").toFile().writeText(
|
||||
"""
|
||||
branches:
|
||||
default:
|
||||
@@ -731,8 +791,8 @@ class ConfigLoaderTest : FunSpec() {
|
||||
}
|
||||
|
||||
test("loadForWorktree without a worktree config equals load") {
|
||||
val dir = Files.createTempDirectory("gittally-test")
|
||||
dir.resolve(".gittally.yml").toFile().writeText(
|
||||
val dir = Files.createTempDirectory("werkator-test")
|
||||
dir.resolve(".werkator.yml").toFile().writeText(
|
||||
"""
|
||||
gitea:
|
||||
owner: my-org
|
||||
@@ -741,12 +801,12 @@ class ConfigLoaderTest : FunSpec() {
|
||||
buildCommand: ./mvnw test
|
||||
""".trimIndent(),
|
||||
)
|
||||
val worktree = Files.createTempDirectory("gittally-worktree")
|
||||
val worktree = Files.createTempDirectory("werkator-worktree")
|
||||
loader.loadForWorktree(dir, worktree) shouldBe loader.load(dir)
|
||||
}
|
||||
|
||||
test("toYaml serializes GitTallyConfig with all sections") {
|
||||
val yaml = loader.toYaml(GitTallyConfig())
|
||||
test("toYaml serializes WerkatorConfig with all sections") {
|
||||
val yaml = loader.toYaml(WerkatorConfig())
|
||||
yaml shouldContain "server:"
|
||||
yaml shouldContain "git:"
|
||||
yaml shouldContain "gitea:"
|
||||
+4
-4
@@ -1,4 +1,4 @@
|
||||
package de.hoennig.gittally.config
|
||||
package de.hoennig.werkator.config
|
||||
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.nulls.shouldBeNull
|
||||
@@ -14,7 +14,7 @@ class ConfigVersionsTest : FunSpec() {
|
||||
) = ConfigVersions.verdict(VersionRequirement(since = since, below = below), running)
|
||||
|
||||
init {
|
||||
test("a file needing a newer GitTally is refused, naming both versions") {
|
||||
test("a file needing a newer Werkator is refused, naming both versions") {
|
||||
val result = verdict(since = "0.9.16", running = "0.9.15")
|
||||
|
||||
result
|
||||
@@ -45,7 +45,7 @@ class ConfigVersionsTest : FunSpec() {
|
||||
val description = "`builds:` is now `buildSpec:`"
|
||||
val written14 = VersionRequirement(since = "1.4.0")
|
||||
|
||||
// no ceiling declared, and none needed: GitTally knows its own breaking change
|
||||
// no ceiling declared, and none needed: Werkator knows its own breaking change
|
||||
ConfigVersions
|
||||
.verdict(written14, "2.0.1", brokeIn, description)
|
||||
.shouldBeInstanceOf<VersionVerdict.Incompatible>()
|
||||
@@ -54,7 +54,7 @@ class ConfigVersionsTest : FunSpec() {
|
||||
it shouldContain "2.0.0"
|
||||
it shouldContain "buildSpec"
|
||||
}
|
||||
// a GitTally from before the change still reads that file
|
||||
// a Werkator from before the change still reads that file
|
||||
ConfigVersions.verdict(written14, "1.9.0", brokeIn, description) shouldBe VersionVerdict.Compatible
|
||||
// and a file written after the change is fine on both sides of it
|
||||
ConfigVersions.verdict(
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package de.hoennig.gittally.config
|
||||
package de.hoennig.werkator.config
|
||||
|
||||
import io.kotest.assertions.throwables.shouldThrow
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package de.hoennig.gittally.framework
|
||||
package de.hoennig.werkator.framework
|
||||
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.shouldBe
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package de.hoennig.gittally.framework
|
||||
package de.hoennig.werkator.framework
|
||||
|
||||
import com.ninjasquad.springmockk.MockkBean
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package de.hoennig.gittally.framework
|
||||
package de.hoennig.werkator.framework
|
||||
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.shouldBe
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package de.hoennig.gittally.framework
|
||||
package de.hoennig.werkator.framework
|
||||
|
||||
import com.github.tomakehurst.wiremock.WireMockServer
|
||||
import com.github.tomakehurst.wiremock.client.WireMock.aResponse
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
package de.hoennig.gittally.git
|
||||
package de.hoennig.werkator.git
|
||||
|
||||
import io.kotest.assertions.throwables.shouldThrow
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
@@ -11,7 +11,7 @@ import kotlin.io.path.exists
|
||||
|
||||
class GitAskPassTest : FunSpec() {
|
||||
private val runner = GitCommandRunner()
|
||||
private val tempDir = Files.createTempDirectory("gittally-askpass-test")
|
||||
private val tempDir = Files.createTempDirectory("werkator-askpass-test")
|
||||
|
||||
private fun runScript(
|
||||
environment: Map<String, String>,
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
package de.hoennig.gittally.git
|
||||
package de.hoennig.werkator.git
|
||||
|
||||
import io.kotest.assertions.throwables.shouldThrow
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
@@ -12,7 +12,7 @@ import java.nio.file.Files
|
||||
|
||||
class GitCommandRunnerTest : FunSpec() {
|
||||
private val runner = GitCommandRunner()
|
||||
private val tempDir = Files.createTempDirectory("gittally-runner-test")
|
||||
private val tempDir = Files.createTempDirectory("werkator-runner-test")
|
||||
|
||||
init {
|
||||
test("captures stdout, stderr and exit code") {
|
||||
@@ -41,7 +41,7 @@ class GitCommandRunnerTest : FunSpec() {
|
||||
}
|
||||
|
||||
test("passes extra environment variables") {
|
||||
val result = runner.run(listOf("sh", "-c", "echo \"\$GITTALLY_TEST_VAR\""), tempDir, mapOf("GITTALLY_TEST_VAR" to "hello"))
|
||||
val result = runner.run(listOf("sh", "-c", "echo \"\$WERKATOR_TEST_VAR\""), tempDir, mapOf("WERKATOR_TEST_VAR" to "hello"))
|
||||
|
||||
result.stdout.trim() shouldBe "hello"
|
||||
}
|
||||
+8
-8
@@ -1,6 +1,6 @@
|
||||
package de.hoennig.gittally.git
|
||||
package de.hoennig.werkator.git
|
||||
|
||||
import de.hoennig.gittally.config.ConfigLoader
|
||||
import de.hoennig.werkator.config.ConfigLoader
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.booleans.shouldBeFalse
|
||||
import io.kotest.matchers.booleans.shouldBeTrue
|
||||
@@ -27,16 +27,16 @@ class GitServiceTest : FunSpec() {
|
||||
// hermetic git: fixed identity, no user/system config (hooks, gpg signing, ...)
|
||||
private val gitEnvironment =
|
||||
mapOf(
|
||||
"GIT_AUTHOR_NAME" to "GitTally Test",
|
||||
"GIT_AUTHOR_NAME" to "Werkator Test",
|
||||
"GIT_AUTHOR_EMAIL" to "test@example.com",
|
||||
"GIT_COMMITTER_NAME" to "GitTally Test",
|
||||
"GIT_COMMITTER_NAME" to "Werkator Test",
|
||||
"GIT_COMMITTER_EMAIL" to "test@example.com",
|
||||
"GIT_CONFIG_GLOBAL" to "/dev/null",
|
||||
"GIT_CONFIG_SYSTEM" to "/dev/null",
|
||||
)
|
||||
|
||||
private inner class Fixture {
|
||||
val root: Path = Files.createTempDirectory("gittally-git-test")
|
||||
val root: Path = Files.createTempDirectory("werkator-git-test")
|
||||
val origin: Path = root.resolve("origin.git")
|
||||
val seed: Path = root.resolve("seed")
|
||||
val work: Path = root.resolve("work")
|
||||
@@ -310,7 +310,7 @@ class GitServiceTest : FunSpec() {
|
||||
test("worktreeAdd creates a detached worktree at the commit") {
|
||||
val fixture = Fixture()
|
||||
val head = service.headCommit(fixture.work)
|
||||
val worktree = fixture.work.resolve(".git/gittally/worktrees/main-test")
|
||||
val worktree = fixture.work.resolve(".git/werkator/worktrees/main-test")
|
||||
|
||||
service.worktreeAdd(worktree, head, fixture.work)
|
||||
|
||||
@@ -324,7 +324,7 @@ class GitServiceTest : FunSpec() {
|
||||
val firstCommit = service.headCommit(fixture.work)
|
||||
fixture.commitFile(fixture.work, "second.txt", "second")
|
||||
val secondCommit = service.headCommit(fixture.work)
|
||||
val worktree = fixture.work.resolve(".git/gittally/worktrees/main-test")
|
||||
val worktree = fixture.work.resolve(".git/werkator/worktrees/main-test")
|
||||
service.worktreeAdd(worktree, firstCommit, fixture.work)
|
||||
Files.writeString(worktree.resolve("README.md"), "dirty")
|
||||
|
||||
@@ -338,7 +338,7 @@ class GitServiceTest : FunSpec() {
|
||||
test("worktreePrune allows re-adding a worktree whose directory was deleted") {
|
||||
val fixture = Fixture()
|
||||
val head = service.headCommit(fixture.work)
|
||||
val worktree = fixture.work.resolve(".git/gittally/worktrees/main-test")
|
||||
val worktree = fixture.work.resolve(".git/werkator/worktrees/main-test")
|
||||
service.worktreeAdd(worktree, head, fixture.work)
|
||||
worktree.toFile().deleteRecursively()
|
||||
|
||||
+17
-17
@@ -1,4 +1,4 @@
|
||||
package de.hoennig.gittally.gitea
|
||||
package de.hoennig.werkator.gitea
|
||||
|
||||
import com.github.tomakehurst.wiremock.WireMockServer
|
||||
import com.github.tomakehurst.wiremock.client.WireMock.aResponse
|
||||
@@ -12,11 +12,11 @@ import com.github.tomakehurst.wiremock.client.WireMock.post
|
||||
import com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor
|
||||
import com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo
|
||||
import com.github.tomakehurst.wiremock.core.WireMockConfiguration.options
|
||||
import de.hoennig.gittally.build.BuildStatus
|
||||
import de.hoennig.gittally.config.ConfigLoader
|
||||
import de.hoennig.gittally.config.GitConfig
|
||||
import de.hoennig.gittally.config.GitTallyConfig
|
||||
import de.hoennig.gittally.config.GiteaConfig
|
||||
import de.hoennig.werkator.build.BuildStatus
|
||||
import de.hoennig.werkator.config.ConfigLoader
|
||||
import de.hoennig.werkator.config.GitConfig
|
||||
import de.hoennig.werkator.config.GiteaConfig
|
||||
import de.hoennig.werkator.config.WerkatorConfig
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.nulls.shouldBeNull
|
||||
import io.kotest.matchers.shouldBe
|
||||
@@ -41,9 +41,9 @@ class GiteaClientTest :
|
||||
token: String = "secret-token",
|
||||
) {
|
||||
every { configLoader.load(any()) } returns
|
||||
GitTallyConfig(
|
||||
WerkatorConfig(
|
||||
git = GitConfig(token = token),
|
||||
gitea = GiteaConfig(baseUrl = baseUrl, owner = owner, repo = repo, statusContext = "GitTally"),
|
||||
gitea = GiteaConfig(baseUrl = baseUrl, owner = owner, repo = repo, statusContext = "werkator"),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ class GiteaClientTest :
|
||||
"""
|
||||
{
|
||||
"state": "success",
|
||||
"context": "GitTally",
|
||||
"context": "werkator",
|
||||
"description": "Build succeeded",
|
||||
"target_url": "https://ci.example.org/branches/main/index.html"
|
||||
}
|
||||
@@ -111,12 +111,12 @@ class GiteaClientTest :
|
||||
sha = "abc123",
|
||||
status = BuildStatus.SUCCESS,
|
||||
description = "d",
|
||||
context = "GitTally/quick",
|
||||
context = "werkator/quick",
|
||||
) shouldBe true
|
||||
|
||||
server.verify(
|
||||
postRequestedFor(urlEqualTo(publishUrl))
|
||||
.withRequestBody(matchingJsonPath("${'$'}.context", equalTo("GitTally/quick"))),
|
||||
.withRequestBody(matchingJsonPath("${'$'}.context", equalTo("werkator/quick"))),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ class GiteaClientTest :
|
||||
|
||||
server.verify(
|
||||
postRequestedFor(urlEqualTo(publishUrl))
|
||||
.withRequestBody(matchingJsonPath("${'$'}.context", equalTo("GitTally"))),
|
||||
.withRequestBody(matchingJsonPath("${'$'}.context", equalTo("werkator"))),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -139,7 +139,7 @@ class GiteaClientTest :
|
||||
server.verify(
|
||||
postRequestedFor(urlEqualTo(publishUrl))
|
||||
.withRequestBody(
|
||||
equalToJson("""{"state": "pending", "context": "GitTally", "description": "Build running"}"""),
|
||||
equalToJson("""{"state": "pending", "context": "werkator", "description": "Build running"}"""),
|
||||
),
|
||||
)
|
||||
}
|
||||
@@ -162,7 +162,7 @@ class GiteaClientTest :
|
||||
client.publishStatus("abc123", status, "d") shouldBe true
|
||||
server.verify(
|
||||
postRequestedFor(urlEqualTo(publishUrl))
|
||||
.withRequestBody(equalToJson("""{"state": "$state", "context": "GitTally", "description": "d"}""")),
|
||||
.withRequestBody(equalToJson("""{"state": "$state", "context": "werkator", "description": "d"}""")),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -207,8 +207,8 @@ class GiteaClientTest :
|
||||
"""
|
||||
[
|
||||
{"context": "other-ci", "state": "failure"},
|
||||
{"context": "GitTally", "state": "success", "description": "Build succeeded"},
|
||||
{"context": "GitTally", "state": "pending"}
|
||||
{"context": "werkator", "state": "success", "description": "Build succeeded"},
|
||||
{"context": "werkator", "state": "pending"}
|
||||
]
|
||||
""".trimIndent(),
|
||||
),
|
||||
@@ -237,7 +237,7 @@ class GiteaClientTest :
|
||||
}
|
||||
|
||||
test("returns Error for an unknown state value") {
|
||||
server.stubFor(get(readUrl).willReturn(okJson("""[{"context": "GitTally", "state": "hovering"}]""")))
|
||||
server.stubFor(get(readUrl).willReturn(okJson("""[{"context": "werkator", "state": "hovering"}]""")))
|
||||
|
||||
client.readStatus("abc123").shouldBeInstanceOf<GiteaStatusResult.Error>()
|
||||
}
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
package de.hoennig.gittally.gitea
|
||||
package de.hoennig.werkator.gitea
|
||||
|
||||
import de.hoennig.gittally.build.BuildStatus
|
||||
import de.hoennig.werkator.build.BuildStatus
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.nulls.shouldBeNull
|
||||
import io.kotest.matchers.shouldBe
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
package de.hoennig.gittally.metrics
|
||||
package de.hoennig.werkator.metrics
|
||||
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.nulls.shouldNotBeNull
|
||||
@@ -50,7 +50,7 @@ class SystemMetricsCollectorTest : FunSpec() {
|
||||
|
||||
init {
|
||||
beforeEach {
|
||||
tempDir = Files.createTempDirectory("gittally-metrics-test")
|
||||
tempDir = Files.createTempDirectory("werkator-metrics-test")
|
||||
}
|
||||
|
||||
afterEach {
|
||||
+5
-5
@@ -1,9 +1,9 @@
|
||||
package de.hoennig.gittally.server
|
||||
package de.hoennig.werkator.server
|
||||
|
||||
import com.ninjasquad.springmockk.MockkBean
|
||||
import de.hoennig.gittally.build.ArtifactStore
|
||||
import de.hoennig.gittally.build.BuildResult
|
||||
import de.hoennig.gittally.build.BuildStatus
|
||||
import de.hoennig.werkator.build.ArtifactStore
|
||||
import de.hoennig.werkator.build.BuildResult
|
||||
import de.hoennig.werkator.build.BuildStatus
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.mockk.clearMocks
|
||||
import io.mockk.every
|
||||
@@ -32,7 +32,7 @@ class ArtifactFileControllerTest : FunSpec() {
|
||||
@MockkBean
|
||||
lateinit var branchPermalinks: BranchPermalinks
|
||||
|
||||
private val artifactDir: Path = Files.createTempDirectory("gittally-artifact-serve-test")
|
||||
private val artifactDir: Path = Files.createTempDirectory("werkator-artifact-serve-test")
|
||||
|
||||
private val greenBuild =
|
||||
BuildResult(
|
||||
+5
-5
@@ -1,9 +1,9 @@
|
||||
package de.hoennig.gittally.server
|
||||
package de.hoennig.werkator.server
|
||||
|
||||
import de.hoennig.gittally.build.BuildResult
|
||||
import de.hoennig.gittally.build.BuildResultRepository
|
||||
import de.hoennig.gittally.build.BuildStatus
|
||||
import de.hoennig.gittally.git.GitService
|
||||
import de.hoennig.werkator.build.BuildResult
|
||||
import de.hoennig.werkator.build.BuildResultRepository
|
||||
import de.hoennig.werkator.build.BuildStatus
|
||||
import de.hoennig.werkator.git.GitService
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.shouldBe
|
||||
import io.mockk.every
|
||||
+5
-5
@@ -1,9 +1,9 @@
|
||||
package de.hoennig.gittally.server
|
||||
package de.hoennig.werkator.server
|
||||
|
||||
import de.hoennig.gittally.build.ArtifactKeys
|
||||
import de.hoennig.gittally.build.BuildResult
|
||||
import de.hoennig.gittally.build.BuildResultRepository
|
||||
import de.hoennig.gittally.build.BuildStatus
|
||||
import de.hoennig.werkator.build.ArtifactKeys
|
||||
import de.hoennig.werkator.build.BuildResult
|
||||
import de.hoennig.werkator.build.BuildResultRepository
|
||||
import de.hoennig.werkator.build.BuildStatus
|
||||
import io.kotest.assertions.throwables.shouldThrow
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.shouldBe
|
||||
+9
-9
@@ -1,13 +1,13 @@
|
||||
package de.hoennig.gittally.server
|
||||
package de.hoennig.werkator.server
|
||||
|
||||
import com.ninjasquad.springmockk.MockkBean
|
||||
import de.hoennig.gittally.build.ArtifactStore
|
||||
import de.hoennig.gittally.build.BuildExecutor
|
||||
import de.hoennig.gittally.build.BuildResult
|
||||
import de.hoennig.gittally.build.BuildResultRepository
|
||||
import de.hoennig.gittally.build.BuildStatus
|
||||
import de.hoennig.gittally.build.RunningBuild
|
||||
import de.hoennig.gittally.git.GitService
|
||||
import de.hoennig.werkator.build.ArtifactStore
|
||||
import de.hoennig.werkator.build.BuildExecutor
|
||||
import de.hoennig.werkator.build.BuildResult
|
||||
import de.hoennig.werkator.build.BuildResultRepository
|
||||
import de.hoennig.werkator.build.BuildStatus
|
||||
import de.hoennig.werkator.build.RunningBuild
|
||||
import de.hoennig.werkator.git.GitService
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.mockk.clearMocks
|
||||
import io.mockk.every
|
||||
@@ -27,7 +27,7 @@ import java.time.Instant
|
||||
|
||||
@WebMvcTest(BuildsApiController::class, properties = ["spring.main.web-application-type=servlet"])
|
||||
class BuildsApiControllerTest : FunSpec() {
|
||||
private val tempDir: Path = Files.createTempDirectory("gittally-server-test")
|
||||
private val tempDir: Path = Files.createTempDirectory("werkator-server-test")
|
||||
|
||||
@Autowired
|
||||
lateinit var mockMvc: MockMvc
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
package de.hoennig.gittally.server
|
||||
package de.hoennig.werkator.server
|
||||
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.shouldBe
|
||||
@@ -8,7 +8,7 @@ import java.nio.file.Path
|
||||
import java.nio.file.attribute.PosixFilePermissions
|
||||
|
||||
class ControlTokenServiceTest : FunSpec() {
|
||||
private fun newTokenFile(): Path = Files.createTempDirectory("gittally-token-test").resolve("control-token")
|
||||
private fun newTokenFile(): Path = Files.createTempDirectory("werkator-token-test").resolve("control-token")
|
||||
|
||||
init {
|
||||
test("generates a hex token once and persists it") {
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package de.hoennig.gittally.server
|
||||
package de.hoennig.werkator.server
|
||||
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.string.shouldContain
|
||||
+22
-22
@@ -1,12 +1,12 @@
|
||||
package de.hoennig.gittally.server
|
||||
package de.hoennig.werkator.server
|
||||
|
||||
import de.hoennig.gittally.build.ArtifactKeys
|
||||
import de.hoennig.gittally.config.ConfigLoader
|
||||
import de.hoennig.gittally.config.GitTallyConfig
|
||||
import de.hoennig.gittally.config.NginxConfig
|
||||
import de.hoennig.gittally.config.ServerConfig
|
||||
import de.hoennig.gittally.git.GitCommandResult
|
||||
import de.hoennig.gittally.git.GitCommandRunner
|
||||
import de.hoennig.werkator.build.ArtifactKeys
|
||||
import de.hoennig.werkator.config.ConfigLoader
|
||||
import de.hoennig.werkator.config.NginxConfig
|
||||
import de.hoennig.werkator.config.ServerConfig
|
||||
import de.hoennig.werkator.config.WerkatorConfig
|
||||
import de.hoennig.werkator.git.GitCommandResult
|
||||
import de.hoennig.werkator.git.GitCommandRunner
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.booleans.shouldBeTrue
|
||||
import io.kotest.matchers.collections.shouldBeEmpty
|
||||
@@ -42,8 +42,8 @@ class NginxProxyManagerTest : FunSpec() {
|
||||
httpsPort: Int = 8443,
|
||||
explicitStateDir: Boolean = true,
|
||||
serverPort: Int = 18080,
|
||||
): GitTallyConfig =
|
||||
GitTallyConfig(
|
||||
): WerkatorConfig =
|
||||
WerkatorConfig(
|
||||
server =
|
||||
ServerConfig(
|
||||
port = serverPort,
|
||||
@@ -82,11 +82,11 @@ class NginxProxyManagerTest : FunSpec() {
|
||||
"--volume",
|
||||
"$stateDir/nginx/nginx.conf:/etc/nginx/nginx.conf:ro",
|
||||
"--label",
|
||||
"org.hoennig.gittally=true",
|
||||
"org.hoennig.werkator=true",
|
||||
"--label",
|
||||
"org.hoennig.gittally.repository=${ArtifactKeys.repoKey(repoDir)}",
|
||||
"org.hoennig.werkator.repository=${ArtifactKeys.repoKey(repoDir)}",
|
||||
"--label",
|
||||
"org.hoennig.gittally.role=nginx",
|
||||
"org.hoennig.werkator.role=nginx",
|
||||
"nginx",
|
||||
)
|
||||
|
||||
@@ -116,8 +116,8 @@ class NginxProxyManagerTest : FunSpec() {
|
||||
captured.clear()
|
||||
configsAtContainerRun.clear()
|
||||
sleepCount = 0
|
||||
repoDir = Files.createTempDirectory("gittally-nginx-repo")
|
||||
stateDir = Files.createTempDirectory("gittally-nginx-state")
|
||||
repoDir = Files.createTempDirectory("werkator-nginx-repo")
|
||||
stateDir = Files.createTempDirectory("werkator-nginx-state")
|
||||
every { commandRunner.run(capture(captured), any(), any(), any()) } answers {
|
||||
if (captured.last().take(3) == listOf("docker", "run", "-d")) {
|
||||
configsAtContainerRun += Files.readString(stateDir.resolve("nginx/nginx.conf"))
|
||||
@@ -145,8 +145,8 @@ class NginxProxyManagerTest : FunSpec() {
|
||||
|
||||
settings.upstreamHost shouldBe "ci.example.org"
|
||||
settings.upstreamPort shouldBe 18080
|
||||
settings.containerName shouldBe "gittally-nginx-${repoDir.fileName}"
|
||||
settings.stateDir.toString() shouldEndWith "gittally/nginx/${ArtifactKeys.repoKey(repoDir)}"
|
||||
settings.containerName shouldBe "werkator-nginx-${repoDir.fileName}"
|
||||
settings.stateDir.toString() shouldEndWith "werkator/nginx/${ArtifactKeys.repoKey(repoDir)}"
|
||||
}
|
||||
|
||||
test("rejects a server name that could inject nginx directives") {
|
||||
@@ -234,11 +234,11 @@ class NginxProxyManagerTest : FunSpec() {
|
||||
"ps",
|
||||
"-aq",
|
||||
"--filter",
|
||||
"label=org.hoennig.gittally=true",
|
||||
"label=org.hoennig.werkator=true",
|
||||
"--filter",
|
||||
"label=org.hoennig.gittally.repository=${ArtifactKeys.repoKey(repoDir)}",
|
||||
"label=org.hoennig.werkator.repository=${ArtifactKeys.repoKey(repoDir)}",
|
||||
"--filter",
|
||||
"label=org.hoennig.gittally.role=nginx",
|
||||
"label=org.hoennig.werkator.role=nginx",
|
||||
)
|
||||
captured shouldContain listOf("docker", "rm", "-f", "test-nginx")
|
||||
}
|
||||
@@ -255,13 +255,13 @@ class NginxProxyManagerTest : FunSpec() {
|
||||
sleepCount shouldBe 4
|
||||
}
|
||||
|
||||
test("removes a stale gittally-named container occupying an nginx port") {
|
||||
test("removes a stale werkator-named container occupying an nginx port") {
|
||||
every { configLoader.load(repoDir) } returns nginxConfig()
|
||||
every {
|
||||
commandRunner.run(match { it.take(2) == listOf("docker", "ps") && it.contains("--format") }, any(), any(), any())
|
||||
} returnsMany
|
||||
listOf(
|
||||
GitCommandResult(0, "abc123\tgittally-nginx-old\t0.0.0.0:8080->80/tcp\t", ""),
|
||||
GitCommandResult(0, "abc123\twerkator-nginx-old\t0.0.0.0:8080->80/tcp\t", ""),
|
||||
GitCommandResult(0, "", ""),
|
||||
)
|
||||
|
||||
+13
-13
@@ -1,15 +1,15 @@
|
||||
package de.hoennig.gittally.server
|
||||
package de.hoennig.werkator.server
|
||||
|
||||
import com.ninjasquad.springmockk.MockkBean
|
||||
import de.hoennig.gittally.build.ArtifactStore
|
||||
import de.hoennig.gittally.build.BuildExecutor
|
||||
import de.hoennig.gittally.build.BuildResult
|
||||
import de.hoennig.gittally.build.BuildResultRepository
|
||||
import de.hoennig.gittally.build.BuildStatus
|
||||
import de.hoennig.gittally.config.ConfigLoader
|
||||
import de.hoennig.gittally.config.GitTallyConfig
|
||||
import de.hoennig.gittally.git.GitService
|
||||
import de.hoennig.gittally.metrics.SystemMetricsCollector
|
||||
import de.hoennig.werkator.build.ArtifactStore
|
||||
import de.hoennig.werkator.build.BuildExecutor
|
||||
import de.hoennig.werkator.build.BuildResult
|
||||
import de.hoennig.werkator.build.BuildResultRepository
|
||||
import de.hoennig.werkator.build.BuildStatus
|
||||
import de.hoennig.werkator.config.ConfigLoader
|
||||
import de.hoennig.werkator.config.WerkatorConfig
|
||||
import de.hoennig.werkator.git.GitService
|
||||
import de.hoennig.werkator.metrics.SystemMetricsCollector
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.mockk.clearMocks
|
||||
import io.mockk.every
|
||||
@@ -65,7 +65,7 @@ class PermanentBranchRoutesTest : FunSpec() {
|
||||
@MockkBean
|
||||
lateinit var branchPermalinks: BranchPermalinks
|
||||
|
||||
private val artifactDir: Path = Files.createTempDirectory("gittally-permanent-routes-test")
|
||||
private val artifactDir: Path = Files.createTempDirectory("werkator-permanent-routes-test")
|
||||
|
||||
private val greenBuild =
|
||||
BuildResult(
|
||||
@@ -90,8 +90,8 @@ class PermanentBranchRoutesTest : FunSpec() {
|
||||
branchListing,
|
||||
branchPermalinks,
|
||||
)
|
||||
every { configLoader.load(any()) } returns GitTallyConfig()
|
||||
every { configLoader.loadWithBranchLayer(any(), anyNullable()) } returns GitTallyConfig()
|
||||
every { configLoader.load(any()) } returns WerkatorConfig()
|
||||
every { configLoader.loadWithBranchLayer(any(), anyNullable()) } returns WerkatorConfig()
|
||||
every { gitService.showFileAtCommit(any(), any(), any()) } returns null
|
||||
every { controlTokens.token() } returns "test-token"
|
||||
every { branchListing.branches(any()) } returns emptyList()
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package de.hoennig.gittally.server
|
||||
package de.hoennig.werkator.server
|
||||
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.shouldBe
|
||||
+6
-6
@@ -1,11 +1,11 @@
|
||||
package de.hoennig.gittally.server
|
||||
package de.hoennig.werkator.server
|
||||
|
||||
import com.ninjasquad.springmockk.MockkBean
|
||||
import de.hoennig.gittally.build.BuildResult
|
||||
import de.hoennig.gittally.build.BuildResultRepository
|
||||
import de.hoennig.gittally.build.BuildStatus
|
||||
import de.hoennig.gittally.gitea.GiteaClient
|
||||
import de.hoennig.gittally.gitea.GiteaStatusResult
|
||||
import de.hoennig.werkator.build.BuildResult
|
||||
import de.hoennig.werkator.build.BuildResultRepository
|
||||
import de.hoennig.werkator.build.BuildStatus
|
||||
import de.hoennig.werkator.gitea.GiteaClient
|
||||
import de.hoennig.werkator.gitea.GiteaStatusResult
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.mockk.clearMocks
|
||||
import io.mockk.every
|
||||
+4
-4
@@ -1,9 +1,9 @@
|
||||
package de.hoennig.gittally.server
|
||||
package de.hoennig.werkator.server
|
||||
|
||||
import com.ninjasquad.springmockk.MockkBean
|
||||
import de.hoennig.gittally.metrics.MetricAggregate
|
||||
import de.hoennig.gittally.metrics.SystemMetrics
|
||||
import de.hoennig.gittally.metrics.SystemMetricsCollector
|
||||
import de.hoennig.werkator.metrics.MetricAggregate
|
||||
import de.hoennig.werkator.metrics.SystemMetrics
|
||||
import de.hoennig.werkator.metrics.SystemMetricsCollector
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.mockk.clearMocks
|
||||
import io.mockk.every
|
||||
+22
-22
@@ -1,22 +1,22 @@
|
||||
package de.hoennig.gittally.server
|
||||
package de.hoennig.werkator.server
|
||||
|
||||
import com.ninjasquad.springmockk.MockkBean
|
||||
import de.hoennig.gittally.build.ArtifactStore
|
||||
import de.hoennig.gittally.build.BuildExecutor
|
||||
import de.hoennig.gittally.build.BuildResult
|
||||
import de.hoennig.gittally.build.BuildResultRepository
|
||||
import de.hoennig.gittally.build.BuildStatus
|
||||
import de.hoennig.gittally.build.RunningBuild
|
||||
import de.hoennig.gittally.config.BranchConfig
|
||||
import de.hoennig.gittally.config.BuildDefinition
|
||||
import de.hoennig.gittally.config.ConfigLoader
|
||||
import de.hoennig.gittally.config.GitTallyConfig
|
||||
import de.hoennig.gittally.config.GiteaConfig
|
||||
import de.hoennig.gittally.config.ServerConfig
|
||||
import de.hoennig.gittally.git.GitService
|
||||
import de.hoennig.gittally.metrics.MetricAggregate
|
||||
import de.hoennig.gittally.metrics.SystemMetrics
|
||||
import de.hoennig.gittally.metrics.SystemMetricsCollector
|
||||
import de.hoennig.werkator.build.ArtifactStore
|
||||
import de.hoennig.werkator.build.BuildExecutor
|
||||
import de.hoennig.werkator.build.BuildResult
|
||||
import de.hoennig.werkator.build.BuildResultRepository
|
||||
import de.hoennig.werkator.build.BuildStatus
|
||||
import de.hoennig.werkator.build.RunningBuild
|
||||
import de.hoennig.werkator.config.BranchConfig
|
||||
import de.hoennig.werkator.config.BuildDefinition
|
||||
import de.hoennig.werkator.config.ConfigLoader
|
||||
import de.hoennig.werkator.config.GiteaConfig
|
||||
import de.hoennig.werkator.config.ServerConfig
|
||||
import de.hoennig.werkator.config.WerkatorConfig
|
||||
import de.hoennig.werkator.git.GitService
|
||||
import de.hoennig.werkator.metrics.MetricAggregate
|
||||
import de.hoennig.werkator.metrics.SystemMetrics
|
||||
import de.hoennig.werkator.metrics.SystemMetricsCollector
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.shouldBe
|
||||
import io.kotest.matchers.string.shouldContain
|
||||
@@ -41,7 +41,7 @@ import java.time.Instant
|
||||
|
||||
@WebMvcTest(UiController::class, properties = ["spring.main.web-application-type=servlet"])
|
||||
class UiControllerTest : FunSpec() {
|
||||
private val tempDir: Path = Files.createTempDirectory("gittally-ui-test")
|
||||
private val tempDir: Path = Files.createTempDirectory("werkator-ui-test")
|
||||
|
||||
@Autowired
|
||||
lateinit var mockMvc: MockMvc
|
||||
@@ -115,11 +115,11 @@ class UiControllerTest : FunSpec() {
|
||||
branchPermalinks,
|
||||
)
|
||||
every { configLoader.load(any()) } returns
|
||||
GitTallyConfig(
|
||||
WerkatorConfig(
|
||||
server = ServerConfig(impressumUrl = "https://example.org/imprint"),
|
||||
gitea = GiteaConfig(baseUrl = "https://git.example.org", owner = "acme", repo = "widget"),
|
||||
)
|
||||
every { configLoader.loadWithBranchLayer(any(), anyNullable()) } returns GitTallyConfig()
|
||||
every { configLoader.loadWithBranchLayer(any(), anyNullable()) } returns WerkatorConfig()
|
||||
every { gitService.showFileAtCommit(any(), any(), any()) } returns null
|
||||
every { controlTokens.token() } returns "test-token"
|
||||
every { repository.latestGreenFor(any()) } returns null
|
||||
@@ -151,7 +151,7 @@ class UiControllerTest : FunSpec() {
|
||||
.andExpect(content().string(containsString("""data-action="restart"""")))
|
||||
.andExpect(content().string(containsString("""data-action="delete"""")))
|
||||
// the control token must never reach the browser: reading a page is unauthenticated
|
||||
.andExpect(content().string(not(containsString("gittally-control-token"))))
|
||||
.andExpect(content().string(not(containsString("werkator-control-token"))))
|
||||
.andExpect(content().string(not(containsString("test-token"))))
|
||||
.andExpect(content().string(containsString("https://example.org/imprint")))
|
||||
.andExpect(content().string(containsString("1:23")))
|
||||
@@ -283,7 +283,7 @@ class UiControllerTest : FunSpec() {
|
||||
every { repository.history() } returns listOf(pitestResult)
|
||||
every { artifactStore.artifactDir("main-pitest-key") } returns null
|
||||
every { configLoader.loadWithBranchLayer(any(), anyNullable()) } returns
|
||||
GitTallyConfig(
|
||||
WerkatorConfig(
|
||||
branches = mapOf("default" to BranchConfig(buildCommand = "./gradlew quick-check")),
|
||||
buildDefinitions = mapOf("pitest" to BuildDefinition(buildCommand = "./gradlew pitestFull")),
|
||||
)
|
||||
+4
-4
@@ -1,8 +1,8 @@
|
||||
package de.hoennig.gittally.server
|
||||
package de.hoennig.werkator.server
|
||||
|
||||
import de.hoennig.gittally.config.GiteaConfig
|
||||
import de.hoennig.gittally.metrics.MetricAggregate
|
||||
import de.hoennig.gittally.metrics.SystemMetrics
|
||||
import de.hoennig.werkator.config.GiteaConfig
|
||||
import de.hoennig.werkator.metrics.MetricAggregate
|
||||
import de.hoennig.werkator.metrics.SystemMetrics
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.shouldBe
|
||||
import java.time.Duration
|
||||
+3
-3
@@ -1,8 +1,8 @@
|
||||
package de.hoennig.gittally.server
|
||||
package de.hoennig.werkator.server
|
||||
|
||||
import com.ninjasquad.springmockk.MockkBean
|
||||
import de.hoennig.gittally.watcher.Watcher
|
||||
import de.hoennig.gittally.watcher.WatcherState
|
||||
import de.hoennig.werkator.watcher.Watcher
|
||||
import de.hoennig.werkator.watcher.WatcherState
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.mockk.clearMocks
|
||||
import io.mockk.every
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
package de.hoennig.gittally.watcher
|
||||
package de.hoennig.werkator.watcher
|
||||
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.booleans.shouldBeFalse
|
||||
@@ -11,7 +11,7 @@ import java.time.LocalDate
|
||||
import java.time.LocalTime
|
||||
|
||||
class AutoBuildStateTest : FunSpec() {
|
||||
private fun stateFile(): Path = Files.createTempDirectory("gittally-autobuild-test").resolve("auto-builds.json")
|
||||
private fun stateFile(): Path = Files.createTempDirectory("werkator-autobuild-test").resolve("auto-builds.json")
|
||||
|
||||
init {
|
||||
test("latestDueSlot picks the latest slot at or before now") {
|
||||
+57
-40
@@ -1,26 +1,26 @@
|
||||
package de.hoennig.gittally.watcher
|
||||
package de.hoennig.werkator.watcher
|
||||
|
||||
import ch.qos.logback.classic.Level
|
||||
import ch.qos.logback.classic.Logger
|
||||
import ch.qos.logback.classic.spi.ILoggingEvent
|
||||
import ch.qos.logback.core.read.ListAppender
|
||||
import de.hoennig.gittally.build.ArtifactKeys
|
||||
import de.hoennig.gittally.build.ArtifactStore
|
||||
import de.hoennig.gittally.build.BuildExecutor
|
||||
import de.hoennig.gittally.build.BuildResult
|
||||
import de.hoennig.gittally.build.BuildStatus
|
||||
import de.hoennig.gittally.build.FileBuildResultRepository
|
||||
import de.hoennig.gittally.build.GitWorktreeWorkspaces
|
||||
import de.hoennig.gittally.build.RunningBuild
|
||||
import de.hoennig.gittally.config.ArtifactsConfig
|
||||
import de.hoennig.gittally.config.AutoBuildConfig
|
||||
import de.hoennig.gittally.config.BranchConfig
|
||||
import de.hoennig.gittally.config.BuildDefinition
|
||||
import de.hoennig.gittally.config.ConfigLoader
|
||||
import de.hoennig.gittally.config.GitTallyConfig
|
||||
import de.hoennig.gittally.config.TriggerConfig
|
||||
import de.hoennig.gittally.config.WatcherConfig
|
||||
import de.hoennig.gittally.git.GitService
|
||||
import de.hoennig.werkator.build.ArtifactKeys
|
||||
import de.hoennig.werkator.build.ArtifactStore
|
||||
import de.hoennig.werkator.build.BuildExecutor
|
||||
import de.hoennig.werkator.build.BuildResult
|
||||
import de.hoennig.werkator.build.BuildStatus
|
||||
import de.hoennig.werkator.build.FileBuildResultRepository
|
||||
import de.hoennig.werkator.build.GitWorktreeWorkspaces
|
||||
import de.hoennig.werkator.build.RunningBuild
|
||||
import de.hoennig.werkator.config.ArtifactsConfig
|
||||
import de.hoennig.werkator.config.AutoBuildConfig
|
||||
import de.hoennig.werkator.config.BranchConfig
|
||||
import de.hoennig.werkator.config.BuildDefinition
|
||||
import de.hoennig.werkator.config.ConfigLoader
|
||||
import de.hoennig.werkator.config.TriggerConfig
|
||||
import de.hoennig.werkator.config.WatcherConfig
|
||||
import de.hoennig.werkator.config.WerkatorConfig
|
||||
import de.hoennig.werkator.git.GitService
|
||||
import io.kotest.assertions.throwables.shouldThrow
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.booleans.shouldBeFalse
|
||||
@@ -53,10 +53,10 @@ class WatcherTest : FunSpec() {
|
||||
private val noon = Instant.parse("2026-07-07T12:00:00Z")
|
||||
|
||||
private inner class Harness(
|
||||
config: GitTallyConfig = GitTallyConfig(),
|
||||
config: WerkatorConfig = WerkatorConfig(),
|
||||
) {
|
||||
val workingDir: Path = Files.createTempDirectory("gittally-watcher-test")
|
||||
val repository = FileBuildResultRepository(workingDir.resolve(".git/gittally/build-results.json"))
|
||||
val workingDir: Path = Files.createTempDirectory("werkator-watcher-test")
|
||||
val repository = FileBuildResultRepository(workingDir.resolve(".git/werkator/build-results.json"))
|
||||
val gitService = mockk<GitService>()
|
||||
val buildExecutor = mockk<BuildExecutor>()
|
||||
val artifactStore = mockk<ArtifactStore>()
|
||||
@@ -134,7 +134,7 @@ class WatcherTest : FunSpec() {
|
||||
branch: String,
|
||||
commit: String,
|
||||
): RunningBuild {
|
||||
val stagingDir = Files.createTempDirectory("gittally-watcher-staging")
|
||||
val stagingDir = Files.createTempDirectory("werkator-watcher-staging")
|
||||
return RunningBuild(
|
||||
branch = branch,
|
||||
commit = commit,
|
||||
@@ -145,8 +145,8 @@ class WatcherTest : FunSpec() {
|
||||
)
|
||||
}
|
||||
|
||||
private fun autoBuildConfig(vararg times: String): GitTallyConfig =
|
||||
GitTallyConfig(
|
||||
private fun autoBuildConfig(vararg times: String): WerkatorConfig =
|
||||
WerkatorConfig(
|
||||
branches =
|
||||
mapOf(
|
||||
"default" to BranchConfig(),
|
||||
@@ -248,7 +248,7 @@ class WatcherTest : FunSpec() {
|
||||
}
|
||||
|
||||
test("poll leaves local branch refs alone when fastForwardLocalRefs is disabled") {
|
||||
val harness = Harness(GitTallyConfig(watcher = WatcherConfig(fastForwardLocalRefs = false)))
|
||||
val harness = Harness(WerkatorConfig(watcher = WatcherConfig(fastForwardLocalRefs = false)))
|
||||
every { harness.gitService.originBranches(any()) } returns listOf("main")
|
||||
|
||||
harness.watcher.poll(harness.workingDir)
|
||||
@@ -304,7 +304,7 @@ class WatcherTest : FunSpec() {
|
||||
}
|
||||
|
||||
test("poll filters new origin branches by the configured newBranchMaxAge") {
|
||||
val harness = Harness(GitTallyConfig(watcher = WatcherConfig(newBranchMaxAge = "12h")))
|
||||
val harness = Harness(WerkatorConfig(watcher = WatcherConfig(newBranchMaxAge = "12h")))
|
||||
|
||||
harness.watcher.poll(harness.workingDir)
|
||||
|
||||
@@ -312,7 +312,7 @@ class WatcherTest : FunSpec() {
|
||||
}
|
||||
|
||||
test("a branch requiring a pull request is only built when its head matches a pull-request head") {
|
||||
val harness = Harness(GitTallyConfig(branches = mapOf("default" to BranchConfig(requirePullRequest = true))))
|
||||
val harness = Harness(WerkatorConfig(branches = mapOf("default" to BranchConfig(requirePullRequest = true))))
|
||||
every { harness.gitService.originBranches(any()) } returns listOf("feature/pr", "feature/no-pr")
|
||||
every { harness.gitService.newOriginBranches(any(), any()) } returns listOf("feature/pr", "feature/no-pr")
|
||||
every { harness.gitService.originHeadCommit("feature/pr", any()) } returns "commit-pr"
|
||||
@@ -339,7 +339,7 @@ class WatcherTest : FunSpec() {
|
||||
test("a disabled pull-request gate builds gated branches on plain-git origins without querying pull-request refs") {
|
||||
val harness =
|
||||
Harness(
|
||||
GitTallyConfig(
|
||||
WerkatorConfig(
|
||||
watcher = WatcherConfig(pullRequestGate = false),
|
||||
branches = mapOf("default" to BranchConfig(requirePullRequest = true)),
|
||||
),
|
||||
@@ -357,7 +357,7 @@ class WatcherTest : FunSpec() {
|
||||
test("a branch entry overrides requirePullRequest from the default entry") {
|
||||
val harness =
|
||||
Harness(
|
||||
GitTallyConfig(
|
||||
WerkatorConfig(
|
||||
branches =
|
||||
mapOf(
|
||||
"default" to BranchConfig(requirePullRequest = true),
|
||||
@@ -378,7 +378,7 @@ class WatcherTest : FunSpec() {
|
||||
test("an auto build requiring a pull request is skipped and its slot stays untriggered") {
|
||||
val harness =
|
||||
Harness(
|
||||
GitTallyConfig(
|
||||
WerkatorConfig(
|
||||
branches =
|
||||
mapOf(
|
||||
"default" to BranchConfig(),
|
||||
@@ -418,7 +418,7 @@ class WatcherTest : FunSpec() {
|
||||
test("a scheduled build definition fires for its selected branches under its own pool") {
|
||||
val harness =
|
||||
Harness(
|
||||
GitTallyConfig(
|
||||
WerkatorConfig(
|
||||
buildDefinitions =
|
||||
mapOf(
|
||||
"pitest" to
|
||||
@@ -447,7 +447,7 @@ class WatcherTest : FunSpec() {
|
||||
test("a scheduled build definition with activeWithin skips branches without recent commits") {
|
||||
val harness =
|
||||
Harness(
|
||||
GitTallyConfig(
|
||||
WerkatorConfig(
|
||||
buildDefinitions =
|
||||
mapOf("pitest" to BuildDefinition(trigger = TriggerConfig(atTimes = listOf("11:00"), activeWithin = "24h"))),
|
||||
),
|
||||
@@ -469,7 +469,7 @@ class WatcherTest : FunSpec() {
|
||||
test("an onPush build definition builds the changed branches it selects") {
|
||||
val harness =
|
||||
Harness(
|
||||
GitTallyConfig(
|
||||
WerkatorConfig(
|
||||
buildDefinitions =
|
||||
mapOf("lint" to BuildDefinition(trigger = TriggerConfig(onPush = true, branches = listOf("main")))),
|
||||
),
|
||||
@@ -491,7 +491,7 @@ class WatcherTest : FunSpec() {
|
||||
|
||||
test("builds.default with onPush false disables the implicit on-push build") {
|
||||
val harness =
|
||||
Harness(GitTallyConfig(buildDefinitions = mapOf("default" to BuildDefinition(trigger = TriggerConfig(onPush = false)))))
|
||||
Harness(WerkatorConfig(buildDefinitions = mapOf("default" to BuildDefinition(trigger = TriggerConfig(onPush = false)))))
|
||||
every { harness.gitService.originBranches(any()) } returns listOf("main")
|
||||
every { harness.gitService.localBranches(any()) } returns listOf("main")
|
||||
every { harness.gitService.hasNewCommits("main", any()) } returns true
|
||||
@@ -517,7 +517,7 @@ class WatcherTest : FunSpec() {
|
||||
test("a build definition committed on a branch fires for that branch, without any entry in the primary config") {
|
||||
val harness = Harness()
|
||||
val branchLayer =
|
||||
GitTallyConfig(
|
||||
WerkatorConfig(
|
||||
buildDefinitions = mapOf("pitest" to BuildDefinition(trigger = TriggerConfig(atTimes = listOf("11:00")))),
|
||||
)
|
||||
every { harness.gitService.originBranches(any()) } returns listOf("main", "experiment")
|
||||
@@ -538,10 +538,27 @@ class WatcherTest : FunSpec() {
|
||||
.shouldBeTrue()
|
||||
}
|
||||
|
||||
test("a branch config committed under the pre-rename name is still read") {
|
||||
val harness = Harness()
|
||||
val branchLayer =
|
||||
WerkatorConfig(
|
||||
buildDefinitions = mapOf("pitest" to BuildDefinition(trigger = TriggerConfig(atTimes = listOf("11:00")))),
|
||||
)
|
||||
every { harness.gitService.originBranches(any()) } returns listOf("experiment")
|
||||
every { harness.gitService.originBranchHeads(any()) } returns mapOf("experiment" to "commit-exp")
|
||||
every { harness.gitService.showFileAtCommit("commit-exp", ".gittally.yml", any()) } returns "branch-yaml"
|
||||
every { harness.configLoader.loadWithBranchLayer(any(), "branch-yaml") } returns branchLayer
|
||||
every { harness.gitService.originHeadCommit("experiment", any()) } returns "commit-exp"
|
||||
|
||||
harness.watcher.poll(harness.workingDir)
|
||||
|
||||
harness.startedBuilds shouldContainExactly listOf("experiment" to "commit-exp")
|
||||
}
|
||||
|
||||
test("a build definition committed on a branch never schedules another branch") {
|
||||
val harness = Harness()
|
||||
val branchLayer =
|
||||
GitTallyConfig(
|
||||
WerkatorConfig(
|
||||
buildDefinitions =
|
||||
mapOf("pitest" to BuildDefinition(trigger = TriggerConfig(atTimes = listOf("11:00"), branches = listOf("main")))),
|
||||
)
|
||||
@@ -585,7 +602,7 @@ class WatcherTest : FunSpec() {
|
||||
// the machine config gains a scheduled build while the branch stays where it is:
|
||||
// caching the definitions by head commit alone would never notice
|
||||
val edited =
|
||||
GitTallyConfig(
|
||||
WerkatorConfig(
|
||||
buildDefinitions = mapOf("nightly" to BuildDefinition(trigger = TriggerConfig(atTimes = listOf("11:00")))),
|
||||
)
|
||||
every { harness.configLoader.load(any()) } returns edited
|
||||
@@ -706,7 +723,7 @@ class WatcherTest : FunSpec() {
|
||||
}
|
||||
|
||||
test("poll keeps the latest green build beyond retention unless keepLatestGreen is disabled") {
|
||||
val keeping = Harness(GitTallyConfig(artifacts = ArtifactsConfig(retentionPerBranch = 1)))
|
||||
val keeping = Harness(WerkatorConfig(artifacts = ArtifactsConfig(retentionPerBranch = 1)))
|
||||
keeping.seed("main", BuildStatus.SUCCESS, commit = "commit-1")
|
||||
keeping.seed("main", BuildStatus.FAILED, commit = "commit-2")
|
||||
every { keeping.gitService.originBranches(any()) } returns listOf("main")
|
||||
@@ -717,7 +734,7 @@ class WatcherTest : FunSpec() {
|
||||
listOf(BuildStatus.FAILED, BuildStatus.SUCCESS)
|
||||
|
||||
val dropping =
|
||||
Harness(GitTallyConfig(artifacts = ArtifactsConfig(retentionPerBranch = 1, keepLatestGreen = false)))
|
||||
Harness(WerkatorConfig(artifacts = ArtifactsConfig(retentionPerBranch = 1, keepLatestGreen = false)))
|
||||
dropping.seed("main", BuildStatus.SUCCESS, commit = "commit-1")
|
||||
dropping.seed("main", BuildStatus.FAILED, commit = "commit-2")
|
||||
every { dropping.gitService.originBranches(any()) } returns listOf("main")
|
||||
@@ -729,7 +746,7 @@ class WatcherTest : FunSpec() {
|
||||
|
||||
test("poll drops builds older than retentionMaxAge but keeps the branch's newest build") {
|
||||
// seeds start one hour before the fixed clock, so a 30m age limit cuts them off
|
||||
val harness = Harness(GitTallyConfig(artifacts = ArtifactsConfig(retentionMaxAge = "30m")))
|
||||
val harness = Harness(WerkatorConfig(artifacts = ArtifactsConfig(retentionMaxAge = "30m")))
|
||||
harness.seed("main", BuildStatus.FAILED, commit = "commit-1")
|
||||
harness.seed("main", BuildStatus.FAILED, commit = "commit-2")
|
||||
every { harness.gitService.originBranches(any()) } returns listOf("main")
|
||||
Reference in New Issue
Block a user