Repository: honeydipper/honeydipper
Pull request #515 (2023-02-21 18:26:14)

chore(release): release
Highlights:

 * fix(core): resume_token should be unique among cluster members
 
This should make the daemon work well in a cluster.


Patch:
diff --git a/go.mod b/go.mod
index 11be3be..033e59e 100644
--- a/go.mod
+++ b/go.mod
@@ -9,8 +9,6 @@ require (
 	cloud.google.com/go/storage v1.27.0
 	github.com/DataDog/datadog-go v4.8.3+incompatible
 	github.com/Masterminds/goutils v1.1.1 // indirect
-	github.com/Masterminds/semver v1.5.0 // indirect
-	github.com/Masterminds/sprig v2.22.0+incompatible
 	github.com/casbin/casbin/v2 v2.41.0
 	github.com/ghodss/yaml v1.0.0
 	github.com/gin-gonic/gin v1.7.7
@@ -24,8 +22,8 @@ require (
 	github.com/google/gofuzz v1.2.0 // indirect
 	github.com/google/uuid v1.3.0
 	github.com/googleapis/gax-go/v2 v2.7.0
-	github.com/huandu/xstrings v1.3.2 // indirect
-	github.com/imdario/mergo v0.3.12
+	github.com/huandu/xstrings v1.4.0 // indirect
+	github.com/imdario/mergo v0.3.13
 	github.com/json-iterator/go v1.1.12 // indirect
 	github.com/logrusorgru/aurora/v3 v3.0.0
 	github.com/mattn/go-runewidth v0.0.13 // indirect
@@ -35,11 +33,11 @@ require (
 	github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
 	github.com/qiangmzsx/string-adapter/v2 v2.1.0
 	github.com/stretchr/testify v1.8.1
-	golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8
-	golang.org/x/net v0.5.0 // indirect
+	golang.org/x/crypto v0.6.0
+	golang.org/x/net v0.7.0 // indirect
 	golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783
-	golang.org/x/term v0.4.0
-	golang.org/x/text v0.6.0 // indirect
+	golang.org/x/term v0.5.0
+	golang.org/x/text v0.7.0 // indirect
 	google.golang.org/api v0.103.0
 	google.golang.org/genproto v0.0.0-20230202175211-008b39050e57
 	gopkg.in/h2non/gock.v1 v1.0.15
@@ -110,15 +108,21 @@ require (
 	sigs.k8s.io/yaml v1.3.0 // indirect
 )
 
-require github.com/go-redis/redismock/v8 v8.0.6
+require (
+	github.com/Masterminds/sprig/v3 v3.2.3
+	github.com/go-redis/redismock/v8 v8.0.6
+)
 
 require (
 	cloud.google.com/go/compute v1.13.0 // indirect
 	cloud.google.com/go/compute/metadata v0.2.1 // indirect
 	cloud.google.com/go/iam v0.10.0 // indirect
 	cloud.google.com/go/longrunning v0.4.0 // indirect
+	github.com/Masterminds/semver/v3 v3.2.0 // indirect
 	github.com/googleapis/enterprise-certificate-proxy v0.2.0 // indirect
+	github.com/shopspring/decimal v1.3.1 // indirect
+	github.com/spf13/cast v1.5.0 // indirect
 	golang.org/x/sync v0.1.0 // indirect
-	golang.org/x/sys v0.4.0 // indirect
+	golang.org/x/sys v0.5.0 // indirect
 	golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
 )
diff --git a/go.sum b/go.sum
index c73ecdb..551e981 100644
--- a/go.sum
+++ b/go.sum
@@ -72,10 +72,10 @@ github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible h1
 github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
 github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
 github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
-github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
-github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
-github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60=
-github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
+github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7YgDP83g=
+github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
+github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA=
+github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM=
 github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
 github.com/Microsoft/go-winio v0.5.1 h1:aPJp2QD7OOrhO5tQXqQoGSJc+DjDtWTGLOmNyAm6FgY=
 github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
@@ -135,6 +135,7 @@ github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYF
 github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
 github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
 github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
+github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
 github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
 github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
 github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI=
@@ -268,6 +269,7 @@ github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLe
 github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
 github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
 github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
+github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
 github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@@ -288,13 +290,15 @@ github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplb
 github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
 github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
 github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
-github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw=
-github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
+github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
+github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU=
+github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
 github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
 github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
 github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
-github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
-github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
+github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
+github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk=
+github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg=
 github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
 github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
 github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
@@ -340,6 +344,7 @@ github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27k
 github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
 github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
 github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
+github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
 github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
 github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
 github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
@@ -347,6 +352,7 @@ github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrk
 github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
 github.com/mitchellh/mapstructure v1.4.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGgCcyj8cs=
 github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
+github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
 github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
 github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
 github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
@@ -401,8 +407,14 @@ github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6po
 github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
 github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
 github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
+github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
+github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
+github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
 github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
 github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
+github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
+github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
+github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=
 github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
 github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
 github.com/src-d/gcfg v1.4.0 h1:xXbNR5AlLSA315x2UO+fTSSAXCDf+Ar38/6oyGbDKQ4=
@@ -436,6 +448,7 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
 github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
 go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
 go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
 go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
@@ -464,9 +477,11 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
-golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8 h1:GIAS/yBem/gq2MUqgNIzUHW7cJMmx3TGZOrnyYaNQ6c=
-golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
+golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc=
+golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -501,6 +516,7 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -542,8 +558,10 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b
 golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
-golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw=
-golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
+golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
+golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -569,6 +587,7 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
 golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -626,12 +645,16 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18=
-golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
-golang.org/x/term v0.4.0 h1:O7UWfv5+A2qiuulQk30kVinPoMtoIPeVaKLEgLpVkvg=
-golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ=
+golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
+golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY=
+golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -641,8 +664,9 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
-golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k=
-golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
+golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -702,6 +726,7 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f
 golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
 golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -848,6 +873,7 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
diff --git a/internal/config/config.go b/internal/config/config.go
index a31e4e4..2f6ea4e 100644
--- a/internal/config/config.go
+++ b/internal/config/config.go
@@ -12,6 +12,7 @@ import (
 	"bytes"
 	"encoding/gob"
 	"fmt"
+	"os"
 	"strings"
 	"sync"
 	"time"
@@ -79,6 +80,7 @@ type Config struct {
 	Stage         int
 	Staged        *DataSet
 	StageWG       []*sync.WaitGroup
+	Overrides     map[string]string
 }
 
 // ResetStage resets the stage of the config.
@@ -110,9 +112,29 @@ func (c *Config) ResetStage() {
 	c.StageWG[StageServing].Add(len(c.Services))
 }
 
+// loadOverrides from the environment variables.
+func (c *Config) loadOverrides() {
+	if c.Overrides == nil {
+		c.Overrides = map[string]string{}
+		for _, ev := range os.Environ() {
+			k, v, _ := strings.Cut(ev, "=")
+			if k == "REPO_OVERRIDE" || strings.HasPrefix(k, "REPO_OVERRIDE_") {
+				remote, override, found := strings.Cut(v, "=>")
+				remote = strings.TrimSpace(remote)
+				override = strings.TrimSpace(override)
+				if !found || remote == "" || override == "" {
+					dipper.Logger.Panicf("invalid repo override definition: %s", ev)
+				}
+				c.Overrides[remote] = override
+			}
+		}
+	}
+}
+
 // Bootstrap loads the configuration during daemon bootstrap.
 // WorkingDir is where git will clone remote repo into.
 func (c *Config) Bootstrap(wd string) {
+	c.loadOverrides()
 	if !c.IsConfigCheck && !c.IsDocGen {
 		c.ResetStage()
 	}
diff --git a/internal/config/repo.go b/internal/config/repo.go
index a4d8b8c..dc24cf9 100644
--- a/internal/config/repo.go
+++ b/internal/config/repo.go
@@ -7,6 +7,7 @@
 package config
 
 import (
+	"bytes"
 	"fmt"
 	"os"
 	"path"
@@ -75,7 +76,12 @@ func (c *Repo) loadFile(filename string) {
 
 	var content DataSet
 	yamlFile := dipper.Must(os.ReadFile(path.Join(c.root, filename[1:]))).([]byte)
-	yamlFile = []byte(dipper.InterpolateGoTemplate(true, "filename", string(yamlFile), map[string]interface{}{"env": dipper.Getenv()}))
+	switch ret := dipper.InterpolateGoTemplate(true, "filename", string(yamlFile), map[string]interface{}{"env": dipper.Getenv()}).(type) {
+	case *bytes.Buffer:
+		yamlFile = ret.Bytes()
+	case string:
+		yamlFile = []byte(ret)
+	}
 	dipper.Must(yaml.Unmarshal(yamlFile, &content))
 
 	if content.Repos != nil {
@@ -144,15 +150,14 @@ func (c *Repo) cloneFetchRepo() {
 func (c *Repo) loadRepo() {
 	defer c.recovering("", c.repo.Repo)
 
-	if c.parent.IsConfigCheck && *c.repo == c.parent.InitRepo {
-		c.root = dipper.Must(filepath.Abs(c.repo.Repo)).(string)
-		dipper.Logger.Infof("using working copy of repo [%v]", c.root)
-		// uncomment below to ensure the working copy is a repo
-		// if _, err = git.PlainOpen(c.root); err != nil {
-		//   panic(err)
-		// }
-	} else {
+	if override, found := c.parent.Overrides[c.repo.Repo]; found {
+		c.root = dipper.Must(filepath.Abs(override)).(string)
+		dipper.Logger.Infof("using [%s] overriding repo [%v]", c.root, c.repo.Repo)
+	} else if _, err := os.Stat(c.repo.Repo); os.IsNotExist(err) || c.repo.Branch != "" {
 		c.cloneFetchRepo()
+	} else {
+		c.root = dipper.Must(filepath.Abs(c.repo.Repo)).(string)
+		dipper.Logger.Infof("using uncommitted files [%v]", c.root)
 	}
 
 	dipper.Logger.Infof("start loading repo [%v]", c.repo.Repo)
@@ -169,37 +174,38 @@ func (c *Repo) refreshRepo() bool {
 
 	defer c.recovering("", c.repo.Repo)
 
-	var repoObj *git.Repository
-	var err error
 	dipper.Logger.Infof("refreshing repo [%v]", c.repo.Repo)
-	if repoObj, err = git.PlainOpen(c.root); err != nil {
-		panic(err)
-	}
-
-	tree := dipper.Must(repoObj.Worktree()).(*git.Worktree)
+	_, overridden := c.parent.Overrides[c.repo.Repo]
+	_, e := os.Stat(c.repo.Repo)
+	usingUncommitted := e == nil && c.repo.Branch == ""
+
+	if !overridden && !usingUncommitted {
+		repoObj := dipper.Must(git.PlainOpen(c.root)).(*git.Repository)
+		tree := dipper.Must(repoObj.Worktree()).(*git.Worktree)
+		opts := &git.PullOptions{
+			RemoteName: "origin",
+		}
 
-	branch := "master"
-	if c.repo.Branch != "" {
-		branch = c.repo.Branch
-	}
+		switch c.repo.Branch {
+		case "":
+			opts.ReferenceName = plumbing.ReferenceName(fmt.Sprintf("refs/heads/%s", c.repo.Branch))
+		default:
+			opts.ReferenceName = plumbing.ReferenceName("refs/heads/master")
+		}
 
-	opts := &git.PullOptions{
-		RemoteName:    "origin",
-		ReferenceName: plumbing.ReferenceName(fmt.Sprintf("refs/heads/%s", branch)),
-	}
-	if strings.HasPrefix(c.repo.Repo, "git@") {
-		if auth := GetGitSSHAuth(c.repo.KeyFile, c.repo.KeyPassEnv); auth != nil {
-			opts.Auth = auth
+		if strings.HasPrefix(c.repo.Repo, "git@") {
+			if auth := GetGitSSHAuth(c.repo.KeyFile, c.repo.KeyPassEnv); auth != nil {
+				opts.Auth = auth
+			}
 		}
-	}
 
-	err = tree.Pull(opts)
-	if errors.Is(err, git.NoErrAlreadyUpToDate) {
-		dipper.Logger.Infof("no changes skip repo [%s]", c.repo.Repo)
+		err := tree.Pull(opts)
+		if errors.Is(err, git.NoErrAlreadyUpToDate) {
+			dipper.Logger.Infof("no changes skip repo [%s]", c.repo.Repo)
 
-		return false
-	} else if err != nil {
-		panic(err)
+			return false
+		}
+		dipper.Must(err)
 	}
 
 	c.DataSet = DataSet{}
diff --git a/internal/service/engine.go b/internal/service/engine.go
index ecea41b..94a7406 100644
--- a/internal/service/engine.go
+++ b/internal/service/engine.go
@@ -48,6 +48,11 @@ func (h *WorkflowHelper) GetConfig() *config.Config {
 	return h.engine.config
 }
 
+// GetDaemonID method gets an identifier to the current daemon.
+func (h *WorkflowHelper) GetDaemonID() string {
+	return h.engine.daemonID
+}
+
 // StartEngine Starts the engine service.
 func StartEngine(cfg *config.Config) {
 	engine = NewService(cfg, "engine")
diff --git a/internal/service/service.go b/internal/service/service.go
index ecb69bb..fe39abb 100644
--- a/internal/service/service.go
+++ b/internal/service/service.go
@@ -75,6 +75,7 @@ type Service struct {
 	ResponseFactory    *api.ResponseFactory
 	healthy            bool
 	drainingGroup      *sync.WaitGroup
+	daemonID           string
 }
 
 var (
@@ -92,6 +93,7 @@ var (
 func NewService(cfg *config.Config, name string) *Service {
 	svc := &Service{
 		name:           name,
+		daemonID:       dipper.GetIP(),
 		config:         cfg,
 		driverRuntimes: map[string]*driver.Runtime{},
 		expects:        map[string][]ExpectHandler{},
@@ -716,7 +718,7 @@ func handleAPI(from *driver.Runtime, m *dipper.Message) {
 
 func handleReload(from *driver.Runtime, m *dipper.Message) {
 	daemonID, ok := m.Labels["daemonID"]
-	if ok && daemonID != dipper.GetIP() {
+	if ok && daemonID != Services[from.Service].daemonID {
 		return
 	}
 
diff --git a/internal/workflow/execute.go b/internal/workflow/execute.go
index e41fee1..982182b 100644
--- a/internal/workflow/execute.go
+++ b/internal/workflow/execute.go
@@ -106,7 +106,7 @@ func (w *Session) executeRound(msg *dipper.Message) {
 		if w.ctx == nil {
 			w.ctx = map[string]interface{}{}
 		}
-		w.ctx["resume_token"] = "/" + w.workflow.Name + "/" + w.ID
+		w.ctx["resume_token"] = w.store.Helper.GetDaemonID() + "/" + w.workflow.Name + "/" + w.ID
 	}
 
 	w.executeIteration(msg)
diff --git a/internal/workflow/mock_workflow/store.go b/internal/workflow/mock_workflow/store.go
index e0aaac1..2d40f43 100644
--- a/internal/workflow/mock_workflow/store.go
+++ b/internal/workflow/mock_workflow/store.go
@@ -56,6 +56,20 @@ func (mr *MockSessionStoreHelperMockRecorder) GetConfig() *gomock.Call {
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetConfig", reflect.TypeOf((*MockSessionStoreHelper)(nil).GetConfig))
 }
 
+// GetDaemonID mocks base method.
+func (m *MockSessionStoreHelper) GetDaemonID() string {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetDaemonID")
+	ret0, _ := ret[0].(string)
+	return ret0
+}
+
+// GetDaemonID indicates an expected call of GetDaemonID.
+func (mr *MockSessionStoreHelperMockRecorder) GetDaemonID() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDaemonID", reflect.TypeOf((*MockSessionStoreHelper)(nil).GetDaemonID))
+}
+
 // SendMessage mocks base method.
 func (m *MockSessionStoreHelper) SendMessage(msg *dipper.Message) {
 	m.ctrl.T.Helper()
diff --git a/internal/workflow/store.go b/internal/workflow/store.go
index 842a53b..eae31bd 100644
--- a/internal/workflow/store.go
+++ b/internal/workflow/store.go
@@ -20,6 +20,7 @@ import (
 type SessionStoreHelper interface {
 	GetConfig() *config.Config
 	SendMessage(msg *dipper.Message)
+	GetDaemonID() string
 }
 
 // SessionStore stores session in memory and provides helper function for session to perform.
diff --git a/pkg/dipper/interpolation.go b/pkg/dipper/interpolation.go
index 98beca1..136e7fc 100644
--- a/pkg/dipper/interpolation.go
+++ b/pkg/dipper/interpolation.go
@@ -14,7 +14,7 @@ import (
 	"text/template"
 	"time"
 
-	"github.com/Masterminds/sprig"
+	"github.com/Masterminds/sprig/v3"
 	"github.com/ghodss/yaml"
 )
 
@@ -48,7 +48,7 @@ func InterpolateStr(pattern string, data interface{}) string {
 }
 
 // InterpolateGoTemplate : parse the string as go template.
-func InterpolateGoTemplate(isLoading bool, title string, pattern string, data interface{}) string {
+func InterpolateGoTemplate(isLoading bool, title string, pattern string, data interface{}) interface{} {
 	ldelim := "{{"
 	rdelim := "}}"
 	if isLoading {
@@ -56,14 +56,35 @@ func InterpolateGoTemplate(isLoading bool, title string, pattern string, data in
 		rdelim = "%}"
 	}
 	if strings.Contains(pattern, ldelim) {
-		tmpl := template.Must(template.New(title).Funcs(FuncMap).Funcs(sprig.TxtFuncMap()).Delims(ldelim, rdelim).Parse(pattern))
+		var ret interface{}
+		useRet := false
+		returnFuncMap := template.FuncMap{
+			"return": func(v interface{}) string {
+				useRet = true
+				ret = v
+
+				return ""
+			},
+		}
+
+		tmpl := template.New(title)
+		tmpl = tmpl.Funcs(FuncMap)
+		tmpl = tmpl.Funcs(sprig.TxtFuncMap())
+		tmpl = tmpl.Funcs(returnFuncMap)
+		tmpl = tmpl.Delims(ldelim, rdelim)
+		parsed := template.Must(tmpl.Parse(pattern))
+
 		buf := new(bytes.Buffer)
-		if err := tmpl.Execute(buf, data); err != nil {
+		if err := parsed.Execute(buf, data); err != nil {
 			Logger.Warningf("interpolation pattern failed: %+v", pattern)
 			Logger.Panicf("failed to interpolate: %+v", err)
 		}
 
-		return buf.String()
+		if useRet {
+			return ret
+		}
+
+		return buf
 	}
 
 	return pattern
@@ -138,7 +159,16 @@ func Interpolate(source interface{}, data interface{}) interface{} {
 			return InterpolateDollarStr(v, data)
 		}
 
-		ret := InterpolateGoTemplate(false, "go", v, data)
+		var ret string
+
+		switch retAnything := InterpolateGoTemplate(false, "go", v, data).(type) {
+		case *bytes.Buffer:
+			ret = retAnything.String()
+		case string:
+			ret = retAnything
+		default:
+			return retAnything
+		}
 
 		if strings.HasPrefix(ret, ":yaml:") {
 			defer func() {
@@ -150,9 +180,8 @@ func Interpolate(source interface{}, data interface{}) interface{} {
 
 			return ParseYaml(ret[6:])
 		}
-		ret = strings.TrimPrefix(ret, "\\")
 
-		return ret
+		return strings.TrimPrefix(ret, "\\")
 	case map[string]interface{}:
 		ret := map[string]interface{}{}
 		for k, val := range v {


Test patch:
diff --git a/internal/config/config_test.go b/internal/config/config_test.go
index e6448be..70871a6 100644
--- a/internal/config/config_test.go
+++ b/internal/config/config_test.go
@@ -82,3 +82,21 @@ func TestRegexParsing(t *testing.T) {
 	assert.Equal(t, "non regex", config.DataSet.Workflows["test-workflow"].UnlessMatch.(map[string]interface{})["key4"], "workflow unless_match non-regex should remain")
 	assert.Equal(t, "non regex", config.DataSet.Rules[0].When.Match["key6"], "rule match non-regex should remain")
 }
+
+func TestLoadValidOverrides(t *testing.T) {
+	config := &Config{}
+	t.Setenv("REPO_OVERRIDE", "https://test.com/foo/bar.git => /tmp/foobar")
+	t.Setenv("REPO_OVERRIDE_ANOTHER", "git@github.com:foo/bar.git => /tmp/foobar")
+
+	assert.NotPanics(t, func() { config.loadOverrides() }, "loadOverride shoud not panic with valid definition")
+	assert.Equal(t, 2, len(config.Overrides), "loadOverride should detect two override definitions")
+	assert.Equal(t, "/tmp/foobar", config.Overrides["https://test.com/foo/bar.git"], "loadOverride should accept REPO_OVERRIDE")
+	assert.Equal(t, "/tmp/foobar", config.Overrides["git@github.com:foo/bar.git"], "loadOverride should accept REPO_OVERRIDE_*")
+}
+
+func TestLoadInvalidOverrides(t *testing.T) {
+	config := &Config{}
+	t.Setenv("REPO_OVERRIDE", "https://test.com/foo/bar.git =>")
+
+	assert.Panics(t, func() { config.loadOverrides() }, "loadOverride shoud panic with invalid definition")
+}
diff --git a/internal/workflow/condition_test.go b/internal/workflow/condition_test.go
index ab65d4b..b07352d 100644
--- a/internal/workflow/condition_test.go
+++ b/internal/workflow/condition_test.go
@@ -29,6 +29,7 @@ func TestConditionElse(t *testing.T) {
 		"msg":      &dipper.Message{},
 		"ctx":      map[string]interface{}{},
 		"asserts": func() {
+			mockHelper.EXPECT().GetDaemonID().Return("")
 			mockHelper.EXPECT().SendMessage(gomock.Eq(&dipper.Message{
 				Channel: "eventbus",
 				Subject: "command",
@@ -77,6 +78,7 @@ func TestSwitchDefault(t *testing.T) {
 		"msg": &dipper.Message{},
 		"ctx": map[string]interface{}{},
 		"asserts": func() {
+			mockHelper.EXPECT().GetDaemonID().Return("")
 			mockHelper.EXPECT().SendMessage(gomock.Eq(&dipper.Message{
 				Channel: "eventbus",
 				Subject: "command",
@@ -127,6 +129,7 @@ func TestSwitch(t *testing.T) {
 		"msg": &dipper.Message{},
 		"ctx": map[string]interface{}{},
 		"asserts": func() {
+			mockHelper.EXPECT().GetDaemonID().Return("")
 			mockHelper.EXPECT().SendMessage(gomock.Eq(&dipper.Message{
 				Channel: "eventbus",
 				Subject: "command",
@@ -186,6 +189,7 @@ func TestWorkflowLoop(t *testing.T) {
 		"msg": &dipper.Message{},
 		"ctx": map[string]interface{}{},
 		"asserts": func() {
+			mockHelper.EXPECT().GetDaemonID().Return("")
 			mockHelper.EXPECT().SendMessage(gomock.Eq(&dipper.Message{
 				Channel: "eventbus",
 				Subject: "command",
diff --git a/internal/workflow/session_context_test.go b/internal/workflow/session_context_test.go
index 53ad705..fc3bde4 100644
--- a/internal/workflow/session_context_test.go
+++ b/internal/workflow/session_context_test.go
@@ -127,6 +127,7 @@ func TestWorkflowWithEventContext(t *testing.T) {
 		"msg":      &dipper.Message{},
 		"ctx":      map[string]interface{}{},
 		"asserts": func() {
+			mockHelper.EXPECT().GetDaemonID().Return("")
 			mockHelper.EXPECT().SendMessage(gomock.Eq(&dipper.Message{
 				Channel: "eventbus",
 				Subject: "command",
@@ -195,6 +196,7 @@ func TestWorkflowWithEventSectionInContext(t *testing.T) {
 		"msg":      &dipper.Message{},
 		"ctx":      map[string]interface{}{},
 		"asserts": func() {
+			mockHelper.EXPECT().GetDaemonID().Return("")
 			mockHelper.EXPECT().SendMessage(gomock.Eq(&dipper.Message{
 				Channel: "eventbus",
 				Subject: "command",
@@ -268,6 +270,7 @@ func TestWorkflowWithNamedContext(t *testing.T) {
 		"msg": &dipper.Message{},
 		"ctx": map[string]interface{}{},
 		"asserts": func() {
+			mockHelper.EXPECT().GetDaemonID().Return("")
 			mockHelper.EXPECT().SendMessage(gomock.Eq(&dipper.Message{
 				Channel: "eventbus",
 				Subject: "command",
diff --git a/internal/workflow/session_faulttolerant_test.go b/internal/workflow/session_faulttolerant_test.go
index dffd032..cf9890b 100644
--- a/internal/workflow/session_faulttolerant_test.go
+++ b/internal/workflow/session_faulttolerant_test.go
@@ -56,6 +56,7 @@ func TestWorkflowErrorWorkflowNotDefined(t *testing.T) {
 		"ctx":      map[string]interface{}{},
 		"steps":    []map[string]interface{}{},
 		"asserts": func() {
+			mockHelper.EXPECT().GetDaemonID().Return("")
 			mockHelper.EXPECT().SendMessage(gomock.Any()).Times(0)
 		},
 	}
@@ -92,6 +93,7 @@ func TestWorkflowIterateEmptyAsChild(t *testing.T) {
 		"ctx":   map[string]interface{}{},
 		"steps": []map[string]interface{}{},
 		"asserts": func() {
+			mockHelper.EXPECT().GetDaemonID().Return("")
 			mockHelper.EXPECT().SendMessage(gomock.Any()).Times(0)
 		},
 	}
diff --git a/internal/workflow/session_hook_test.go b/internal/workflow/session_hook_test.go
index 78ec228..b49dc0d 100644
--- a/internal/workflow/session_hook_test.go
+++ b/internal/workflow/session_hook_test.go
@@ -34,6 +34,7 @@ func TestOnSessionHook(t *testing.T) {
 			},
 		},
 		"asserts": func() {
+			mockHelper.EXPECT().GetDaemonID().AnyTimes().Return("")
 			mockHelper.EXPECT().SendMessage(gomock.Eq(&dipper.Message{
 				Channel: "eventbus",
 				Subject: "command",
@@ -68,6 +69,9 @@ func TestOnSessionHook(t *testing.T) {
 					},
 				},
 				"ctx": map[string]interface{}{},
+				"asserts": func() {
+					mockHelper.EXPECT().GetDaemonID().AnyTimes().Return("")
+				},
 			},
 		},
 	}
@@ -85,6 +89,7 @@ func TestOnFirstActionHook(t *testing.T) {
 			},
 		},
 		"asserts": func() {
+			mockHelper.EXPECT().GetDaemonID().Return("")
 			mockHelper.EXPECT().SendMessage(gomock.Eq(&dipper.Message{
 				Channel: "eventbus",
 				Subject: "command",
@@ -153,6 +158,7 @@ func TestOnExitHook(t *testing.T) {
 			},
 		},
 		"asserts": func() {
+			mockHelper.EXPECT().GetDaemonID().Return("")
 			mockHelper.EXPECT().SendMessage(gomock.Eq(&dipper.Message{
 				Channel: "eventbus",
 				Subject: "command",
@@ -205,6 +211,7 @@ func TestOnSuccessHook(t *testing.T) {
 			},
 		},
 		"asserts": func() {
+			mockHelper.EXPECT().GetDaemonID().Return("")
 			mockHelper.EXPECT().SendMessage(gomock.Eq(&dipper.Message{
 				Channel: "eventbus",
 				Subject: "command",
@@ -259,6 +266,7 @@ func TestOnFailureHook(t *testing.T) {
 			},
 		},
 		"asserts": func() {
+			mockHelper.EXPECT().GetDaemonID().Return("")
 			mockHelper.EXPECT().SendMessage(gomock.Eq(&dipper.Message{
 				Channel: "eventbus",
 				Subject: "command",
@@ -360,6 +368,7 @@ func TestOnErrorHook(t *testing.T) {
 			},
 		},
 		"asserts": func() {
+			mockHelper.EXPECT().GetDaemonID().Return("")
 			mockHelper.EXPECT().SendMessage(gomock.Eq(&dipper.Message{
 				Channel: "eventbus",
 				Subject: "command",
@@ -458,6 +467,7 @@ func TestFailureInHook(t *testing.T) {
 			},
 		},
 		"asserts": func() {
+			mockHelper.EXPECT().GetDaemonID().Return("")
 			mockHelper.EXPECT().SendMessage(gomock.Eq(&dipper.Message{
 				Channel: "eventbus",
 				Subject: "command",
@@ -508,6 +518,7 @@ func TestErrorInCompletionHook(t *testing.T) {
 			},
 		},
 		"asserts": func() {
+			mockHelper.EXPECT().GetDaemonID().Return("")
 			mockHelper.EXPECT().SendMessage(gomock.Eq(&dipper.Message{
 				Channel: "eventbus",
 				Subject: "command",
diff --git a/internal/workflow/session_parallel_test.go b/internal/workflow/session_parallel_test.go
index ce472d6..e8ba3cb 100644
--- a/internal/workflow/session_parallel_test.go
+++ b/internal/workflow/session_parallel_test.go
@@ -65,6 +65,7 @@ func TestWorkflowIterateParallel(t *testing.T) {
 		"msg": &dipper.Message{},
 		"ctx": map[string]interface{}{},
 		"asserts": func() {
+			mockHelper.EXPECT().GetDaemonID().AnyTimes().Return("")
 			mockHelper.EXPECT().SendMessage(DipperMsgEq(&dipper.Message{
 				Channel: "eventbus",
 				Subject: "command",
@@ -188,6 +189,7 @@ func TestWorkflowThreads(t *testing.T) {
 		"msg": &dipper.Message{},
 		"ctx": map[string]interface{}{},
 		"asserts": func() {
+			mockHelper.EXPECT().GetDaemonID().AnyTimes().Return("")
 			mockHelper.EXPECT().SendMessage(DipperMsgEq(&dipper.Message{
 				Channel: "eventbus",
 				Subject: "command",
diff --git a/internal/workflow/store_session_test.go b/internal/workflow/store_session_test.go
index f932570..da1b642 100644
--- a/internal/workflow/store_session_test.go
+++ b/internal/workflow/store_session_test.go
@@ -49,6 +49,7 @@ func TestWorkflowNoopAsChild(t *testing.T) {
 		"ctx":   map[string]interface{}{},
 		"steps": []map[string]interface{}{},
 		"asserts": func() {
+			mockHelper.EXPECT().GetDaemonID().AnyTimes().Return("")
 			mockHelper.EXPECT().SendMessage(gomock.Any()).Times(0)
 		},
 	}
@@ -68,6 +69,7 @@ func TestWorkflowNoop(t *testing.T) {
 		"ctx":   map[string]interface{}{},
 		"steps": []map[string]interface{}{},
 		"asserts": func() {
+			mockHelper.EXPECT().GetDaemonID().AnyTimes().Return("")
 			mockHelper.EXPECT().SendMessage(gomock.Any()).Times(0)
 		},
 	}
@@ -81,6 +83,7 @@ func TestCallWorkflow(t *testing.T) {
 		"ctx":      map[string]interface{}{},
 		"steps":    []map[string]interface{}{},
 		"asserts": func() {
+			mockHelper.EXPECT().GetDaemonID().AnyTimes().Return("")
 			mockHelper.EXPECT().SendMessage(gomock.Any()).Times(0)
 		},
 	}
@@ -93,6 +96,7 @@ func TestCallDriver(t *testing.T) {
 		"msg":      &dipper.Message{},
 		"ctx":      map[string]interface{}{},
 		"asserts": func() {
+			mockHelper.EXPECT().GetDaemonID().AnyTimes().Return("")
 			mockHelper.EXPECT().SendMessage(gomock.Eq(&dipper.Message{
 				Channel: "eventbus",
 				Subject: "command",
@@ -142,6 +146,7 @@ func TestCallFunction(t *testing.T) {
 		"msg":      &dipper.Message{},
 		"ctx":      map[string]interface{}{},
 		"asserts": func() {
+			mockHelper.EXPECT().GetDaemonID().AnyTimes().Return("")
 			mockHelper.EXPECT().SendMessage(gomock.Eq(&dipper.Message{
 				Channel: "eventbus",
 				Subject: "command",
@@ -202,6 +207,7 @@ func TestWorkflowSteps(t *testing.T) {
 		"msg": &dipper.Message{},
 		"ctx": map[string]interface{}{},
 		"asserts": func() {
+			mockHelper.EXPECT().GetDaemonID().AnyTimes().Return("")
 			mockHelper.EXPECT().SendMessage(gomock.Eq(&dipper.Message{
 				Channel: "eventbus",
 				Subject: "command",
@@ -302,6 +308,7 @@ func TestWorkflowResumeWithTimeout(t *testing.T) {
 		"msg": &dipper.Message{},
 		"ctx": map[string]interface{}{},
 		"asserts": func() {
+			mockHelper.EXPECT().GetDaemonID().AnyTimes().Return("")
 			mockHelper.EXPECT().SendMessage(gomock.Eq(&dipper.Message{
 				Channel: "eventbus",
 				Subject: "command",
@@ -367,6 +374,7 @@ func TestWorkflowResume(t *testing.T) {
 		"msg": &dipper.Message{},
 		"ctx": map[string]interface{}{},
 		"asserts": func() {
+			mockHelper.EXPECT().GetDaemonID().AnyTimes().Return("")
 			mockHelper.EXPECT().SendMessage(gomock.Eq(&dipper.Message{
 				Channel: "eventbus",
 				Subject: "command",
@@ -438,6 +446,7 @@ func TestContinueNonexistSession(t *testing.T) {
 		"msg":      &dipper.Message{},
 		"ctx":      map[string]interface{}{},
 		"asserts": func() {
+			mockHelper.EXPECT().GetDaemonID().AnyTimes().Return("")
 			mockHelper.EXPECT().SendMessage(gomock.Any()).Times(0)
 		},
 		"steps": []map[string]interface{}{
@@ -479,6 +488,7 @@ func TestWorkflowResumeCrash(t *testing.T) {
 		"msg": &dipper.Message{},
 		"ctx": map[string]interface{}{},
 		"asserts": func() {
+			mockHelper.EXPECT().GetDaemonID().AnyTimes().Return("")
 			mockHelper.EXPECT().SendMessage(gomock.Eq(&dipper.Message{
 				Channel: "eventbus",
 				Subject: "command",
@@ -558,6 +568,7 @@ func TestWorkflowIterate(t *testing.T) {
 		"msg": &dipper.Message{},
 		"ctx": map[string]interface{}{},
 		"asserts": func() {
+			mockHelper.EXPECT().GetDaemonID().AnyTimes().Return("")
 			mockHelper.EXPECT().SendMessage(gomock.Eq(&dipper.Message{
 				Channel: "eventbus",
 				Subject: "command",
diff --git a/pkg/dipper/interpolation_test.go b/pkg/dipper/interpolation_test.go
index c5c1779..5048a76 100644
--- a/pkg/dipper/interpolation_test.go
+++ b/pkg/dipper/interpolation_test.go
@@ -10,6 +10,7 @@
 package dipper
 
 import (
+	"bytes"
 	"testing"
 
 	"github.com/stretchr/testify/assert"
@@ -76,6 +77,8 @@ test:
 func TestInterpolateGoTemplate(t *testing.T) {
 	assert.Equal(t, "{% not interpolated %}", InterpolateGoTemplate(false, "go", "{% not interpolated %}", map[string]interface{}{}), "should not interpolate {%%} in non-loading time")
 	assert.Equal(t, "{{ not interpolated }}", InterpolateGoTemplate(true, "test.yml", "{{ not interpolated }}", map[string]interface{}{}), "should not interpolate {{}} in loading time")
-	assert.Equal(t, "test", InterpolateGoTemplate(false, "go", "{{ .env.TEST_ENV }}", map[string]interface{}{"env": map[string]interface{}{"TEST_ENV": "test"}}), "should interpolate {{}} in non-loading time")
-	assert.Equal(t, "test", InterpolateGoTemplate(true, "test.yml", "{% .env.TEST_ENV %}", map[string]interface{}{"env": map[string]interface{}{"TEST_ENV": "test"}}), "should interpolate {%%} in loading time")
+	assert.Equal(t, "test", InterpolateGoTemplate(false, "go", "{{ .env.TEST_ENV }}", map[string]interface{}{"env": map[string]interface{}{"TEST_ENV": "test"}}).(*bytes.Buffer).String(), "should interpolate {{}} in non-loading time")
+	assert.Equal(t, "test", InterpolateGoTemplate(true, "test.yml", "{% .env.TEST_ENV %}", map[string]interface{}{"env": map[string]interface{}{"TEST_ENV": "test"}}).(*bytes.Buffer).String(), "should interpolate {%%} in loading time")
+	assert.Equal(t, true, InterpolateGoTemplate(false, "go", "{{ return true }}", map[string]interface{}{}), "should return a boolean type")
+	assert.Equal(t, map[string]interface{}{"foo": "bar"}, InterpolateGoTemplate(false, "go", "{{ dict \"foo\" \"bar\" | return }}", map[string]interface{}{}), "should return a map type")
 }