ΠΡΠΈΠ²Π΅Ρ! Feature branch (aka deploy preview, review app) β ΡΡΠΎ ΠΊΠΎΠ³Π΄Π° Π΄Π΅ΠΏΠ»ΠΎΠΈΡΡΡ Π½Π΅ ΡΠΎΠ»ΡΠΊΠΎ master Π²Π΅ΡΠΊΠ°, Π½ΠΎ ΠΈ ΠΊΠ°ΠΆΠ΄ΡΠΉ pull request Π½Π° ΡΠ½ΠΈΠΊΠ°Π»ΡΠ½ΡΠΉ URL. ΠΠΎΠΆΠ½ΠΎ ΠΏΡΠΎΠ²Π΅ΡΠΈΡΡ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ Π»ΠΈ ΠΊΠΎΠ΄ Π² production-ΠΎΠΊΡΡΠΆΠ΅Π½ΠΈΠΈ, ΡΠΈΡΡ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠΊΠ°Π·Π°ΡΡ Π΄ΡΡΠ³ΠΈΠΌ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΡΠ°ΠΌ ΠΈΠ»ΠΈ ΠΏΡΠΎΠ΄ΡΠΊΡΠΎΠ»ΠΎΠ³Π°ΠΌ. ΠΠΎΠΊΠ° Π²Ρ ΡΠ°Π±ΠΎΡΠ°Π΅ΡΠ΅ Π² pull request’Π΅, ΠΊΠ°ΠΆΠ΄ΡΠΉ Π½ΠΎΠ²ΡΠΉ commit ΡΠ΅ΠΊΡΡΠΈΠΉ deploy Π΄Π»Ρ ΡΡΠ°ΡΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π° ΡΠ΄Π°Π»ΡΠ΅ΡΡΡ, Π° Π½ΠΎΠ²ΡΠΉ deploy Π΄Π»Ρ Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π° Π²ΡΠΊΠ°ΡΡΠ²Π°Π΅ΡΡΡ. ΠΠΎΠΏΡΠΎΡΡ ΠΌΠΎΠ³ΡΡ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΡΡΡ ΡΠΎΠ³Π΄Π°, ΠΊΠΎΠ³Π΄Π° Π²Ρ ΡΠΌΠ΅ΡΠ΄ΠΆΠΈΠ»ΠΈ pull request Π² master Π²Π΅ΡΠΊΡ. Feature branch Π²Π°ΠΌ Π±ΠΎΠ»ΡΡΠ΅ Π½Π΅ Π½ΡΠΆΠ½Π°, Π½ΠΎ ΡΠ΅ΡΡΡΡΡ Kubernetes Π²ΡΠ΅ Π΅ΡΠ΅ Π½Π°Ρ ΠΎΠ΄ΡΡΡΡ Π² ΠΊΠ»Π°ΡΡΠ΅ΡΠ΅.
ΠΡΠ΅ ΠΏΡΠΎ feature branch’ΠΈ
ΠΠ΄ΠΈΠ½ ΠΈΠ· ΠΏΠΎΠ΄Ρ ΠΎΠ΄ΠΎΠ² ΠΊΠ°ΠΊ ΡΠ΄Π΅Π»Π°ΡΡ feature branch’ΠΈ Π² Kubernetes β ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ namespace’Ρ. ΠΡΠ»ΠΈ ΠΊΡΠ°ΡΠΊΠΎ, production ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ Π²ΡΠ³Π»ΡΠ΄ΠΈΡ ΡΠ°ΠΊ:
kind: Namespace
apiVersion: v1
metadata:
name: habr-back-end
...
kind: Deployment
apiVersion: apps/v1
metadata:
namespace: habr-back-end
spec:
replicas: 3
...
ΠΠ»Ρ feature branch ΡΠΎΠ·Π΄Π°Π΅ΡΡΡ namespace c Π΅Π΅ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΠΎΠΌ (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, Π½ΠΎΠΌΠ΅Ρ pull request’Π°) ΠΈ ΠΊΠ°ΠΊΠΈΠΌ-ΡΠΎ ΠΏΡΠ΅ΡΠΈΠΊΡΠΎΠΌ/ΠΏΠΎΡΡΡΠΈΠΊΡΠΎΠΌ (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, -pr-):
kind: Namespace
apiVersion: v1
metadata:
name: habr-back-end-pr-17
...
kind: Deployment
apiVersion: apps/v1
metadata:
namespace: habr-back-end-pr-17
spec:
replicas: 1
...
Π ΠΎΠ±ΡΠ΅ΠΌ, Ρ Π½Π°ΠΏΠΈΡΠ°Π» Kubernetes Operator (ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, ΠΊΠΎΡΠΎΡΠΎΠ΅ ΠΈΠΌΠ΅Π΅Ρ Π΄ΠΎΡΡΡΠΏ ΠΊ ΡΠ΅ΡΡΡΡΠ°ΠΌ ΠΊΠ»Π°ΡΡΠ΅ΡΠ°),
$ kubectl get pods --all-namespaces | grep -e "-pr-"
NAMESPACE ... AGE
habr-back-end-pr-264 ... 4d8h
habr-back-end-pr-265 ... 5d7h
ΠΡΠΎ ΡΠΎ ΠΊΠ°ΠΊ Π²Π½Π΅Π΄ΡΠΈΡΡ feature branch’ΠΈ Π² ΠΊΠ»Π°ΡΡΠ΅Ρ, ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΡΠΈΡΠ°ΡΡ
ΠΠΎΡΠΈΠ²Π°ΡΠΈΡ
ΠΠ°Π²Π°ΠΉΡΠ΅ ΠΏΠΎΡΠΌΠΎΡΡΠΈΠΌ Π½Π° ΡΠΈΠΏΠΈΡΠ½ΡΠΉ ΠΆΠΈΠ·Π½Π΅Π½Π½ΡΠΉ ΡΠΈΠΊΠ» pull request’a Ρ Π½Π΅ΠΏΡΠ΅ΡΡΠ²Π½ΠΎΠΉ ΠΈΠ½ΡΠ΅Π³ΡΠ°ΡΠΈΠ΅ΠΉ (continuous integration
):
- ΠΡΡΠΈΠΌ Π½ΠΎΠ²ΡΠΉ commit Π² Π²Π΅ΡΠΊΡ.
- ΠΠ° Π±ΠΈΠ»Π΄Π΅, Π·Π°ΠΏΡΡΠΊΠ°ΡΡΡΡ Π»ΠΈΠ½ΡΠ΅ΡΡ ΠΈ/ΠΈΠ»ΠΈ ΡΠ΅ΡΡΡ.
- ΠΠ° Π»Π΅ΡΡ ΡΠΎΡΠΌΠΈΡΡΡΡΡΡ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ Kubernetes pull request’a (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, Π² Π³ΠΎΡΠΎΠ²ΡΠΉ ΡΠ°Π±Π»ΠΎΠ½ ΠΏΠΎΠ΄ΡΡΠ°Π²Π»ΡΠ΅ΡΡΡ Π΅Π³ΠΎ Π½ΠΎΠΌΠ΅Ρ).
- Π‘ ΠΏΠΎΠΌΠΎΡΡΡ kubectl apply ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ ΠΏΠΎΠΏΠ°Π΄Π°ΡΡ Π² ΠΊΠ»Π°ΡΡΠ΅Ρ (deploy).
- Pull request ΡΠ»ΠΈΠ²Π°Π΅ΡΡΡ Π² master Π²Π΅ΡΠΊΡ.
ΠΠΎΠΊΠ° Π²Ρ ΡΠ°Π±ΠΎΡΠ°Π΅ΡΠ΅ Π² pull request’Π΅, ΠΊΠ°ΠΆΠ΄ΡΠΉ Π½ΠΎΠ²ΡΠΉ commit ΡΠ΅ΠΊΡΡΠΈΠΉ deploy Π΄Π»Ρ ΡΡΠ°ΡΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π° ΡΠ΄Π°Π»ΡΠ΅ΡΡΡ, Π° Π½ΠΎΠ²ΡΠΉ deploy Π΄Π»Ρ Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π° Π²ΡΠΊΠ°ΡΡΠ²Π°Π΅ΡΡΡ. ΠΠΎ ΠΊΠΎΠ³Π΄Π° pull request ΡΠ»ΠΈΠ²Π°Π΅ΡΡΡ Π² master Π²Π΅ΡΠΊΡ, Π±ΡΠ΄Π΅Ρ Π±ΠΈΠ»Π΄ΠΈΡΡΡ ΡΠΎΠ»ΡΠΊΠΎ master Π²Π΅ΡΠΊΠ°. Π ΠΈΡΠΎΠ³Π΅ ΠΏΠΎΠ»ΡΡΠ°Π΅ΡΡΡ, ΡΡΠΎ ΠΏΡΠΎ pull request ΠΌΡ ΡΠΆΠ΅ Π·Π°Π±ΡΠ»ΠΈ, Π° Π΅Π³ΠΎ Kubernetes ΡΠ΅ΡΡΡΡΡ Π²ΡΠ΅ Π΅ΡΠ΅ Π½Π°Ρ ΠΎΠ΄ΡΡΡΡ Π² ΠΊΠ»Π°ΡΡΠ΅ΡΠ΅.
ΠΠ°ΠΊ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ
Π£ΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ ΠΏΡΠΎΠ΅ΠΊΡ ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ Π½ΠΈΠΆΠ΅:
$ kubectl apply -f https://raw.githubusercontent.com/dmytrostriletskyi/stale-feature-branch-operator/master/configs/production.yml
Π‘ΠΎΠ·Π΄Π°ΡΡ ΡΠ°ΠΉΠ» ΡΠΎ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΌ ΡΠΎΠ΄Π΅ΡΠΆΠ°Π½ΠΈΠ΅ΠΌ ΠΈ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ ΡΠ΅ΡΠ΅Π· kubectl apply -f
:
apiVersion: feature-branch.dmytrostriletskyi.com/v1
kind: StaleFeatureBranch
metadata:
name: stale-feature-branch
spec:
namespaceSubstring: -pr-
afterDaysWithoutDeploy: 3
ΠΠ°ΡΠ°ΠΌΠ΅ΡΡ namespaceSubstring Π½ΡΠΆΠ΅Π½, ΡΡΠΎΠ±Ρ ΠΎΡΡΠΈΠ»ΡΡΡΠΎΠ²Π°ΡΡ namespace’Ρ Π΄Π»Ρ pull request’ΠΎΠ² ΠΎΡ Π΄ΡΡΠ³ΠΈΡ
namespace’ΠΎΠ². ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, Π΅ΡΠ»ΠΈ Π² ΠΊΠ»Π°ΡΡΠ΅ΡΠ΅ Π΅ΡΡΡ ΡΠ»Π΅Π΄ΡΡΡΠΈΠ΅ namespace’Ρ: habr-back-end
, habr-front-end
, habr-back-end-pr-17
, habr-back-end-pr-33
, ΡΠΎΠ³Π΄Π° ΠΊΠ°Π½Π΄ΠΈΠ΄Π°ΡΠ°ΠΌΠΈ Π½Π° ΡΠ΄Π°Π»Π΅Π½ΠΈΠ΅ Π±ΡΠ΄ΡΡ habr-back-end-pr-17
, habr-back-end-pr-33
.
ΠΠ°ΡΠ°ΠΌΠ΅ΡΡ afterDaysWithoutDeploy Π½ΡΠΆΠ΅Π½ ΡΡΠΎΠ±Ρ, ΡΠ΄Π°Π»ΡΡΡ ΡΡΠ°ΡΡΠ΅ namespace’Ρ. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, Π΅ΡΠ»ΠΈ namespace ΡΠΎΠ·Π΄Π°Π½ 3 Π΄Π½Ρ 1 ΡΠ°Ρ
Π½Π°Π·Π°Π΄, Π° Π² ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠ΅ ΡΠΊΠ°Π·Π°Π½ΠΎ 3 Π΄Π½Ρ
, ΡΡΠΎΡ namespace Π±ΡΠ΄Π΅Ρ ΡΠ΄Π°Π»Π΅Π½. Π Π°Π±ΠΎΡΠ°Π΅Ρ ΠΈ Π² ΠΎΠ±ΡΠ°ΡΠ½ΡΡ ΡΡΠΎΡΠΎΠ½Ρ, Π΅ΡΠ»ΠΈ namespace ΡΠΎΠ·Π΄Π°Π½ 2 Π΄Π½Ρ 23 ΡΠ°ΡΠ°
Π½Π°Π·Π°Π΄, Π° Π² ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠ΅ ΡΠΊΠ°Π·Π°Π½ΠΎ 3 Π΄Π½Ρ
, ΡΡΠΎΡ namespace Π½Π΅ Π±ΡΠ΄Π΅Ρ ΡΠ΄Π°Π»Π΅Π½.
ΠΡΡΡ Π΅ΡΠ΅ ΠΎΠ΄ΠΈΠ½ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡ, ΠΎΠ½ ΠΎΡΠ²Π΅ΡΠ°Π΅Ρ Π·Π° ΡΠΎ ΠΊΠ°ΠΊ ΡΠ°ΡΡΠΎ ΡΠΊΠ°Π½ΠΈΡΠΎΠ²Π°ΡΡ Π²ΡΠ΅ namespace’Ρ ΠΈ ΠΏΡΠΎΠ²Π΅ΡΡΡΡ Π½Π° Π΄Π½ΠΈ Π±Π΅Π· deploy’Ρ β checkEveryMinutes. ΠΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ ΠΎΠ½ ΡΠ°Π²Π΅Π½ 30 ΠΌΠΈΠ½ΡΡΠ°ΠΌ
.
ΠΠ°ΠΊ ΡΡΠΎ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ
ΠΠ° ΠΏΡΠ°ΠΊΡΠΈΠΊΠ΅, ΠΏΠΎΠ½Π°Π΄ΠΎΠ±ΠΈΡΡΡ:
Docker Π΄Π»Ρ ΡΠ°Π±ΠΎΡΡ Π² ΠΈΠ·ΠΎΠ»ΠΈΡΠΎΠ²Π°Π½Π½ΠΎΠΌ ΠΎΠΊΡΡΠΆΠ΅Π½ΠΈΠΈ.Minikube ΠΏΠΎΠ΄Π½ΠΈΠΌΠ΅Ρ Kubernetes ΠΊΠ»Π°ΡΡΠ΅Ρ Π»ΠΎΠΊΠ°Π»ΡΠ½ΠΎ.kubectl β ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ ΡΡΡΠΎΠΊΠΈ Π΄Π»Ρ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ ΠΊΠ»Π°ΡΡΠ΅ΡΠΎΠΌ.
ΠΠΎΠ΄Π½ΠΈΠΌΠ°Π΅ΠΌ Kubernetes ΠΊΠ»Π°ΡΡΠ΅Ρ Π»ΠΎΠΊΠ°Π»ΡΠ½ΠΎ:
$ minikube start --vm-driver=docker
minikube v1.11.0 on Darwin 10.15.5
Using the docker driver based on existing profile.
Starting control plane node minikube in cluster minikube.
Π£ΠΊΠ°Π·ΡΠ²Π°Π΅ΠΌ kubectl
ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π»ΠΎΠΊΠ°Π»ΡΠ½ΡΠΉ ΠΊΠ»Π°ΡΡΠ΅Ρ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ:
$ kubectl config use-context minikube
Switched to context "minikube".
Π‘ΠΊΠ°ΡΠΈΠ²Π°Π΅ΠΌ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ Π΄Π»Ρ production-ΡΡΠ΅Π΄Ρ:
$ curl https://raw.githubusercontent.com/dmytrostriletskyi/stale-feature-branch-operator/master/configs/production.yml > stale-feature-branch-production-configs.yml
Π’Π°ΠΊ ΠΊΠ°ΠΊ production ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ Π½Π°ΡΡΡΠΎΠ΅Π½Ρ ΠΏΡΠΎΠ²Π΅ΡΡΡΡ ΡΡΠ°ΡΡΠ΅ namespace’Ρ, Π° Π² Π½Π°ΡΠ΅ΠΌ Π½ΠΎΠ²ΠΎ ΠΏΠΎΠ΄Π½ΡΡΠΎΠΌ ΠΊΠ»Π°ΡΡΠ΅ΡΠ΅ ΠΈΡ
Π½Π΅Ρ, Π·Π°ΠΌΠ΅Π½ΠΈΠΌ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ ΠΎΠΊΡΡΠΆΠ΅Π½ΠΈΡ IS_DEBUG
Π½Π° true
. ΠΡΠΈ ΡΠ°ΠΊΠΎΠΌ Π·Π½Π°ΡΠ΅Π½ΠΈΠΈ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡ afterDaysWithoutDeploy
Π½Π΅ ΡΡΠΈΡΡΠ²Π°Π΅ΡΡΡ ΠΈ namespace’Ρ Π½Π΅ ΠΏΡΠΎΠ²Π΅ΡΡΡΡΡΡ Π½Π° Π΄Π½ΠΈ Π±Π΅Π· deploy’Ρ, ΡΠΎΠ»ΡΠΊΠΎ Π½Π° Π²Ρ
ΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ ΠΏΠΎΠ΄ΡΡΡΠΎΠΊΠΈ (-pr-
).
ΠΡΠ»ΠΈ Π²Ρ Π½Π° Linux
:
$ sed -i 's|false|true|g' stale-feature-branch-production-configs.yml
ΠΡΠ»ΠΈ Π²Ρ Π½Π° macOS
:
$ sed -i "" 's|false|true|g' stale-feature-branch-production-configs.yml
Π£ΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΠΌ ΠΏΡΠΎΠ΅ΠΊΡ:
$ kubectl apply -f stale-feature-branch-production-configs.yml
ΠΡΠΎΠ²Π΅ΡΡΠ΅ΠΌ, ΡΡΠΎ Π² ΠΊΠ»Π°ΡΡΠ΅ΡΠ΅ ΠΏΠΎΡΠ²ΠΈΠ»ΡΡ ΡΠ΅ΡΡΡΡ StaleFeatureBranch
:
$ kubectl api-resources | grep stalefeaturebranches
NAME ... APIGROUP ... KIND
stalefeaturebranches ... feature-branch.dmytrostriletskyi.com ... StaleFeatureBranch
ΠΡΠΎΠ²Π΅ΡΡΠ΅ΠΌ, ΡΡΠΎ Π² ΠΊΠ»Π°ΡΡΠ΅ΡΠ΅ ΠΏΠΎΡΠ²ΠΈΠ»ΡΡ ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡ:
$ kubectl get pods --namespace stale-feature-branch-operator
NAME ... STATUS ... AGE
stale-feature-branch-operator-6bfbfd4df8-m7sch ... Running ... 38s
ΠΡΠ»ΠΈ Π·Π°Π³Π»ΡΠ½ΡΡΡ Π² Π΅Π³ΠΎ Π»ΠΎΠ³ΠΈ, ΠΎΠ½ Π³ΠΎΡΠΎΠ² ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°ΡΡ ΡΠ΅ΡΡΡΡΡ StaleFeatureBranch
:
$ kubectl logs stale-feature-branch-operator-6bfbfd4df8-m7sch -n stale-feature-branch-operator
... "msg":"Operator Version: 0.0.1"}
...
... "msg":"Starting EventSource", ... , "source":"kind source: /, Kind="}
... "msg":"Starting Controller", ...}
... "msg":"Starting workers", ..., "worker count":1}
Π£ΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΠΌ Π³ΠΎΡΠΎΠ²ΡΠ΅ fixtures
(Π³ΠΎΡΠΎΠ²ΡΠ΅ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ Π΄Π»Ρ ΠΌΠΎΠ΄Π΅Π»ΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΡΠ΅ΡΡΡΡΠΎΠ² ΠΊΠ»Π°ΡΡΠ΅ΡΠ°) Π΄Π»Ρ ΡΠ΅ΡΡΡΡΠ° StaleFeatureBranch
:
$ kubectl apply -f https://raw.githubusercontent.com/dmytrostriletskyi/stale-feature-branch-operator/master/fixtures/stale-feature-branch.yml
Π ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡΡ
ΡΠΊΠ°Π·Π°Π½ΠΎ ΠΈΡΠΊΠ°ΡΡ namespace’Ρ Ρ ΠΏΠΎΠ΄ΡΡΡΠΎΠΊΠΎΠΉ -pr-
ΡΠ°Π· Π² 1 ΠΌΠΈΠ½ΡΡΡ
.:
apiVersion: feature-branch.dmytrostriletskyi.com/v1
kind: StaleFeatureBranch
metadata:
name: stale-feature-branch
spec:
namespaceSubstring: -pr-
afterDaysWithoutDeploy: 1
checkEveryMinutes: 1
ΠΠΏΠ΅ΡΠ°ΡΠΎΡ ΠΎΡΡΠ΅Π°Π³ΠΈΡΠΎΠ²Π°Π» ΠΈ Π³ΠΎΡΠΎΠ² ΠΏΡΠΎΠ²Π΅ΡΡΡΡ namespace’Ρ:
$ kubectl logs stale-feature-branch-operator-6bfbfd4df8-m7sch -n stale-feature-branch-operator
... "msg":"Stale feature branch is being processing.","namespaceSubstring":"-pr-","afterDaysWithoutDeploy":1,"checkEveryMinutes":1,"isDebug":"true"}
Π£ΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΠΌ fixtures
, ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΠΈΠ΅ Π΄Π²Π° namespace’Π° (project-pr-1
, project-pr-2
) ΠΈ ΠΈΡ
deployments
, services
, ingress
, ΠΈ ΡΠ°ΠΊ Π΄Π°Π»Π΅Π΅:
$ kubectl apply -f https://raw.githubusercontent.com/dmytrostriletskyi/stale-feature-branch-operator/master/fixtures/first-feature-branch.yml -f https://raw.githubusercontent.com/dmytrostriletskyi/stale-feature-branch-operator/master/fixtures/second-feature-branch.yml
...
namespace/project-pr-1 created
deployment.apps/project-pr-1 created
service/project-pr-1 created
horizontalpodautoscaler.autoscaling/project-pr-1 created
secret/project-pr-1 created
configmap/project-pr-1 created
ingress.extensions/project-pr-1 created
namespace/project-pr-2 created
deployment.apps/project-pr-2 created
service/project-pr-2 created
horizontalpodautoscaler.autoscaling/project-pr-2 created
secret/project-pr-2 created
configmap/project-pr-2 created
ingress.extensions/project-pr-2 created
ΠΡΠΎΠ²Π΅ΡΡΠ΅ΠΌ, ΡΡΠΎ Π²ΡΠ΅ ΡΠ΅ΡΡΡΡΡ Π²ΡΡΠ΅ ΡΡΠΏΠ΅ΡΠ½ΠΎ ΡΠΎΠ·Π΄Π°Π½Ρ:
$ kubectl get namespace,pods,deployment,service,horizontalpodautoscaler,configmap,ingress -n project-pr-1 && kubectl get namespace,pods,deployment,service,horizontalpodautoscaler,configmap,ingress -n project-pr-2
...
NAME ... READY ... STATUS ... AGE
pod/project-pr-1-848d5fdff6-rpmzw ... 1/1 ... Running ... 67s
NAME ... READY ... AVAILABLE ... AGE
deployment.apps/project-pr-1 ... 1/1 ... 1 ... 67s
...
Π’Π°ΠΊ ΠΊΠ°ΠΊ ΠΌΡ Π²ΠΊΠ»ΡΡΠΈΠ»ΠΈ debug
, namespace’Ρ project-pr-1
ΠΈ project-pr-2
, ΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΠΎ ΠΈ Π²ΡΠ΅ ΠΎΡΡΠ°Π»ΡΠ½ΡΠ΅ ΡΠ΅ΡΡΡΡΡ, Π΄ΠΎΠ»ΠΆΠ½Ρ Π±ΡΠ΄ΡΡ ΡΡΠ°Π·Ρ ΡΠ΄Π°Π»ΠΈΡΡΡΡ Π½Π΅ ΡΡΠΈΡΡΠ²Π°Ρ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡ afterDaysWithoutDeploy
. Π Π»ΠΎΠ³Π°Ρ
ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡΠ° ΡΡΠΎ Π²ΠΈΠ΄Π½ΠΎ:
$ kubectl logs stale-feature-branch-operator-6bfbfd4df8-m7sch -n stale-feature-branch-operator
... "msg":"Namespace should be deleted due to debug mode is enabled.","namespaceName":"project-pr-1"}
... "msg":"Namespace is being processing.","namespaceName":"project-pr-1","namespaceCreationTimestamp":"2020-06-16 18:43:58 +0300 EEST"}
... "msg":"Namespace has been deleted.","namespaceName":"project-pr-1"}
... "msg":"Namespace should be deleted due to debug mode is enabled.","namespaceName":"project-pr-2"}
... "msg":"Namespace is being processing.","namespaceName":"project-pr-2","namespaceCreationTimestamp":"2020-06-16 18:43:58 +0300 EEST"}
... "msg":"Namespace has been deleted.","namespaceName":"project-pr-2"}
ΠΡΠ»ΠΈ ΠΏΡΠΎΠ²Π΅ΡΠΈΡΡ Π½Π°Π»ΠΈΡΠΈΠ΅ ΡΠ΅ΡΡΡΡΠΎΠ², ΠΎΠ½ΠΈ Π±ΡΠ΄ΡΡ Π² ΡΡΠ°ΡΡΡΠ΅ Terminating
(ΠΏΡΠΎΡΠ΅ΡΡ ΡΠ΄Π°Π»Π΅Π½ΠΈΡ) ΠΈΠ»ΠΈ ΡΠΆΠ΅ ΡΠ΄Π°Π»Π΅Π½Ρ (Π²ΡΠ²ΠΎΠ΄ ΠΊΠΎΠΌΠ°Π½Π΄Ρ ΠΏΡΡΡ).
$ kubectl get namespace,pods,deployment,service,horizontalpodautoscaler,configmap,ingress -n project-pr-1 && kubectl get namespace,pods,deployment,service,horizontalpodautoscaler,configmap,ingress -n project-pr-2
...
ΠΠΎΠΆΠ΅ΡΠ΅ ΠΏΠΎΠ²ΡΠΎΡΠΈΡΡ ΠΏΡΠΎΡΠ΅ΡΡ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ fixtures
Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΡΠ°Π· ΠΈ ΡΠ±Π΅Π΄ΠΈΡΡΡΡ, ΡΡΠΎ ΠΎΠ½ΠΈ Π±ΡΠ΄ΡΡ ΡΠ΄Π°Π»Π΅Π½Ρ Π² ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ ΠΌΠΈΠ½ΡΡΡ.
ΠΠ»ΡΡΠ΅ΡΠ½Π°ΡΠΈΠ²Ρ
Π§ΡΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°ΡΡ Π²ΠΌΠ΅ΡΡΠΎ ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡΠ°, ΠΊΠΎΡΠΎΡΡΠΉ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ Π² ΠΊΠ»Π°ΡΡΠ΅ΡΠ΅? ΠΠΎΠ΄Ρ ΠΎΠ΄ΠΎΠ² Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ, Π²ΡΠ΅ ΠΎΠ½ΠΈ Π½Π΅ΠΈΠ΄Π΅Π°Π»ΡΠ½Ρ (ΠΈ ΠΈΡ Π½Π΅Π΄ΠΎΡΡΠ°ΡΠΊΠΈ ΡΡΠ±ΡΠ΅ΠΊΡΠΈΠ²Π½Ρ), ΠΈ ΠΊΠ°ΠΆΠ΄ΡΠΉ ΡΠ°ΠΌ ΡΠ΅ΡΠ°Π΅Ρ ΡΡΠΎ Π»ΡΡΡΠ΅ Π²ΡΠ΅Π³ΠΎ ΠΏΠΎΠ΄ΠΎΠΉΠ΄Π΅Ρ Π½Π° ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΠΎΠΌ ΠΏΡΠΎΠ΅ΠΊΡΠ΅:
-
Π£Π΄Π°Π»ΡΡΡ feature branch Π²ΠΎ Π²ΡΠ΅ΠΌΡ Π±ΠΈΠ»Π΄Π° Π½Π΅ΠΏΡΠ΅ΡΡΠ²Π½ΠΎΠΉ ΠΈΠ½ΡΠ΅Π³ΡΠ°ΡΠΈΠΈ master Π²Π΅ΡΠΊΠΈ.
- ΠΠ»Ρ ΡΡΠΎΠ³ΠΎ Π½Π°Π΄ΠΎ Π·Π½Π°ΡΡ ΠΊΠ°ΠΊΠΎΠΉ pull request ΠΎΡΠ½ΠΎΡΠΈΡΡΡ ΠΊ commit’Ρ, ΠΊΠΎΡΠΎΡΡΠΉ Π±ΠΈΠ»Π΄ΠΈΡΡΡ. Π’Π°ΠΊ ΠΊΠ°ΠΊ feature branch namespace ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ Π² ΡΠ΅Π±Π΅ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ pull request’a β Π΅Π³ΠΎ Π½ΠΎΠΌΠ΅Ρ, ΠΈΠ»ΠΈ Π½Π°Π·Π²Π°Π½ΠΈΠ΅ Π²Π΅ΡΠΊΠΈ, ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ Π²ΡΠ΅Π³Π΄Π° ΠΏΡΠΈΠ΄Π΅ΡΡΡ ΡΠΊΠ°Π·ΡΠ²Π°ΡΡ Π² commit’e.
- ΠΠΈΠ»Π΄Ρ master Π²Π΅ΡΠΎΠΊ ΡΠ΅ΠΉΠ»ΡΡΡΡ. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, Ρ Π²Π°Ρ ΡΠ»Π΅Π΄ΡΡΡΠΈΠ΅ ΡΡΠ°ΠΏΡ: ΡΠΊΠ°ΡΠ°ΡΡ ΠΏΡΠΎΠ΅ΠΊΡ, Π·Π°ΠΏΡΡΡΠΈΡΡ ΡΠ΅ΡΡΡ, ΡΠΎΠ±ΡΠ°ΡΡ ΠΏΡΠΎΠ΅ΠΊΡ, ΡΠ΄Π΅Π»Π°ΡΡ ΡΠ΅Π»ΠΈΠ·, ΠΎΡΠΏΡΠ°Π²ΠΈΡΡ ΡΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΡ, ΠΎΡΠΈΡΡΠΈΡΡ feature branch ΠΏΠΎΡΠ»Π΅Π΄Π½Π΅Π³ΠΎ pull request’a. ΠΡΠ»ΠΈ Π±ΠΈΠ»Π΄ ΡΡΠ΅ΠΉΠ»ΠΈΡΡΡ Π½Π° ΠΎΡΠΏΡΠ°Π²ΠΊΠ΅ ΡΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΡ, Π²Π°ΠΌ ΠΏΡΠΈΠ΄Π΅ΡΡΡ ΡΠ΄Π°Π»ΡΡΡ Π²ΡΠ΅ ΡΠ΅ΡΡΡΡΡ Π² ΠΊΠ»Π°ΡΡΠ΅ΡΠ΅ ΡΡΠΊΠ°ΠΌΠΈ.
- ΠΠ΅Π· Π΄ΠΎΠ»ΠΆΠ½ΠΎΠ³ΠΎ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ°, ΡΠ΄Π°Π»Π΅Π½ΠΈΠ΅ feature branch’ΠΈ Π² master Π±ΠΈΠ»Π΄Π΅ Π½Π΅ΠΎΡΠ΅Π²ΠΈΠ΄Π½ΠΎ.
-
ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ webhook’ΠΎΠ² (
ΠΏΡΠΈΠΌΠ΅Ρ ).- ΠΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, ΡΡΠΎ Π½Π΅ Π²Π°Ρ ΠΏΠΎΠ΄Ρ
ΠΎΠ΄. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, Π²
Jenkins , ΡΠΎΠ»ΡΠΊΠΎ ΠΎΠ΄ΠΈΠ½ Π²ΠΈΠ΄ ΠΏΠ°ΠΉΠΏΠ»Π°ΠΉΠ½Π° ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅Ρ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ ΡΠΎΡ ΡΠ°Π½ΡΡΡ Π΅Π³ΠΎ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ Π² ΠΈΡΡ ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠΎΠ΄Π΅. ΠΡΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠΈ webhook’ΠΎΠ² Π½ΡΠΆΠ½ΠΎ Π½Π°ΠΏΠΈΡΠ°ΡΡ ΡΠ²ΠΎΠΉ ΡΠΊΡΠΈΠΏΡ Π΄Π»Ρ ΠΈΡ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ. ΠΡΠΎΡ ΡΠΊΡΠΈΠΏΡ ΠΏΡΠΈΠ΄Π΅ΡΡΡ ΡΠ°Π·ΠΌΠ΅ΡΠ°ΡΡ Π² ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ΅ Jenkins’Π°, ΡΡΠΎ ΡΡΡΠ΄Π½ΠΎ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°ΡΡ.
- ΠΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, ΡΡΠΎ Π½Π΅ Π²Π°Ρ ΠΏΠΎΠ΄Ρ
ΠΎΠ΄. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, Π²
-
ΠΠ°ΠΏΠΈΡΠ°ΡΡ
Cronjob ΠΈ Π΄ΠΎΠ±Π°Π²ΠΈΡΡ Kubernetes ΠΊΠ»Π°ΡΡΠ΅Ρ.- ΠΠ°ΡΡΠ°ΡΠ° Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ Π½Π° Π½Π°ΠΏΠΈΡΠ°Π½ΠΈΠ΅ ΠΈ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΊΡ.
- ΠΠΏΠ΅ΡΠ°ΡΠΎΡ ΡΠΆΠ΅ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ Π² ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎΠΌ ΡΡΠΈΠ»Π΅, Π·Π°Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠΈΡΠΎΠ²Π°Π½ ΠΈ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅ΡΡΡ.
Π‘ΠΏΠ°ΡΠΈΠ±ΠΎ Π·Π° Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ ΠΊ ΡΡΠ°ΡΡΠ΅.
ΠΡΡΠΎΡΠ½ΠΈΠΊ: habr.com