diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d3e3578e..94cd4cea 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,12 +1,25 @@ name: Build -# Documentation-only changes skip this workflow entirely. +# Documentation-only changes, and changes confined to the Kubernetes +# manifests, skip this workflow entirely. # # A push to master here does not just build - it pushes an image, runs the # migrations and restarts the demo container, so the site takes a short outage. # Paying that for a README edit is waste at best; at worst a deploy fails for a # reason unrelated to anything in the change. Code coverage is unaffected, # because go.yml still builds every push and pull request. +# +# scripts/k8s holds deploy.yml, storage.yml and prerun.sh, and the deploy below +# reads none of them - it is an ssh into one host that runs docker, building the +# Dockerfile at the repository root. Those manifests are for people deploying to +# a cluster of their own. The pattern is scripts/k8s/** rather than scripts/** +# because scripts/Dockerfile is a build input: go.yml builds the release image +# from it on a tag. +# +# A file outside these patterns still runs the workflow even when the rest of +# the change is ignorable: paths-ignore skips only when every changed path +# matches. Editing this file is one such case, on purpose - a deploy script +# that is never exercised by the change that broke it is worse than an outage. on: push: branches: [ master ] @@ -15,6 +28,7 @@ on: - 'docs/**' - 'LICENSE*' - '.github/ISSUE_TEMPLATE/**' + - 'scripts/k8s/**' pull_request: branches: [ master ] paths-ignore: @@ -22,6 +36,7 @@ on: - 'docs/**' - 'LICENSE*' - '.github/ISSUE_TEMPLATE/**' + - 'scripts/k8s/**' # One deploy at a time. Two merges seconds apart raced here: both runs did # docker rm -f then docker run, the second removed the container the first had diff --git a/scripts/k8s/deploy.yml b/scripts/k8s/deploy.yml index cac85e8e..e9ad5e24 100644 --- a/scripts/k8s/deploy.yml +++ b/scripts/k8s/deploy.yml @@ -23,10 +23,20 @@ metadata: version: v1 spec: # One replica, and the drain window below buys nothing at one replica: there - # is nowhere to send the traffic this pod stops taking. Raising it needs one - # more change than the number - the volume below is shared by every replica, - # and the log path in settings.yml lives on it, so a second pod would append - # to the same rotating file. + # is nowhere to send the traffic this pod stops taking. Raising it needs two + # changes that are not this number: + # + # The volume below is shared by every replica, and the log path in + # settings.yml lives on it, so a second pod would append to the same + # rotating file. + # + # The job scheduler is per process while its handle on a job is one shared + # column. Startup runs `UPDATE sys_job SET entry_id = 0 WHERE entry_id > 0` + # across the whole table (app/jobs/jobbase.go), so a second pod erases the + # first pod's ids and writes its own, and every pod registers the whole + # enabled list in its own scheduler. Neither symptom logs anything: an + # enabled job fires once per pod, and stopping one from the UI removes an + # entry from the wrong process and still answers 200. See #915. replicas: 1 selector: matchLabels: