From 137732a6f27ac55cbce4b6d3d3022dd577c43c47 Mon Sep 17 00:00:00 2001 From: zaynelt <16801980+zaynelt@users.noreply.github.com> Date: Sun, 28 Jun 2026 18:50:30 -0700 Subject: [PATCH 1/2] Add OG social card for GitHub repo preview Co-Authored-By: Claude Opus 4.6 --- assets/og-image.png | Bin 0 -> 53734 bytes assets/og-image.svg | 54 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 assets/og-image.png create mode 100644 assets/og-image.svg diff --git a/assets/og-image.png b/assets/og-image.png new file mode 100644 index 0000000000000000000000000000000000000000..3e43318a05977600180d7687394f8f4cdcf7b2fd GIT binary patch literal 53734 zcmc$_byQqmmn}*RLI{vx!3pjmKyV8l+}(l)cb7`g-~kGEcemgP!5xai9SVm+3n>a- zCHeY(w}0KE-~Ho`_r^E_P8IuXS$plZ=9=>mrmQH9`Hc7(3JMCQ%m)co6qLu+C@2rz zpFTu>^MmRD0|n&;ij0J)x@Y>q5}Gd_m;m*-b+`SJTntC{_4&Au16A(VuTk`0sj{gU z2o9d8yi{S){+65V8oTTRZKwJ6?c1`?oJU-+dELe6QU0O-y-}t^O1lq-0B36o=k{nj z0d8ECT(ZPqexyut{a&X=OhG~nRL!^eSQ~!oQ-fzRNGtb7e&fZ&wic)(g3?M7ki9n#v30w)2TO-b_d%}!Oc8@KUBhZ52!;-kr*)o%AX z<@Ds;_J7o~bY`8Fq_3;5{0x|e-8plyV=8@kF5mBV*kH|`FeAF!*xspMj;LfUJZ3Fv zLHZ2lBDDNQL|y3wvu!q~euWmi(stv9`+WsdcDSB~2FGon?g8AuRP4$4z=+7ZYS%&t$#St&5wy(vXjywzg{l8?hVbqs zmWAb2Ym_x4EyBz4tMwZ#6BcY__maDuOF|&whXuNq0kWiSdNQzw4SH2KFKNNm>5QEo z3ewrKqy-*Dzc)_HnhgMz)zi3J)-W2LvJ(pa(q6((IHuMP|EAeffY}M4h zTQw_Sq6AL&%WNVb)=ERq<#V+!0D{_<;A9*+cbtOnSj5!D9T8}H?_u@X4U^USe1*n( zr-t%wMQx~>kqNL?6SEpvtFwFsTnhx9B#7Tf>@7pN4A`fAI+-iQ8cAq}N82{XXb*87XsC5=1F6K}wpYO2wB!d~&g zS}tPcg;ewoMu%x?l!_OSTKpNqIklT8>!hLimHWoFPOf}eCvujV%(jzW6+`sGmRB^` zuwZAko{G}bWqd=X`_MsWFzgvz&VaNcL8#}F0bG46n!X3{$D5Xj6-(b6!iV`>@RsVy z5J>-W4n`EXmX|Kbw#4x)^MdaencgHpgRPx5ZQ!pt)MlYfdP*j^oS6@hVIBqL^DevT zpBt2qao=A24*e)7$qY0>f4`%9hEDnC?sJ%!*wa6EA9MfR3?qY;#v(x`uRb?`2-WEY z+CQ&74N{kg&)oBQv&{m!^EyfR38fjRK!6>xWpc+qn-|foXAd#_YqYr8?#P*mhXvZ* zqNM-0Oe6CIC?EfwUtZ9gyuWwP4_*I4Us{V1{4k-z_aDJpb}CaL_j1TJk&7*SQ;6WN-t zfxQ2?dI_aH{IHAlsPtbM*5Br~X#TZg)FI08G&F1-&UCnaSoPjEvyBi@Y$AOkmh%MTfK9}Hk z+h74{X@&~eA}vYs2OE3qmilK&BEpV0#E*V=@p&(jl@gdRV}_pAVoA;51!8NC+x~)` zxCki!t{k&k8jC-nR(r2%@wHz01(T$Em_3V+;4Ro87Wa>@GO(8hIo^C9ovC+aE>DSi5~iAoYm0#M{lp9jXpDt|<<|0rM@uDksK2N1 zQJ#jIeM9F_UpyvLEF|dsC%b z(`P6hh8i9Sz`0yjdnZ(|^CM*+xWO14cTeT*e#Lw?0}ztT%p56^eaaQZA*(ZYQ)Q_6 zyr-Es+zAhmp(_i`;AHtd^yd@y5U;1fTed;YZ|5+5!aY!}e^R9APNr6u##%6BO-;$) z;Q_e&kCqHQ9U9DkZ8PK^$lYl-{K}uiITT{rW-t>48jXxECabc^uGLF`QZj{}7Q|ty zZuR16Y7beDtKD3@1m7L)Fv{9b!0~<$7^xAc^c0eU4;U?+HI$n#)Fw9*`=qpRgf>IZ zq2`%Znir?Z+)%Rlk<-%qo;}DpMy#Pp6s7Ar3%a@|sp-w*&$A0F{|}K&+Zml-1T$x@e4# zatJI4W+v@{azhE31uaIJ?!mSfQl%1!mSNV^B8%}t^PxJr)fs(r*kvi|rET*-JI&~1 zVzQr!>OQg;h62|(VBbPHFqvOCQPO%{?V>6prrH4+Q!7a6L`QZTuhm0SuV!ya7EG`R zbmn8NlTapS=xmMYDy4Hf?bc>bOK9I)zEN-2WSl{oruf8hQRz>-mMSu)51JneROl00 zzW&w3a&WM7Qo$Mz5 z3}XWkfBt1BiHGJ07exus&N|iko3C)n2%!h`qI@cWZk9D1Fj{8=gXUsLB|4Zye-J|-U8K^H-=u@#d`7ra2S zfF;R_j9PlURW17YZ>xXAi(DfYE4W5A54eFH+(G(kZNELn-T`gwD`}+d9`LpRvYZ`# znBkC^d!`{&nXfkEMyCEAO)hFWWlOdAdWas^-lqArFW9xBDH90oPOQkR!k5axIEq6| zGvJ=5b$rWUT!s>8U8v6rH6KuTTzJE&75h|O|HPUuC}SDrQa^Cxc8%7 z8izmF!l;HX*wCja74lC{89uHh%C+x0Bz5uVD0g`_ASet~=HGp7X8Z_8sS=2rQXUfJv3 z);i)nw$nfAaeuEgo19}l==dfTkdT;f^d0DS7&6~miYwV4?rGgus^es#A>&mt*##-m zERFF6bWebd)^KoW%~(nZ+mD@25dJT(0#QIR#+xePh{3ye(fPL7E8;= zkMhpj&qNm872^v5)ptWmn%08cu-mH5m5?uic1uq zL!O1?t(Y`F8GO*{zW?)`+TbOgG!$rQ6D~uo1W;j3NoHVFgCytbVx*P2D2~hR^tE5& z-Artdi=97t^4km_1@j^Yk6Pn3)!+V_l1LAxosGKTWtW6${Fkk^Az@?qTa;76v>|(ucmYhI zwHI@Mt()i3Nz4S;2{$9t+hb4uH=OVrGgy*hWT+f0lI@C$dRJ2JtBX5fWj2fPQEHqq zED`gYHK}e)-Ue{4+_U(kdmbNGa}DWd={o-h7qHtIh8F$lnV}B-VpHgz!?}?{N%kVN zY@2MwK!bj9B&5RNXoglw&dkfPpgQ`?-2|J^%BQPUYKqb3(`}L3U{%Ief+}{bcD1=c zBv>dDW?m3Jn>o@@a4x0w(a?|pbD!#MF^rZ3ZT@;?D!|?9F+*!^Q<{=IDG_Y#z%|ve z0^yWrsE8|MWXCEVCjZHIRm75gd&Q?Mv{b-fy7xX$78jqXbUO>9knKMKD)t6m%#NYr za%Cw=vBMDtJ%N*++r}y-@UpySD<~7Q(Z|nvVWx=meqFR`0@uh_e2xwz$!I%urW7Mw z9pyfa+#ASTwxT+QdFoIgN9dd0y#vXTM%`kdjUVFjO%Fgd;N96BrhhG^p#|Yv!4jCp zD-n8L6p8S9?k?%C1wAjhg@ zR(qAZx3{GFpd7!W1bY%lytTAkmGP-$;k`ZK$z!F*V>`vuYDV?$E_|)WNqTzjZ|(2x z7is1E7%A2DD9tXL##-3unIVct?L`a?@+&$ObcOF8WV4J$Iz6&DPFTg;4-JnMx=}O* zUnZFtsO%;&C6Jo4GlS~j?J_B1vELHQG>`GL#CL<8vD+Iz-j|fgn?I9aRc|sx-0S}v zXa2#QJCS*JCPQ8OpCpY+=5T*zZEK~$V#h~75{GQ=Fr@by;7MIJrnER0@k zd~-JMHb^cxhB}8h%u^p#T}V+Y2`_$UoGpkomX2H6E|akSR@izwK#Pb*`4-K=}SU89_&ylhv0x zTuKh~9m!SPwWDuJzO=VsA}qs~*%9QdWD7&XvOr#3UDV3I1CKeC_tc5pxH)rXb*# z&&ej`eB^|rk|uP>fjse+Y0+OE*ck!%iXGUPo*Q13gI4x0lrFw^Rgz!%9O>(Kw8vIhmQiFFW}Ex;5QJ0e1NP0ZV;D%k zy1`_^Z{f0;JXuQ7x;Jdib?IC$w^caAZ~d&PSoWcL1*edw;gQ20?zaE8%897hzeOq` zvnipvlp?p1&<2S?h^4L=pF&_nX@kSf0&>|{MAde;o9$Jjs%e;mXBwr?IDXp=<#WqN zb#zL#HB5AynkgVlGV=V6o72-7y1GXzouPMSh-uNkkENR0 zqEq6dUl-9XBDYykQf&0}X~?mn+B z-=2Kgaf%YQDygjc4hBRG1|En0sgOR;8>=Jp+JIEj?jpx&6pw{XR*|9MpqyZ~ldhNo zM6@sab0ete@x`vwRp3}vrFO+paDr)yHPnXR^#c^Zb5x#cM^!6TLg%g3}dxVkcwwp*phsx6JZ=GfRWr8l~bi&*Wgk$Z%!VIzUlx-H= znJbmNUm@ToyS$p-He9^l^3mNQq#=8YKd^29{3a zG&KD=U7z{Q>d`52d0U<*oFc)VnjX2Wh|7F`g$-wwzTTYO>Y*LKbqq&{du|w{qAb);*~%xt-k^PqzI!55W!jPae3q-;{FV4QP_B} zp>yV~Js#!hiFEqIN1Hk76DPE%d^y+%&YPugfGo~K|4*nT=ilUcqus9b96g;A%i%Ff%N9M#s52hzi zHy0hYyXDhQ^az9!Id(HUVaYPXUF1XrXGij~54Bv6l5l^g^Y6F9&Wsx=@61b;w5d(6_9^tR%9VwbYj*09>j+o z+E>CNxeQ<-kwguQ_;Z-1^rQ?afor4&TLYmhk&F&ZJ}ky@nae_!tn(8m?K;vTnXMOd zuQcj@BKKvnRr(}qZoZEr>eK^1Ti0KbD*+o*G+qXDj<3j5sn}9e*aMx#G#@cM(!aj| zo@bmfMx?25ont6*7rVA*!>;5F*6HOiz|qpb6&e&2w;>uFvAO!7a_48^8M>*MJKTy^ zGMr^!6AW$`N0=ywm>360kt7D9zfOVGPa3W1Y3;kJ#*&3l&tM;cI$cV+CtM@sIXqzh z{Mz8ukTOx-Kh>e~%8uewS__NwU(Yq0oIDF@&o7><=&oy87^P?A)hka+s~-)S-}^V8 z8x>w~_w1lxgM%xkSj*96OJ3t6c0!%G=ZbUWjbtBHlqX+4<%672CD204+2{^gy9 zKmITNiK>?!MAS376zl(7zlcBP7bojlCG|Z68((>w#N9k{kB4Tq;R>zTneBt`#vD%i zC?P%%L1z)u8DSde%Yk7EUS_Xk9~z}7iDZ?LFi9mO=9*|#Tu41r?Ci>e)@M&ZeGy}C zSj)P9eTo+UPuNd1-5bA;rX_N4Cq41FNW>BXu^hOUi2=Z+y^517m!`IDjoyG0?d+Rh zbnXw5U5gZ`!fsYV!)1rSA#oM?+CVx~b=ill&aPAj_ZN5##`r}%z*mo;Zb}t*aaH%r z*W)%AgnyltlV6G`K~o(se|wPp?W3u9UUeFMgk=7KzX;e#G#+Fx!X>m9w#IquN8CrN zuit#KUq39-;Izq?=Ie)*ZvpBWWu?Af`VQ*RQAiasy92~~b3=)ClTwUoZ+F0CNkvnq8L1o;cPt5%;`(A0htFyi(yf*a?^M$(-Ev69t=>M-)z>&VJ z$3?A_Z4am3=jHcXtmauxZU?MnB6$pEt`8&M&qknX4HDmZI(AaZO82RUxOKpG;o_m^ zs@}#{UOl&D+dI-~X4l$W<-Ps2T!SDpPNm`1qZYmm|H2~PvY^HEQZKCCpLd)ymJDq{ z{uuZ)ms(M3rP{@tyQQUr$^XrC`ht*~(tm_7O%;f?rUZluex=G>z-y4G3?q4(GAQ_> zHb>Z;Q|axRdY!23OGsw`M>`+bvZZK6tW(ZPon%<%um36~>x+Gm>JU!aO=S>c)$vl6 zd#U7~wvOa0PPc=mRHu^-%ecYsf>h%Q^G_?qDmXE%iCNU|PS>i2we-aXG819vt zn+r`F$(8*;A=D?q;~OO|fGS-c#FOjq>|r#*e1ZN9@bJ#GpGRYyqA?HzH}ic;I=k0s ztwJ!f%MaGEhr$_d#+P=$ZXU>w=9d%Xc<~Bk9@BvKikRrnL+>RD z(_U}{r+>5RUt};=Yio@Wu~ZvI*9g>ty*!-GD=jKs?f=sd#e{t~=$pnEdYH+jN{@Cw@`>vxuF&ngrBWB)?K=azfuIgyFOBga7sc8+tioFAV2`9n4qC8h6Y4jyC?G)iaE zIL*gjtLwP= z5g#dr{4La!!zKT7^?~H**?W0gaK-)_@vZC*$KOc(zbhm(|7SwV|G&)!#Vj$xbj&9i zDvCdb{1?5Y`%eg6q{@zhF}M#94Ey~D7jP7v=ss;OSs>43j#`e1WEMcL{y{aYPf3uv z68#}pP~NKGq$Qv5>t^Fc{8N?qY8vU}O8+lQeFTo1|2>aCB>u-8|G(=$|2KLA29FZp z)D7mV=&JmD{$I2gWGcL1if)#CPjdL1eqlW<9}1UEQ6GG+O@ho=|DY^>3qWDK|MsZg zRK8pNdq#qPdg_Zl!VP2&|9fnHFy#C%1?|7n>;6YKV}iDd$kRQ%m&Wn16G441W8pOjGAzWgwQWWDp-OFMj7 z5wc9ER-Bfr@klI&O$;yz$kGV zzv;z6=ahr|-~<-@QU zT6Pebw}gGt;|Wz{!&Gg*SB^N1Q=R_d#f`b@Z~$ic_5kJcPhF|Ux=7uB*{!;vv8L7x z+0SLlr{HnUNx=B_2F(^%95z}#hL7zD9-Z>-gw2CP;xs+21?o3nG8-#lpT z8gXo=Wh))FLRue+^~7Y1(atQDywkuL_T@3f+bE*d!HQOVd{s`)%1#^AlJlz`ZKM-8 zW)08=85ohh`NS}hdvHr4Ft$x&u}NzQp|RL1vH%T{wWX7_8MLK7339cQjUiH(=^z|S zd7%kRSP}AwcrcZ?Wqen9R`&$%{r2-bxKO5g5{Dj5z@oZ)Y8b_VCo_=;M^$!68JT-O zqscQL9@l(nRlBytx;HQ0hAIHYF@38(obPSC;QH@}oYs!(_BJo~n=k<*HO_pIOk@(h_ka5y<{j8V(Zc#(OD z{H4DjD>Sp!?I4LPGRD@A;T1nGU?cUFKLaa^u{V44VY(Bi*OHtF2mlslX076FHoM%? zkxOxuav`NsJnXBfe~XQAY+~}mU5Zrv9NI0QQ|4|x6DkY96~1NdR7PZMdj>JH*8 zJPhP*ps?J-eZf%fj$c7af)K()WU> z2^8zy>&@v{PSjZtU)|n6B3v(+@FRS00N?46)*i_#cNm3|5TSf7)(;e9J*-e;qvv=l z#g8M#A6BI1HTTHk^UaICyPq}H!R*Q5IMaly6a}=jAyww!@^{sXBj(j~pd?qO8i&620;;JS zNJmJ9CA7QEXoWx#Caj#ZhvHff=XosL2D|1bCuYDu7g9=ZVVR0JoOSEz0lDb`$S~Hr z?T|!($B9d6jFp){@^d1lF$BXdaWQ|mT(2ahNj0MOEJei;8ByyRMwuCy7$#kga5p|$ znqG{aVMhVJhvsEOmnBELPnTV$Egf>@{hgPtz|x@A?XoMX+ht~>&KW~n zXyf4H0*4?2)oiO%wnuhMT9C}?vk123HkYf#sQ9FH*(cG>5Hp7bD#6zrvrSIfTG=tJ z!Oc1r_M-YG^CLmPjJ`MKX4^F_8(RnOExGu-f(uZe(-ihxyGIhpLM21Ig{#0W7Z$8q@=kFY?uX1)G1v5j5hQ>0zGq(C;k2`;} z@k6(0tQpgzj`Fqu18KG`eCxLHah^iH3T|An!F>8Ry$0bL0MNq>LX}}D(SV-kO-16OC5Hr`_3#qQXbQM~dgMIk)MR#M(NVa508A zta4+61@ad=*J(y<3vqF=zk;$q`|-cao60@CU0#|4jfA~V}6_%zANm25RqfIkvtiX7PDKu4taO ztU1`~q*{qEtB7ZKa?au+DEKrodNNZn9*t*jPJcX2p&3{WuLB1YJ-j=(@b>{`tGM9x zP&Buk7Ol7|=n#zG%OXA}Y4D90FWs_@7@qvChgp*zb|P zNO_Q3oIlmjdQ)Sp>i%Y22Yrep-vqFS+e5HMVR{{acAvBlnx=w2?fIS= zv~DvVSdHG(O^kh4&I5E7D6+-E{#NQkU*FR$29tOQ>(=`pR^r~W&B2FQWS^!u))CyE zT}+OI%Vko`xxj*60u?#!T^;Z0y)Wz864`$#PquAtgo(GJlUODC!vScc9ajS;*ZAQ< zBWLO}S(S)jk#~U)zDk?W<%9<`#5WR64ayC2n#Auq3kHUasUK0AB^1HCMo*VW;E{&h z6$|H~2SQ#@5%mOrAsshLzn;3(H8TA3SqimZ-jXtp-JvjR;^Y1?wwnel2tWq%P3@+3 zd@*pQBDQfa$lbMF_U^k=Rw6aP_lpQgxjr*V*-l@paLqc`edA5K@6?M@G=Gu(-G#J{ zj<&73u$c2nY7&}CMVKp{tK~kAD_>TT-LrZ>KRYyOZb z`v2ep%8Rbgc-9Y(e2<_?#o9Ub>53ZItp1iiNtDpTrB<|Juy;J&A${KTeBma#K^3V2 zw01Kd0swDQⓈ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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Ship automations + from + your terminal + + pull · diff · lint · push · MCP — one CLI for humans and agents + + + wk + + + + + From aaf7b67e002b03462da15442c96f38e088455ed2 Mon Sep 17 00:00:00 2001 From: Bill Prin Date: Tue, 30 Jun 2026 22:41:50 -0700 Subject: [PATCH 2/2] Send wk-cli/ User-Agent for telemetry attribution * Send wk/ User-Agent so telemetry can attribute releases The backend telemetry pipeline attributes CLI requests by their User-Agent header (the old workato-platform-cli sends "workato-platform-cli/"). Here the header was a hardcoded const userAgent = "wk/dev", so every release reported "wk/dev" and its traffic was indistinguishable across versions. The MCP client sent no User-Agent at all. Build-time version info is already injected via goreleaser ldflags into main.version/commit/date, but only flowed to the `version` command, not the HTTP clients. This wires it through: - Add internal/version: single source of truth for build version, exposing UserAgent() -> "wk/" (keeps the existing "wk" product token; mirrors the old CLI's product/version convention). - main.go records the ldflags values via version.Set (var names kept as main.version/commit/date so existing -X flags keep working). - Remove the duplicated version state from internal/commands; the version command now reads from the shared package. - Replace the hardcoded `const userAgent = "wk/dev"` and its three call sites (api do/doRaw and package upload) with version.UserAgent(). - Add the User-Agent header to the MCP client (it had none) and wire the real version into its clientInfo. Verified: go build/vet/test all pass; a release build (-X main.version=1.0.6-beta) reports the injected version, and a wire test confirms the header reaches the network. Co-Authored-By: Claude Opus 4.8 (1M context) * Use distinctive workato-cli/ User-Agent token; add tests Two changes from review feedback: - Change the User-Agent product token from "wk" to "workato-cli". The nginx access-log field telemetry lands in is analyzed/tokenized, so the short "wk" token collides with stray "wk" tokens in unrelated user-agents (e.g. Customer.io), forcing fragile exclusion filters in the dashboards. "workato-cli" matches cleanly as a phrase and mirrors the old Python CLI's distinctive "workato-platform-cli" convention. The command stays `wk`; only the telemetry token changes. - Normalize a leading "v" in Set() via strings.TrimPrefix. Git tags are "v1.0.6-beta"; goreleaser strips the "v" but the Makefile's `git describe` does not, so without this the User-Agent differed by build path. Now it's consistently "workato-cli/1.0.6-beta". - Add internal/version/version_test.go covering Set/accessors, the User-Agent format, the v-prefix stripping, and the dev fallback. Co-Authored-By: Claude Opus 4.8 (1M context) * Clarify in comments that ldflags are declared in the Makefile + goreleaser Spell out, where the version vars are defined, that the values come from the linker's -X flags declared in both the Makefile (via `git describe`) and .goreleaser.yaml, and that plain `go run`/`go build` leaves the defaults. Co-Authored-By: Claude Opus 4.8 (1M context) * Use wk-cli/ User-Agent token Switch the telemetry token from workato-cli to wk-cli. wk-cli filters cleanly as a phrase (avoiding the bare "wk" collision) and matches the token the original beta builds already sent, so it reconnects with existing telemetry history instead of starting a new naming era. Co-Authored-By: Claude Opus 4.8 (1M context) --------- Co-authored-by: Claude Opus 4.8 (1M context) --- cmd/wk/main.go | 13 ++++++-- internal/api/http_client.go | 9 +++--- internal/api/packages.go | 4 ++- internal/commands/root.go | 14 -------- internal/commands/version.go | 10 +++--- internal/mcp/client.go | 4 ++- internal/version/version.go | 55 ++++++++++++++++++++++++++++++++ internal/version/version_test.go | 47 +++++++++++++++++++++++++++ 8 files changed, 129 insertions(+), 27 deletions(-) create mode 100644 internal/version/version.go create mode 100644 internal/version/version_test.go diff --git a/cmd/wk/main.go b/cmd/wk/main.go index dad63c9..734675d 100644 --- a/cmd/wk/main.go +++ b/cmd/wk/main.go @@ -6,9 +6,16 @@ import ( "os/signal" "github.com/workato-devs/wk/internal/commands" + wkversion "github.com/workato-devs/wk/internal/version" ) -// Set by goreleaser ldflags. +// These default to "dev"/"none"/"unknown" and are overwritten at build time +// by the Go linker's -X flags. Two build paths set them: +// - Makefile: -X main.version=$(VERSION) ... (VERSION from `git describe`) +// - .goreleaser.yaml: -X main.version={{.Version}} ... (release builds in CI) +// The variable names must stay version/commit/date so those -X flags keep +// matching (the linker matches by exact symbol name, e.g. main.version). +// A plain `go run`/`go build` with no -X flags leaves the defaults in place. var ( version = "dev" commit = "none" @@ -19,6 +26,8 @@ func main() { ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt) defer cancel() - commands.SetVersionInfo(version, commit, date) + // Record build-time version info so every package (CLI version command, + // API client User-Agent, MCP client) reads from a single source. + wkversion.Set(version, commit, date) os.Exit(commands.Execute(ctx)) } diff --git a/internal/api/http_client.go b/internal/api/http_client.go index 2beae8b..ac75980 100644 --- a/internal/api/http_client.go +++ b/internal/api/http_client.go @@ -9,10 +9,9 @@ import ( "net/http" "os" "time" -) -// userAgent is sent on every outbound Workato API request. -const userAgent = "wk/dev" + "github.com/workato-devs/wk/internal/version" +) // HTTPClient implements the Client interface using HTTP. type HTTPClient struct { @@ -175,7 +174,7 @@ func (c *HTTPClient) do(ctx context.Context, method, path string, body, result a } req.Header.Set("Authorization", "Bearer "+c.token) - req.Header.Set("User-Agent", userAgent) + req.Header.Set("User-Agent", version.UserAgent()) if body != nil { req.Header.Set("Content-Type", "application/json") } @@ -237,7 +236,7 @@ func (c *HTTPClient) doRaw(ctx context.Context, method, path string) ([]byte, er } req.Header.Set("Authorization", "Bearer "+c.token) - req.Header.Set("User-Agent", userAgent) + req.Header.Set("User-Agent", version.UserAgent()) if c.verbose { fmt.Fprintf(os.Stderr, "[debug] %s %s%s\n", method, c.baseURL, path) diff --git a/internal/api/packages.go b/internal/api/packages.go index e222279..c7c24a5 100644 --- a/internal/api/packages.go +++ b/internal/api/packages.go @@ -9,6 +9,8 @@ import ( "net/http" "os" "time" + + "github.com/workato-devs/wk/internal/version" ) type packageService struct { @@ -63,7 +65,7 @@ func (s *packageService) Import(ctx context.Context, folderID int, data []byte, } req.Header.Set("Authorization", "Bearer "+s.client.token) - req.Header.Set("User-Agent", userAgent) + req.Header.Set("User-Agent", version.UserAgent()) req.Header.Set("Content-Type", "application/octet-stream") if s.client.verbose { diff --git a/internal/commands/root.go b/internal/commands/root.go index a651612..0a0f174 100644 --- a/internal/commands/root.go +++ b/internal/commands/root.go @@ -29,20 +29,6 @@ func (e ExitCodeError) Error() string { return fmt.Sprintf("exit code %d", e.Code) } -// Version info set by main via SetVersionInfo. -var ( - versionStr = "dev" - commitStr = "none" - dateStr = "unknown" -) - -// SetVersionInfo is called from main.go to inject ldflags values. -func SetVersionInfo(version, commit, date string) { - versionStr = version - commitStr = commit - dateStr = date -} - // RunContext carries resolved dependencies into every command handler. // No global state — everything a command needs is here. type RunContext struct { diff --git a/internal/commands/version.go b/internal/commands/version.go index 11b602d..a74febc 100644 --- a/internal/commands/version.go +++ b/internal/commands/version.go @@ -4,6 +4,8 @@ import ( "fmt" "github.com/spf13/cobra" + + "github.com/workato-devs/wk/internal/version" ) func newVersionCmd() *cobra.Command { @@ -20,16 +22,16 @@ func newVersionCmd() *cobra.Command { } info := map[string]string{ - "version": versionStr, - "commit": commitStr, - "date": dateStr, + "version": version.Version(), + "commit": version.Commit(), + "date": version.Date(), } if flagJSON { return rctx.Formatter.Format(cmd.OutOrStdout(), info) } - fmt.Fprintf(cmd.OutOrStdout(), "wk %s\n", versionStr) + fmt.Fprintf(cmd.OutOrStdout(), "wk %s\n", version.Version()) return nil }, } diff --git a/internal/mcp/client.go b/internal/mcp/client.go index 1ed0e1e..24eb4c6 100644 --- a/internal/mcp/client.go +++ b/internal/mcp/client.go @@ -11,6 +11,7 @@ import ( "time" "github.com/workato-devs/wk/internal/api" + "github.com/workato-devs/wk/internal/version" ) // Client is an MCP protocol client using Streamable HTTP transport. @@ -57,7 +58,7 @@ func (c *Client) Initialize(ctx context.Context) (*api.MCPServerInfo, error) { "capabilities": map[string]any{}, "clientInfo": map[string]any{ "name": "wk", - "version": "dev", + "version": version.Version(), }, }, ID: 1, @@ -125,6 +126,7 @@ func (c *Client) send(ctx context.Context, rpcReq jsonRPCRequest) (*jsonRPCRespo req.Header.Set("Content-Type", "application/json") req.Header.Set("Accept", "text/event-stream, application/json") + req.Header.Set("User-Agent", version.UserAgent()) if c.sessionID != "" { req.Header.Set("Mcp-Session-Id", c.sessionID) } diff --git a/internal/version/version.go b/internal/version/version.go new file mode 100644 index 0000000..1acc19f --- /dev/null +++ b/internal/version/version.go @@ -0,0 +1,55 @@ +// Package version holds build-time version metadata injected via goreleaser +// ldflags (see .goreleaser.yaml and the Makefile) and derives values from it, +// such as the HTTP User-Agent sent on every API request for backend telemetry. +package version + +import ( + "fmt" + "strings" +) + +// These are populated once at startup by Set. The real values originate from +// the Go linker's -X flags, which are declared in the Makefile and +// .goreleaser.yaml, applied to main.version/commit/date, then handed here via +// Set. They default to dev values so `go run`/`go test` builds (no -X flags) +// still produce a sensible User-Agent. +var ( + version = "dev" + commit = "none" + date = "unknown" +) + +// Set records the build-time version info. Called once from main, before any +// HTTP client is constructed. +func Set(v, c, d string) { + // Normalize a leading "v". Git tags are "v1.0.6-beta"; `git describe` in + // the Makefile keeps the "v", while goreleaser's {{.Version}} strips it. + // Trimming here keeps the version — and the telemetry User-Agent — + // consistent regardless of which build path produced the binary. + version = strings.TrimPrefix(v, "v") + commit = c + date = d +} + +// Version returns the build version string (e.g. "1.2.3" or "dev"). +func Version() string { return version } + +// Commit returns the build commit hash. +func Commit() string { return commit } + +// Date returns the build date. +func Date() string { return date } + +// UserAgent returns the HTTP User-Agent header value, e.g. "wk-cli/1.2.3". +// The backend telemetry pipeline attributes requests to the CLI and its +// version via this header, mirroring the old workato-platform-cli's +// "workato-platform-cli/" convention. +// +// The token is "wk-cli", not the bare command name "wk": the nginx access-log +// field this lands in is analyzed/tokenized, so a 2-char token like "wk" +// shows up as a stray token in unrelated user-agents and collides. "wk-cli" +// filters cleanly as a phrase ("wk" then "cli" adjacent), and it matches the +// token the original beta builds already sent, keeping telemetry continuous. +func UserAgent() string { + return fmt.Sprintf("wk-cli/%s", version) +} diff --git a/internal/version/version_test.go b/internal/version/version_test.go new file mode 100644 index 0000000..a0e1978 --- /dev/null +++ b/internal/version/version_test.go @@ -0,0 +1,47 @@ +package version + +import "testing" + +func TestSetPopulatesAccessors(t *testing.T) { + Set("1.2.3", "abc1234", "2026-06-30") + + if got, want := Version(), "1.2.3"; got != want { + t.Errorf("Version() = %q, want %q", got, want) + } + if got, want := Commit(), "abc1234"; got != want { + t.Errorf("Commit() = %q, want %q", got, want) + } + if got, want := Date(), "2026-06-30"; got != want { + t.Errorf("Date() = %q, want %q", got, want) + } +} + +func TestUserAgentFormat(t *testing.T) { + Set("1.2.3", "c", "d") + + if got, want := UserAgent(), "wk-cli/1.2.3"; got != want { + t.Errorf("UserAgent() = %q, want %q", got, want) + } +} + +// A leading "v" from a git tag (e.g. via `git describe` in the Makefile) must +// be normalized so the telemetry token is consistent across build paths. +func TestSetStripsLeadingV(t *testing.T) { + Set("v1.0.6-beta", "c", "d") + + if got, want := Version(), "1.0.6-beta"; got != want { + t.Errorf("Version() = %q, want %q (leading v should be stripped)", got, want) + } + if got, want := UserAgent(), "wk-cli/1.0.6-beta"; got != want { + t.Errorf("UserAgent() = %q, want %q", got, want) + } +} + +// The dev fallback must not be mangled by the "v" trimming. +func TestSetDevFallbackUnchanged(t *testing.T) { + Set("dev", "none", "unknown") + + if got, want := UserAgent(), "wk-cli/dev"; got != want { + t.Errorf("UserAgent() = %q, want %q", got, want) + } +}