From fc5b861bcd90cb22c42c44a9b6d7e7f9cb4d6d2f Mon Sep 17 00:00:00 2001 From: Alexander Nitsche Date: Tue, 12 Apr 2022 19:00:11 +0200 Subject: [PATCH] [TASK] Update docs (#404) See https://github.com/TYPO3-Documentation/TYPO3CMS-Guide-HowToDocument/commit/c2bb63beadb7cc1ea6eb3496613c3376f970d4c9 for further details. The README.md should mostly only cover the abstract and links. The composer commands are the core value of this extension. List all commands in the documentation and copy the descriptions from the `composer.json`. This lets the global search at docs.typo3.org find these commands. Remove superfluous Linters page, which is integrated now in the Running page. Use sentence case in page titles in order to conform to the TYPO3 documentation standards. The ambiguous :ts: text role has been removed to not confuse the writer with typescript and typoscript. Add the common extension destinations to `composer.json`. (Packagist displays them in a prominent place.) --- .editorconfig | 2 +- Documentation/ContinuousIntegration.rst | 46 +++ Documentation/DependencyManager.rst | 21 ++ Documentation/Documentation.rst | 22 ++ .../Documentation/Rendering/Index.rst | 26 -- Documentation/Environment.rst | 11 + Documentation/Images/SlidesCover.jpg | Bin 0 -> 56929 bytes Documentation/Images/VideoCover.jpg | Bin 0 -> 20618 bytes Documentation/Includes.rst.txt | 34 +++ Documentation/Includes.txt | 17 -- Documentation/Index.rst | 75 +++-- Documentation/Introduction.rst | 53 ++++ Documentation/Introduction/Index.rst | 16 - Documentation/Linters/GitHub/Index.rst | 22 -- Documentation/Linters/GitLab/Index.rst | 13 - Documentation/Linters/Index.rst | 18 -- Documentation/Running.rst | 281 ++++++++++++++++++ Documentation/Security.rst | 16 + Documentation/Settings.cfg | 106 ++++--- Documentation/Sitemap.rst | 4 +- Documentation/TestingFramework.rst | 57 ++++ Documentation/genindex.rst | 7 + README.md | 228 +------------- composer.json | 4 +- 24 files changed, 655 insertions(+), 424 deletions(-) create mode 100644 Documentation/ContinuousIntegration.rst create mode 100644 Documentation/DependencyManager.rst create mode 100644 Documentation/Documentation.rst delete mode 100644 Documentation/Documentation/Rendering/Index.rst create mode 100644 Documentation/Environment.rst create mode 100644 Documentation/Images/SlidesCover.jpg create mode 100644 Documentation/Images/VideoCover.jpg create mode 100644 Documentation/Includes.rst.txt delete mode 100644 Documentation/Includes.txt create mode 100644 Documentation/Introduction.rst delete mode 100644 Documentation/Introduction/Index.rst delete mode 100644 Documentation/Linters/GitHub/Index.rst delete mode 100644 Documentation/Linters/GitLab/Index.rst delete mode 100644 Documentation/Linters/Index.rst create mode 100644 Documentation/Running.rst create mode 100644 Documentation/Security.rst create mode 100644 Documentation/TestingFramework.rst create mode 100644 Documentation/genindex.rst diff --git a/.editorconfig b/.editorconfig index 0c5bdfe..9d5e9dc 100644 --- a/.editorconfig +++ b/.editorconfig @@ -23,7 +23,7 @@ indent_style = tab indent_size = 2 # ReST files -[*.rst] +[{*.rst,*.rst.txt}] indent_size = 3 max_line_length = 80 diff --git a/Documentation/ContinuousIntegration.rst b/Documentation/ContinuousIntegration.rst new file mode 100644 index 0000000..1bc5e73 --- /dev/null +++ b/Documentation/ContinuousIntegration.rst @@ -0,0 +1,46 @@ +.. include:: /Includes.rst.txt + +.. _continuous-integration: + +====================== +Continuous integration +====================== + +As an example, this extension provides several ways to perform the code quality +checks and tests in a CI pipeline. You can copy the +appropriate configuration depending on which Git hosting service and CI +platform you want to use. + +.. contents:: Table of Contents: + :backlinks: top + :class: compact-list + :depth: 2 + :local: + +.. _github-actions: + +GitHub Actions +============== + +This extension has two code-checking workflows for +`GitHub Actions `__: + +- `one that uses the local tools `__: + This is the workflow you most probably would want to use: + This workflow uses the development tools installed via Composer and PHIVE and + calls them using the provided Composer scripts. Use this workflow if you want + to run the code quality checks locally as well as in GitHub Actions. + +- `one that completely relies on predefined actions `__: + This workflow does not need the development tools to be installed locally. + Use this workflow if you only want to run the code quality checks in GitHub + Actions, but not locally. + +.. _gitlab-ci: + +GitLab CI +========= + +This extension also provides +`configuration `__ +for `GitLab CI `__. diff --git a/Documentation/DependencyManager.rst b/Documentation/DependencyManager.rst new file mode 100644 index 0000000..e7bcdb8 --- /dev/null +++ b/Documentation/DependencyManager.rst @@ -0,0 +1,21 @@ +.. include:: /Includes.rst.txt + +.. _dependency-manager: + +================== +Dependency manager +================== + +To keep things simple, most development tools, for example PHP_CodeSniffer, are +installed by Composer as development requirements and in some cases where +installation via Composer is not possible, we use `PHIVE `__. + +PHIVE packages each tool with all its dependencies as +a separate PHAR. This helps avoid dependency hell (which means that you cannot +install or upgrade some tool as the tool's dependencies conflict with the +dependencies on another library). It also allows running versions of tools +that require a PHP version that is higher than the lowest allowed PHP version +for this project. Currently, we use PHIVE for +`PHP Copy/Paste Detector `__, +that requires PHP >= 7.3, which conflicts with this project's PHP version +support (we also support PHP 7.2). diff --git a/Documentation/Documentation.rst b/Documentation/Documentation.rst new file mode 100644 index 0000000..793e82f --- /dev/null +++ b/Documentation/Documentation.rst @@ -0,0 +1,22 @@ +.. include:: /Includes.rst.txt + +.. _documentation: + +======================= +Documentation rendering +======================= + +In order to render the documentation, this extension provides a Composer script +that you can run locally via + +.. index:: Commands; composer docs:generate +.. code-block:: bash + + composer docs:generate + +You do not need to start or build the containers for this as this happens +automatically. + +.. seealso:: + + For further details read the :doc:`TYPO3 Documentation Rendering Guide `. diff --git a/Documentation/Documentation/Rendering/Index.rst b/Documentation/Documentation/Rendering/Index.rst deleted file mode 100644 index 32db46b..0000000 --- a/Documentation/Documentation/Rendering/Index.rst +++ /dev/null @@ -1,26 +0,0 @@ -.. include:: ../../Includes.txt - -.. _documentation: - -======================= -Documentation rendering -======================= - -.. _how-to-render-documentation-locally: - -How to render documentation locally? -==================================== - -In order to render documentation, first of all, clone the repository: - -.. code-block:: bash - - git clone https://github.com/TYPO3-Documentation/tea.git - -then go to the extension root: - -.. code-block:: bash - - cd tea - -and follow `the TYPO3 documentation quickstart guide `_ diff --git a/Documentation/Environment.rst b/Documentation/Environment.rst new file mode 100644 index 0000000..a948522 --- /dev/null +++ b/Documentation/Environment.rst @@ -0,0 +1,11 @@ +.. include:: /Includes.rst.txt + +.. _development-environment: + +======================= +Development environment +======================= + +You can either run the code quality checks and automated tests locally (using a +local PHP, Composer, and database), or you can use +`ddev `__ for a Docker-based setup. diff --git a/Documentation/Images/SlidesCover.jpg b/Documentation/Images/SlidesCover.jpg new file mode 100644 index 0000000000000000000000000000000000000000..20e51e2b73abbe20fba53e8173e1afa5fb4f744f GIT binary patch literal 56929 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 YqMwvVU+j_+W&4k99&Ug9TmJz6+1I6&qW}N^ literal 0 HcmV?d00001 diff --git a/Documentation/Images/VideoCover.jpg b/Documentation/Images/VideoCover.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1b029a4c9e2bf807c1e3ca09139350ce2bf96c0f GIT binary patch literal 20618 zcmdSA1y>wR*ETx1OK=YacSvvz?l!nvkYRAw5ZpCbaCdii32uV~cXthbxF31n^_}&d zA8=}>*GyMky{}!htGcRp?S5N)+W=t7O3FwApr8N%sP_-xZ5a>|^83g!dUTR(sV0Dy*u`A60NNzhO*uGn_Izi3t9@kET{uyJrz9sJ^JK79r{=JZTce(~SD;1o4+s_ng`qUPYr6?jva&2F9d1~=NXEy()$%taV<6JUOHGlX&A-VWg zWP@#TBi8G}yo<9KrV0hSTy|OMC!l||ON@m6W1|BH%b%6$f2j8N`H3?3y#9+W*Kw;1 zy-{B%v%nHP?OPoGFC^~7tiHW){Q6z5f7LDSpsh+{f;?yip(c9vD(%ZLc1M(w6K>Hi zm&H7-7g1*Q;aV%@bh4pwIxkA|J-g0#RdXK`w;K90MpEx3*dD^N zCm3;;mGCD^E8|4^%;3Km)p^o)YsW~gykq)V4g@3S|AUeBO12TEuM?`_U;J6l=lia* z%jBX3vgldfVvCiB!mrz~wf>?OE67zD>$_%Qe0@ca2QgABKEd`0EaxkARvzlf|Av_S zACS0%roqVBkYN7oBZGW%w1j8k@Bu`C0A-e zquCc{>1*USfN?r5O8Y&dPNurqi-}haWsAu+p zxRr+gLyT13nNS~(D8B2N&cB(?O_Y5ilK#__GV`Ru3*uS-YMgwQ!<9DB!@t`vuf_8} zmi=%0{bQUF_kQT3iJP(!L2e(D5~WNb+cH1s3rKn*OHED{D%qjFKc>!-aq-$ zH2nq0Q3m~YRwzMQ5exQI?OX0(k(FeT)!7B>K`Puw9$r0!wGA;lOqv$Z(;p(de&YW60U9f=`2f=o)Kp%f}MzB z4nA}MGm572!^)HV%52FW!%Y|`umYO0PlV>!Ltr!o)XndfShn{pA2}fL^0AtC|Aj z&!T2H!2IHId8`IDph`4klN>lxK(KhElLN)3p2W!}or2R76$u%}4l*fsErioRHc~EQ zLbi&<>5-)yL`seOA{$@sf()gqHVjn5$}KMS^JmD;&XF;}p+`pc7ZH&F#%HHvZp9Wl zC;`}T|M`y7!dl6_-fAePiLG!}VBwAx3G$bAfek^ z15Lzq@E2sIj#f8%#-%jXQ5kCzn*m2Q)%|O9s!G$PS~ zcwQda4)^e5YR?Zmjc(r9;3mTHfM|jr@LESVwDrat+ze)UQ<*MVpP$D0UVMzTAU_kn zwUCLLC*qK-{CyOSU4M?0%28Xgwy!X*;EHUD3NQRPf762s)Fx}4<*^n+^SFHjob509 z`Q!Y~(V9cIva~6MAKlG?_>~!q(4<(Fw8e7Zu2crIgri$_J#X@?}DUs<) z@wc?qU~_mxBb~|NI5g;_kjSe?Y%pUGDav60DEU@&q1(~&Hjd}+J09HZVAM@e)PWKV2uXUk_ zf+#n{H*<+t<@N};#UWhd|1btZ?k;H$k7&QB7Fm-s0Dpv zpR4$68o$GXGgSNrP8>u;z_iV0>;VGWHMU9jt^z zJv?b-(fmY2eP~TwYHC&LI5-goU?SW&W9Ua@3SlaIPebw3;GPSa2gSaUY|lBHddBs7 z>`egFVWAH!G!24PV2y`(W&r%Vm2#@GMU=AcrOOl6n3BTT-&u^uO(pK)o zTs7SN)ES37t#UC4qi6-#nz+17BFgy%3@EwCfz;F}R8ALo;^olW!2pwel2oq5_(L`s z&Nd7Le3AhDP=GhBRkqgkPfmO-mOi3R?3lo-FK*dP55rjmtWkpRL$%smKg{(4ta0;k zut6+hqq+K|g!%YmoR(1$SQU0>Y&)jc(*7ctEXmlw`6PUHle?s^ToqDd%yCq_SK5)+ zYbPf$JC~fJlCS@ThG0=-kLQ*M*Bc*G(&(JTPxcQ(h>rqi)XdMM>rKsDEgS23V~isdMFZR|{AdeKz-NssPS`5st4H zOJ&UF%tkEcsvhC=kIcfBi=Dn(f)jGdw2j@qLbzy++X@cvNg1{M7!p zR&2O1+Wfe26%I@ib#q2zwn7adge|tz=3j)Ij@6a8VI~ble^029QAb;Z5PxaUCiyvp zoUK9Qq6u}Bg5&r3$7drTbpEFmHTx7QBtH#?L3w25dqoxNYqF`<%!bzxWJG;B)PdgdauL$VM5o<)N*ueM+;q|t2OA#&d zp``jym5%9D+j@0S6kRZojy#wON5gj|2r`4VKPKNR-3DX?x>wlW4%jvbWCa@0dxiGHg zaGw3rUZrn5wH!Vy+ja#`Cj1`pxZ?5D84oPH12H#E`oCxoSVyDnt&8q`hEZ&u+*Ng= z2qC(jw&8MvW5(Iu%X|ZbA!BQ;865--6~oO;btp86J3kugu-H8-U1>=nH%YS`*~f>U z8K#YLA}OMOOG~G1f4_u?;)df#hqet~qJ@2EUr z<#~aTvnbey8OF%Kd){BBwR1~LvDv|-sn~#Ws?nJVm!nNKODEyuMb*?e%F@MSUHpAr zrj8zA{WdiJk~dy1a^#Alaum-RRJ)vL$envUL=^iJ)~p9?c6SPHSG zt;EKcQGr{%l)Qr%1j>e-T90UEqf$Ym{-~CUE!fGJ1_*eaev4|x6EiIrC`MCY&9LZ^ zRM9AD6)u#a*s~DT?8N<3&Iqf8n_WK4Ag)HDUa;3H3rfIH^N}8Cu4HLgGQWWO=I5xA z8}87fxlsI{c5%z{zvOGdu6?e|`-PMTReWW+7is1O!M`g=is54lo0WJoO~r1)r%zA> z1|yIOhR@1=|7BZ_nA9NIVMYT>Cw4qF6*egpVSH<5by_{+a(>#?SQr_9QNQU}uflem zdLalrU=Cv&oe0y4D$87sEg3$So(Ni{043#X5X7O66Zt?>lf^ z(%xtoVBLKu+jI6otIihpL%O8kyd)hoaEhqOm#R0``35}_20sbPc}dEHX61is@i%TE_at)BBiwlm5~RbPP$ko?-Ri9uSr+Z#q5ZKMMgy%4L)Rv+mv682P#8R zg6A8n?2kaYubE0I_Lj3!lJ>Fa3Lha?5b z2sp^k=pj;l5JiF|=^?R^05`XaY19t;XNAmB=TZ(H10=6tgu!ph|oW@ z@zm&S4;sMu+~&O3n8<7YBqKadTIzHij;yj;-!8myC|v!!4yIpI|8LIF^8|xAho{aL znIM;ja}yDlulxg+lDiW+yAAd>B$si&F7(k~I1Ru*s#If?4cZjuZK`Z3ZGcPZ#)8Z7 zBdaHd!RXX;LAsu{ZpzThoHK}JIBb}CV5e#F1_y81i3 zTODdgIwMz}1*HwGC6WS^G|6@0&*-}unmUo@f9n<0J{9Xdr;!I@CA7#;#b+lpD3>ZC zQH$bW1^r0K&rZOhimk8*L7$5K*j1aqyR7?Vx+byn+rgSd*l=2-f~NiP4N!S{h@`B; zv|rt}V9P92^EaEUI#=)hY1tqbxfYuNsZuBDc*RU2D7o}&zsZHr;%bx0=?c77#kZE| zuk3}H7i5y3P`UL`5tLcL>8_jAEF{14l_L>foU3x(sX|c$GuW~t5f{bX8%RbWH+%^e zo-18#cneMR7MDDvl*QZD@u%@hJ$2Tin4N|0M*p~f!>eGVIa+lLa+%C81D;Y04)IfJ zI?iWu`wX@+5KkfT;d^VS35SaLjYetS@x$lk9*28kaMK3AtqEHx1EjRaDwXUm3UL3* z_F-ztkbILBk0`@jyUg0tv4)&T7feKbxHOR76?gDh_<=yt%=)p|d44H*x+$Xgp=0{R z(Elzocrs7D)UNanpM~{?AG`iA?vq#$T^|vZ)Czb7l}AiBLu|xJhn)wNv!bKG$pC@L z+GLE!Xv%EEj&~@OD||ZpjIp3{-p|3w$!;GX!+XsnzE|bse0|8*9NoM`Hj1cIHU{z1 z&dct>`wFFhw)x(S7JZS$Xg^e({Vut&J{o_Y9-4&BLuH#Ac}p85$&&M`xuK>)Q;o@L z@)^x*srOksLa|_%1vK<5*JEcvk386-hRqtVk1&T~)#ej$F5|nA^U|#+z_MxdG-LRe z&d?se?Lhb(>@zub)j?+{nzd$u6H;ObwOH<&4&A89*3Nsd(}e$Z%xR$vD~Z2U@dT%v zqXYuQ5WB-(&_%P^Bh~rI7xlb7uwoPZ^sl*Pn1_Mv9N)XG^NQ#@UPx>AL%@Bs!J6>n z_S3ufK`LYNW&N-35-1!P#Mn=kaO_DbL}OOjzstihI)w0LxM2G#RitvMTpxD&8Zg#M z>*F((^Rp5K&F-utnWW%nMjE-Ki*UHDt=n_A!EG%jA5kw?{MSGeodYvM|KVwlF_li$ESG&0mH7)7Vkg1 z{SQMgxvjnkueZtj5%<%0Eg!#bCG%WPwJ16TW6aC^>F`=LRcvmbJ;g=jJ?XI^IE{1| zLP)M|D-hl5N=W)b8-wS;hu&*ma9G?ilp^N4*BFhHb*2noN08}<*8P%Q=d2_t-m%~E z{7n<3sl=t+_8V6b(UfV6RjL;_bXsSgsP_koSg@j3iFZJ`5rT-;z8y2GL zuGxi`+V6fWLFl?J^NLE|0NYB7V`n(TBT4+)xE+ed&$6>Ux>d*@uexr#p5^3nmkwnI zi!}fG&O{RNzX9??y7s!6mjfbryZgiUk{ZS_H`j1jaNG9*E{?h}d|(7wa+3(&rW*{z;Vx%>?mti#(L{h9O}DWj zxJNecq1KZn+NI*HBVx3amQnYfny*QeulD#Vi}{a(%e6m0hn@k2N;drciAGr$)<3nw zAn6Stp{~|2A{I7j_GKTP)F>OLb|_)ZK0WfDi21&s1tw^f2RfsJ9yfJEz8$J2PV0BT z^B^s7lbNx=9uB0J5`&mdV`O0Y2Ec-1$zFH4#F*A!i`4TV6(!tc8X5}O4oIw2xk`#3 zy0?Gkc_rizXK2s(G((3~fu0h+=vL;?+)8+W^P>JFemn&ZmWBzs`X_~Ti@F{-L*uEtaA zVGHg z$G%IpBYdl+z)~T>%(cFJtwt}S-TOgN*{uzvMyfy;op&MBkX^8n7r$Y&MN8-=`4t&|1+EXIC#AX5mKbo(Yqw$S z(`|5^z1~rAFZ^ZHIqOLEX>!K_?;Gybujs@W6l(8EAM__`_kfwnquL>(*~?H;(W3d9 z9?d}>Hd_`!T8yt+2P3n(Q49VSUhRgPtM{?GF{O1%*XSlz+ zkc-G@@*Y+?+I??_?%x0_G3=_YRnNkw9BwUi^hm&V-Xk`z)(__;hUvn_$IhE-Pl2pk zy7vwmaXAS0B}(bSuD7ihH820p)NGl415{UbRPADqS)sh{OD%R<@7*V?snfu@o6Z;= zr+@VN=Vsg)TK_A9IThXgLp6pw*)9rzUvhR2(aIIzNmOeQE`?GK}=Pi_$_RW^Z^hGJT?m8 zWG@oSAQjA|@s8fhc6*+(&N&JuNYpFU*4|_T`D5&xpBa6B>%Y#OUKEc}D-DLPRrd-F zAL-bH@eWA%VXN^(u{`h!PstwYfGkojFz`pbP)x;Oh&P}SZD({8xTn4J2|ebc9PH4p zB9`QuYN~GPCXPNj-ISwzSck@-R!$8SK&;w4)fZe`Xske$JdTv1f-bV z(HMB*$!p%cmogO!FCsAipj4QcMjtdLC799od7v-H1JjS@2R?SJB~>bNI`qOq8N*|c zwv_Ko@4fAF#35vr(UNvlh<_vi^LWa%TO6OgP}gvNMV2f`R~+1b z7BmBK>Lw$zTOGRoMfJ*PeXz7!WRx$RocTptqCVsnJwl&HyB9m@J0AUE5Ld;~Xm>w4 zFU%;iJoutU52r>^+Fnw7unda^DNw>$T1%}6tL&g-k0^+WnjvxmwpbJ=2`3S@go576 z|99Z0a52pE^xY!rIN~pp#{(wiDMKGRDujZj%|GLp|Dh}gQRGSr5b}XYp}^vGB9ufMwn;c5DOm>jEq306luL{q$F8D4v>OI%+WDx>+vrC zdPehHmk~uc8c15QqB=?YD<94m25*6s7Oj#qg2vb4`*IYn{~0*Jjvx8HzD(L!R*apJ z-To!#d{>V9IgTkhXc!7vm0Gmce?+c@A1GgaX?;HB23dAs(9 zihB+5dtdrk8QUpW+-9NuP-{i{%jY#D)GlWtg+nO>^^2rD1nP$al)^c1Q9n z;{`n_Xtq6Ef!(rdxSNR}P^WA}Yy7(4=vmd=bIgYsxpjJVl^8^ayEgz8qUe=#?H}uU zf;jy!=o1?E-<3U4dzG|Ca9*-=Ig;r4Ym~T2PjUP7vxzcv5@sF0_g6kIyJZf$lF1WE zM2V$qa>tGd;HAE>*Emi2>OjWFc+b4nwhrP*_B)1j)2$RwuGD{Y;+GkYJnp&dF5R=p z*c&c@ZW&Rem!_hq{|t59B~gf}syLxdFW#tE`_jTVP_}f)qXIo;%Fk?*>Tbt*kxucI@Ec!*z;=ql1Y4>emS`VdKAh^ zf0%eFH*E`sFO3D3==IxX7Dg&I;<$hKq!|%>wXcuM(YpC#Aw`!Z6U0OqD*p}ZYHtuc zzK0i)69ei$-i6EaPr-#W&6O!PWRyG9sCtd8|LOB}qs-D(Dgw5HNBLDYe;cXgm&R(c zt@KPeOUaRo_#u;sUfdBR2N)-#t7$eXM@^te#9&o=5b~bc@3BxZ#I|a-Hh@bx4j_Z$ z)S;Vp8%ZxOgHatpe7Lkg-mx_UpO)1vEo3A0uSIZ9XpJGI%k`S_JcW%Ut}PeK0c1<~ zHLa;4=c$~gDqR|xIPp#OFOnTmhK!T;H18>C(K@!otJlu-v25053zUDE5q$AIQhb} z8I?R&`=eWNXUr*j5LKj#ho`O`=NHTkE3f9Kh8w*QYOMGbCs5e-3 zrA~@}Dp?aKbYLZ7aJHZYe8F9Z3s6}CMcFH0)tHP+ygOn_csll&7{yR#WxSV{YRY zdTr|m4w)aEh3{DZ*tSd);t_uM!~=D9!s!Dz*AYt-iScyMf#f3yj)5f%?m44iKI?r& zIY7rcv0I`xW3z z2gU*zgv^Lp65JO5xJKf$hbF8!o=^($NcfWZd~vzqqJUE?-j2u?Y;DOZgd-La{gU3z zsxGEB=OY?KFjGWiucacxY9b&Z(=t4wyX^5zV8a!47}BhXL?rhlZzaZ=l+0qy97pt-gveobSwcRmrmVWv7uItJ!0nX6zdSVEjap0(K`8cmqcu`ub`6tXVKxUbJX4_W^; z-T2$7BGQxZ>MQG)%J7CYbzcH>)w$M`pUE5iQ#(x>vG~XB=dX^J zpW|+8)Xwy>>%hi}aP|T|mF0+F4WQTTep}P8BA)r$3OP<{9yKp!xtdNiM@}2W+F$I% z5utj71A@=~Fr_oy?Btsxj0>|FxFM|QB+@LQ8zz?ytSyz$Ign4s66_#SMq>XMAK&GH zC*}ER%cu5+G7Rp~u`#^U9RYc+3|p&}nVVzJN3}ZGqft9^{g!Z`+@96?nnuC*8rtec z$2PXL&sL8g@-FrWISzu!*~DxeY{8Pu9-L)L{&cdKqL0pp5|Z>%j_2WwdFmOuS`&86`(Af-PSYsxKz@plLHAU9 z4{sX5T)!%N_@I!DRo-JYP}EOGSp5LpvlMH|Mk?BNzGFEVsvkWuUR627(Rh%;o3{CE{t~%suViQqXbG;scp-=`iZ_ZlhiFEg6WoSm|sk!}rX0tf4ENHAb)L z3-sy>-D_(j`DGB1wnYUa9XZj@G#-KGucz~PdKgOiJx)PN7(HKfxLr((d0GUcD$-qP zwiEwmI)l*(;;qLGhp?vQ`XUB}@jSS}NzV&uxmOBNWT@QngqWQL`3OcsJj$^yKN_{G z{>lp{tlyfs>wSDW(#@n@6$I)1nU31c$I+lgR+LM#`|eXXfP72Z;K6lGs6@J`8x`&) zl~2)JOVuwa0FaZHgg`TV4sJg-mz1gABEUxXHg?@c=|L}BA`QXgRNF5xy@)z5?)rqk zh+<$>S>_{}Xw`VpR9L->%Op@ab~z|r+fV{bfA?J7=U=vwO^{$XiCH&Fg==HoP9sh3 zV9qMk?$qvfadNY!-Pb&qRPsboi1ARyWZd*iIH;T2h7hBTWAG?z8U~YfKGhY+L0WD#l3KvBX$3lguBJN3x&m2N`hz}P z<@-&Fd80*47O5xPK6uliDmh$K7UH0=52r?^sZ(NBpP6~)s*ZF9YUl?fqcDg>L&dSv;#^QWf03MFW1qmw#QV2p*KK86c!$p{xL$D6V2d}$` zSgX%Y>5OozpK`l!SX}sZ+)|wq>0aj}JCk@uK5x8~oZS&emseCm%-;YOoNWTwh9&!! znK6A4$O51c!C2$@Lu0gx!L`scRRzhfcBR)$C`@A#Eg11*dU|J?_^2d|vIef?RwcSL z8S;pj)Vmbvayke3Msh?h&rSZ{!+EF*4y%w)h`dw#s|q8s>qkL`%GDrq#=CeuGbUc1 z{rJsuPVckY#xj>o)&rLQy2y=M&KL^Vl?b+14&XgqDv{;~v_S5ZDzZP{XgcFBd45ay zErg*{^f%*eypO4NVzo>z!Lv6&bcAQi{8O1)d`+?FjulZ9!>%&>u%IGMawX<@jBjsSK)Mf4E5ruu; zv&{gwTfTaF*)2}9gxNo z)#^cml7)KKI;sqYE;yr-PFc{`=^MXeQ>XUv;W-4eIkWHc?DfFNNjHqb%t|A7)agw7 z5knu1XIq1G>KA@y4uRcAH+#MpwG=g?@>+bwjQAbC7_?%VdZMERM>kzxVO8d}8PJvR z@SzjJnagQ@h>PrOccfaFV3OMV&NqEDQjkx}opjx`HjHpBFpMO>eRyjnExS!hmnZVU zjk`o|apmW*Ejj{oj)g>Bsv~t#IYUs&kx+ttn;tiA$1eGp7nUSJ)TQp+i+bey55$*K zY*ErE+L_Z3u~5DSf2(Qsp{yW%W-mnF6eX49smf(A9wy6~uQGcufRE|xuL5;rye%KG zoOu#LOZjira52!7c^Z|`dMlrJmwE_Me++xcMccC$y4jA%^REo&=WBi&;(yhj;ES?a zi>u8D#l5p3x(gbw*T>0??+brD-hF;jO0(jcv(&K48}+)L?0VdQW#T6r4S_4DP9<6p z_ZEe35`bhW??IVoS4I@!Q*$+yZ(dD)Bq6d=plSQK183Dv0a7(HjvXN^u5iN|Lo~{{ z*9z!?RYtQYOgD|Oc;irTacx^)yP(f!;=ome_cEfF` z1SGj~5}r-5Le5Wa=r#*mvbXy>c5_Sb6gK(jj3!6INU#f=+pRgpCwNY8w?X~}D6)FE zVa;}STLX4=i@X68=g#;ro{rX?t_8Yeg$jh*?X@h>1A9hVcgKP@9X;ds5@*eQH%=cK zeM?c28(dIe3Fg%_xbb_f%~uK6LhxfO_sJVP4I*FY^;GrDBthR1uyt2T6fUBq_b+)% z4}bbz1ZxiTz5#%AEwPM+paAzYE)DGJ&`XxyRpW6I@MCDMv)93NTk&6p&j$B>JDgFs z%p1)Q;xD6N+x9BwRZs3+Rz!;&qTu^wjdvfa5M}o|+HNJOiXe*KM#AfR45=OdshAQg z@4%9+izVubwCw}COvtglAWA`j-UAB1RZK`S=!wMs4FGR>gdf)8ZDqD&1~w>Kk@3H89AM{P^sNm)7k8OOWK@Rqec1WW|2fc2)syV^-*12dV$zTA zp~W!`&wm>1bAQPy-^?U!CWR}w#l73oLAB*W_&9jdWJe|J{H}>nOw+lp2cmF zEUnxHZOC za!ljf=??J7MlG;r?M2y`$ktiRrSr$_Yz26?plG?1pBLOx|0&t2rQZW){io5+=W2iu24kR2<9D zeg(ZO2;@KMyiBuG7)a->6-+{m@-rX@e$WQS9AjrV;6nj zvh7!10F1QcRdrBX8mnz8ak%9D`37JG9;Op05ya{ZA-|4Y5GV>HtB;dxtR3X;vA7j` zCW~%Fbfi7lcaA0_r% zHX6Kzno&J?seEt?sfGz!sNNv!m5^{Dfr9h6Cc1+>j;O?M^0(GBUmYnZf!gnP4$C}k zlYfE_wh7Mom>R06dG>0Vh-+x@gm^H zW=tOx^!~tYB7-w;Zw8OSingHN*+QDVTU(j_dwxfZ(+gFHq+A69mIG=9bOlt^I|VI8 z(X^iuS--RgF*w>{D;+eYo5mIL&H>C%eh~gFR@K&hZiCCB+vm$_82iR0&dg1CrG-T6 z;~KPcVP_J;JIh{7-dz%`A0RIo-bzu`W4_uxIxtIYJto0|yQQrmVmDC9O4;ke2;pSX zpa(TZUm13krh{1I8hztm2;Zwb8p9m}34XZm{QcVX`?9n$R_G96-}t4ml%XQ_eB=2< zxN&Z;#K+}S$}#s5V{v>vnB`SzZ`-FBEWSG5)Jf3xpp+JMms0`XnT~H)AiU(_Q}YIp z=t+4Q=mc zkIxQ4j|MNeC$oKz14y!1mOfu^Mq<7JI3G})a?;_D6D%SL10EA@w#Vt-P^EI{kLOlq z4+;Hf<#Vmj7%57~y?D|zJu}ZZjp9$Sp1T*CI}r*`Y$O*<{zHb618g^nLaj&JYj&<+ zmFH0mK;(@Nl$YW$g#G1i0djwZoY@lh?r;TV46J@YgnbWCXunOxkktZie`aawjogBI zU|VD*^ViI4JuDc|@#5IZell>{9KGa$@NtV`Ev2U~u#gG70igekic)DsM-c8&X=bWs zMM(w72hayi|Ik)U5Rh>}G>)A1SX7NYY9f0g`c@pkf#6O@oGvLryG>`$emc6}LHN5`L|UXwBeo75y!ouWK`u_a562ezG=1==3GsjsywaTChOk@&-w z@?{`J=$^y zXc|h*(-z4(MyfS#M?KXHzmMzw{UaS~J2ka}sO0#b5?p0jC_Qgd_8wibK#*Jk$x-7o zV*NJ7yJvqTv)8_(G(;$<0(MT@#bpfOo8a!!1go_Tn9AEkNmhG^ki`}fau4i>l{GWTFIH1R(8QKHLeagA++ zkqKzIKvP*rn4OR?9FG?h;_gFd1X;EnMF-lv0on*{SUkWa3W;Di?fKVhUDhP@{8!9^ zQADOFpQ*Ff*gtXu`4+wm@hx7m_GRw6o=J5MzO~1u2Nncc+c8r;riIh>OIIF`dX5ji z!?QM|>~Rs!l73j^X142rea@*G=^cF~9!XIR7I+evyC^2D#LH+aa&QYtu|sOY$V5aH zIJ|6(u2nLXU<+HEWiX+=_9Z9iKn=8Qt}5edV|&4EgE507jT&qS_XcRF7p#gLgi+p) zhm#xd;Fi=$;`+7xxhCiUGxJZf1UOg13&xIvbDTVOJI1372!YIjC-tfr?KmBR2ib2m z+)a6(^q=L+WD1DZ^m%P8PHpeJ_@m0ior6gbzu0dfBoB4i*JL*lXu@sj(T86->&$FX ziiBF}^osR4F*(U8F#a0sKp8EyZ|I=az0(smz4dnL%DiSxnKe+2IsM)g%uPI>eCSPZ z@kumzG3VTw8+wnkVy7Rx3M6spt}vCbf$xcdr##0KV{Ipba-)y7%%%cUcvx!NHl#(Q zrL0U6+Yhoe*?Q=96wra{i>DI__RX~?UY_RBgM{-Ny`}I6l0yFm0`v}SN&w2f?(Jos zvvJOJQGQGZ4&%!)OaQJJkSoQ$G9@z@DEg=Q5YF>R*1qVM1*@@zudT;@3dr)Nq<)+J zg>1YiYIP+lK;+a_Zjd#UM9Y{rJvfA@WsDM9k|e&7u*_iGEB(I5E0-skCrNyl=M?IO zF>6j*tAew2{zkw*k``xK*I{XGR1f5QG*jTFXk_~jN#la(RJRzTkp!-Z* zHt7Zsd@17UeC*L>)MxTpzl zP`j>8S@2vbZxOojkv2RUpk!Pj@m5#%sN)}5x=rN-l@%om1v^FQ0$y&o+*qK- zGNb9HuOZ&!qT2-T@hluXHQkV7SZ7w;N+@jAuT!W9+YP2o&CXT~B{U1B+6Fg_GcKkz z9kffCAH&+d&M*ogb-=@neMMW76c0B#h}pRgDgseg9)?ziUcf_@8*!qVT8WA9rpwTR z44nLf+PumaS_(@z2}A@=dKu_Dtqb1Y#0z}RwFPee5@;vBjVh=ePYQzO;Hg3jaby%D zc36!6PEgFy^~!1PLEJv-`w}5RO~D8*Pv&Qj%u&>(r*42<9 z&o`@_(V(fp9^rVBpepy>jit|VYXrBXSZ0`dc=KxQNihZla*i}v<1?TVof5O_H7+<( z!*E{VOXmL545eScaI83(4jP{+x9*%(=$iWmY0z1?0+!~cPW&zBPIuVvbE729NMz)I z5cdu4U2l$teMOC6b1w{r8(BHnbiR>Nv3+%sd@acZWj_eVq2<%}VFVSIm6 zrxLJZ#g#GoJMAat%3a4et7(KDfn1PC&Je(JF3H=7q!)@?`cq*5Of1;Nx#F=#RhwO8 zGmSs{D#H!cN>5UKk(1H5o7@QT?^&MA%JLtlDxsyOwf(euBOItmz_%}6b(LogoAMLQ zKRwQzqHU=%{i>NQr>z^82VVxKv6#5-r*%~>v^A%$cl0~UaPP|5*BU1I4J`T69x5CO zX~`9rzQNB{+i5ce!l7hjiWCW%UUY_1x@%q`M&&I9So37ciRr9J8|Bb$)RP=3<+kA} z{qo?>6*^ULDvRd(@q!isZ(@5+@dMdyFC`g_Lj^&tq1DDI?Z=?nlA+b+q~DnW4#6yB z)|X1KlPin+kevDb)Ig-}PsSEm=h?KH0W3ZS(C3zjhymuJ|)Vuns&?#`)CCJsPrSSXYMvesrajF}&6!6Oq!SU;56Ux&Y zsIg_2SVLpYajHv7qRW$%F^H!7_mflT`2{4*eTvNv4ley5fg@Uw{J}+zB!v^1>#IpP zja$VhxUmE{az?Fwigrv%y&eq5#xID42pzCSjw_tyn$;(Q;+~L%2ze<%Q76Q+SMyg( z%%&KnonZZZ7Vqu37c6zXMX$$@J=GLS9}KpfKNXUQ%hE&b*+Cw`T-dXQ%JLLZKb(@W z=hSFNs8rBNrC~l>;u)SKbo)#9MiFM(CuXCmuRC*iCV|aK0OYeat9ie)dVu+D$cCsJ zfKRDEcCnmFASJ2Elq!1#2*;i`v{?~RN^ljiTJ%o~5_KjXV~fwO_0N?gJaq)U+&s(Ua~yC}J8=fDr+u2a#T-i=E=3WqzJT2E-gy7-B2? zj&E5D9ha|6`>f7bd}1CAWlXb>zi4?KmEmFo5|ELuG_)8l0Xbb!UDQT))iXG$^e6F| zzNL5Y!i~Cd(XjCoBz0QVi!sZWv#koNe{F0Cut6p~NY@)=_;2~RhU zagA%76lfFc4%Suou}rp%U*bZ{9$ z`SvHw21Z7lGPJMY@hXsNTS9?;aq93WzR<$q#57hJOb)7;fBIuc6-T%%UgqC*#KKOA`{>sLb{a^AQ#|Wf+7S3<+hX!nL?||^SlK_ zV$lkKUY))bIpy+6RfR}&mmaghO+d0I4d~o^rWYT#Rn&XSttrJ~QMUEDaIXRF{=Rxs z*4EssT41SBLi5xiQy}WXHUznNFJ+)D+;f5WvBV)Uj`Y9ZTtVJ)QGZX3eQws+ z4xi}R66P$d$Mlv_8c;Ja5BUR5WaehmT#^&pr+7t5&3l&Qyf&p#zK9vQnE0U$uAU5Q$$yUwzYcBrcpqn4OKC!av^ab8i^TWiTkx zQh$}K;jA8biF_dL#Co&l+qUNF162wwP~8U<_{UJbU18gUkj{!U4&3Aqnb?zyUUMT^ z7elG4n>2J+Htx31x%Ad;tI4(;hoC%b{)-@;93anYtXxR@k{037M}00qwF2rpt76kf z*WaAeZ0FwyYLkIdz#-|JU4_`aW>1_VwjT|0PG>Fz7OGy(2AR2pKIxQV>875O1mKl+ zmE@ab(49n}m|V^R{{`1x1<=`y>hNBvD=M^T$Tf&-rKNi~Zr4HH=yWEyzY`810$KXP zQ_I`3^$fL@fgt!N2&+3gwiIX!!+~M3X|^zTb`gRe6b^Qb4u__yUz$W)YTM z%N`7kHJWvQv}x#hsrp1CIHY^HHItU`@xjkK$$t^?Cp8IYb$?K;P|3q~+lHfRE0 zP5OKhs>OY++r2YHeh~ifbLkvU;*ArJmjdG(U45Rax{$-K!!+#r-%?E>*NkGjsfKcF zxGXu~i}Wl-zkbBdNyo$&qSp+6&@$J%-KN>9t{D-(AXQlB(n1`@gX6MC;gO+3Zo9<^ zb{#ntOs~LG=`D>rvciLP>l-0)Re?XKl>A?SxVRSK+EPzL8Pr_ey4-9MJ*iv_GIy^F zta?`{2(nwgE`j;Aptby1Y<$-xRVrV`cH!`Vr!&o^B@P0*LiJbDJT(fi6l@&QsXMtH zQ+3`?>()R5XRiydcATRlrT)Aa!?V=e<;(@SRjPvV&q7I~x=Yx(K?1l$z)fr>sC?xu zkuh&T{i+pWjxZe6_pX&)CU((%I8@77_??umOK2R6|4pOu)IaN5nb{LA=6`=Qoz3uv z07MdDZCP+0-#88I9LrDgsW*wyoJg#)M%*-7DSE~(3Y>{oPm00MzL2B36*+>Jm%M}w z`8CUMqiY@o?i;!0Z3L#vAVBVAcE`_xd}KXYd%ju9V&mg(2F$piS<`A~x|^-SD*_Ye z2qLF_pFg=eoF9A!v&y8T(`u0*#J?p8xbULAYr8>N61kXUyaP%+t-cn;XZ{gJQpg5! ztUzA3<<`9N^l9*-UrN`(hz$NaWcgHRf;@@M&=&3>7X$ZcxKSOg{dRl5Uk*z@7jRC=XMlIqRASjs11$3_f~VaRFS^kq-RsGjs?+&;djTMZtBN4F~sg~d}s;l>BCgy4HM7{y7OQ3QGSiG zQM@mYP$P6ybc+M)4A-6DJc;-dDJJLghAa2hj@gQqN`C=-Q+o6a{K(%#jVgeVyK7Ur zvtDhZ?{AvF2;NAK z`2ZQv`CXB>vo=?+t*p%?<>>g^d0X82C~s2buGt|(X}Pj&TZjAlebS}8_uFbw6~dIvg!GA@sDMTp=%HB&R}}YOGA$qUD=TM5 z6e@AZJpVB`?Q0$^T{ypY5C3${DjZ*aJEcdb&zqi*4&BnmPffSkqEh#cNr;bDv7|E! zO5Pp~C#L-zN6F^&lpC|wrzgoR@yPBeHXn>${vzrCp<7se$lWvU3;j`__ + `GNU General Public License v2.0 `__. :Rendered: - |today| + |today| -TYPO3 -===== +---- -The content of this document is related to TYPO3 CMS, -a GNU/GPL CMS/Framework available from `typo3.org `_ . +This TYPO3 extension, based on Extbase and Fluid, is an example of best +practices in automated code checks, unit/functional/acceptance testing and +continuous integration. -For Contributors -================ +---- -You are welcome to help improve this guide if you missing something. -Just click on "Edit me on GitHub" on the top right to submit your change request -or `report a problem `__ - -Table of Contents -================= +**Table of Contents:** .. toctree:: - :maxdepth: 5 + :maxdepth: 2 :titlesonly: - :glob: - Introduction/Index - Linters/Index - Documentation/Rendering/Index + Introduction + TestingFramework + Environment + DependencyManager + Running + ContinuousIntegration + Documentation + Security + +.. Meta Menu + +.. toctree:: + :hidden: + Sitemap + genindex diff --git a/Documentation/Introduction.rst b/Documentation/Introduction.rst new file mode 100644 index 0000000..6d05091 --- /dev/null +++ b/Documentation/Introduction.rst @@ -0,0 +1,53 @@ +.. include:: /Includes.rst.txt + +.. _introduction: + +============ +Introduction +============ + +.. _what-it-does: + +What does it do? +================ + +This TYPO3 extension, based on Extbase and Fluid, is an example of best +practices in automated code checks, unit/functional/acceptance testing and +continuous integration (CI). + +.. _presentation-online-days-2021: + +Presentation at the TYPO3 Online Days 2021 +========================================== + +At the TYPO3 Online Days 2021, `Oliver Klee `__ +held a session presenting our approach to automate extension code quality. +Have a look at the slides and the video of the presentation! + +.. container:: row m-0 p-0 + + .. container:: col-md-6 pl-0 pr-3 py-3 m-0 + + .. container:: card px-0 h-100 + + .. rst-class:: card-header h3 + + .. rubric:: Slides + + .. container:: card-body + + .. image:: /Images/SlidesCover.jpg + :target: https://speakerdeck.com/oliverklee/automating-the-code-quality-of-your-extensions + + .. container:: col-md-6 pl-0 pr-3 py-3 m-0 + + .. container:: card px-0 h-100 + + .. rst-class:: card-header h3 + + .. rubric:: Video + + .. container:: card-body + + .. image:: /Images/VideoCover.jpg + :target: https://youtu.be/_oe8ku2GM84?t=6983 diff --git a/Documentation/Introduction/Index.rst b/Documentation/Introduction/Index.rst deleted file mode 100644 index 0df1e6d..0000000 --- a/Documentation/Introduction/Index.rst +++ /dev/null @@ -1,16 +0,0 @@ -.. include:: ../Includes.txt - -.. _introduction: - -============== -Introduction -============== - -.. _what-it-does: - -What does it do? -================ - -This TYPO3 extension is an example of best practices in continuous integration and automated code checks, also -writing unit and functional tests with PHPUnit in Extbase/Fluid-based extensions for TYPO3 CMS, and then running them -in a pipeline. diff --git a/Documentation/Linters/GitHub/Index.rst b/Documentation/Linters/GitHub/Index.rst deleted file mode 100644 index b4334dd..0000000 --- a/Documentation/Linters/GitHub/Index.rst +++ /dev/null @@ -1,22 +0,0 @@ -.. include:: ../../Includes.txt - -.. _linters_github: - -======================= -Running lints in GitHub -======================= - -For GitHub, we prepared two ways of running lints. First one relies on executing -composer scripts, and second is using exported, prepared GitHub Actions in your -workflow. - -Composer scripts -================ -You can run your lints using composer scripts. An example workflow is defined in -`ci-composer-scripts.yml`. - -Ready to use GitHub Actions -=========================== -You can use prepared GitHub Actions. All of ready to use GitHub Actions are in -`TYPO3 Continuous Integration organisation `_ -An example workflow is defined in `ci.yml`. diff --git a/Documentation/Linters/GitLab/Index.rst b/Documentation/Linters/GitLab/Index.rst deleted file mode 100644 index 1c5f6fb..0000000 --- a/Documentation/Linters/GitLab/Index.rst +++ /dev/null @@ -1,13 +0,0 @@ -.. include:: ../../Includes.txt - -.. _linters_gitlab: - -======================= -Running lints in GitLab -======================= -In GitLab CI you should use composer scripts. - -Composer scripts -================ -You can run your lints using composer scripts. An example workflow is defined in -`.gitlab-ci.yml`. diff --git a/Documentation/Linters/Index.rst b/Documentation/Linters/Index.rst deleted file mode 100644 index f721b8f..0000000 --- a/Documentation/Linters/Index.rst +++ /dev/null @@ -1,18 +0,0 @@ -.. include:: ../Includes.txt - -.. _linters: - -======================= -Linters -======================= - -.. only:: html - - This chapter describes how to use linters in CI. - -.. toctree:: - :maxdepth: 5 - :titlesonly: - - GitHub/Index - GitLab/Index diff --git a/Documentation/Running.rst b/Documentation/Running.rst new file mode 100644 index 0000000..12eb4ee --- /dev/null +++ b/Documentation/Running.rst @@ -0,0 +1,281 @@ +.. include:: /Includes.rst.txt + +.. _running-checks-and-tests: + +====================== +Running checks & tests +====================== + +Most code checks and tests can be run via Composer commands. + +.. contents:: Table of Contents: + :backlinks: top + :class: compact-list + :depth: 1 + :local: + +.. _composer-scripts: + +Composer scripts +================ + +For most development-related tasks, this extension provides Composer scripts. +If you are working locally, you can run them using :bash:`composer `. +If you are working with ddev, you can run them with :bash:`ddev composer `. +You do not need to start or build the containers for this as this happens +automatically. + +The code-quality-related Composer scripts make use of the PHIVE-installed tools. +This means that for non-ddev-based development, you need to run :bash:`phive install` +before you can use the Composer scripts. + +You can run :bash:`composer` (or :bash:`ddev composer`) to display a list of all available +Composer commands and scripts. For all custom Composer scripts there are descriptions +in the `script-description` section of the `composer.json`. + +.. _running-code-checks: + +Running code checks +=================== + +You can currently run these code checks on the command line (if working locally without ddev, omit the :bash:`ddev` part): + +.. index:: Commands; composer ci +.. code-block:: bash + + ddev composer ci + +Runs all dynamic and static code checks. + +.. index:: Commands; composer ci:composer:normalize +.. code-block:: bash + + ddev composer ci:composer:normalize + +Checks the composer.json. + +.. index:: Commands; composer ci:json:lint +.. code-block:: bash + + ddev composer ci:json:lint + +Lints the JSON files. + +.. index:: Commands; composer ci:php +.. code-block:: bash + + ddev composer ci:php + +Runs all static checks for the PHP files. + +.. index:: Commands; composer ci:php:copypaste +.. code-block:: bash + + ddev composer ci:php:copypaste + +Checks for copy\'n\'pasted PHP code. + +.. index:: Commands; composer ci:php:cs-fixer +.. code-block:: bash + + ddev composer ci:php:cs-fixer + +Checks the code style with the PHP Coding Standards Fixer (PHP-CS-Fixer). + +.. index:: Commands; composer ci:php:lint +.. code-block:: bash + + ddev composer ci:php:lint + +Lints the PHP files for syntax errors. + +.. index:: Commands; composer ci:php:sniff +.. code-block:: bash + + ddev composer ci:php:sniff + +Checks the code style with PHP_CodeSniffer (PHPCS). + +.. index:: Commands; composer ci:php:stan +.. code-block:: bash + + ddev composer ci:php:stan + +Checks the PHP types using PHPStan. + +.. index:: Commands; composer ci:static +.. code-block:: bash + + ddev composer ci:static + +Runs all static code checks (syntax, style, types). + +.. index:: Commands; composer ci:ts:lint +.. code-block:: bash + + ddev composer ci:ts:lint + +Lints the TypoScript files. + +.. index:: Commands; composer ci:yaml:lint +.. code-block:: bash + + ddev composer ci:yaml:lint + +Lints the YAML files. + +.. index:: Commands; composer fix:php +.. code-block:: bash + + ddev composer fix:php + +Runs all fixers for the PHP code. + +.. index:: Commands; composer fix:php:cs +.. code-block:: bash + + ddev composer fix:php:cs + +Fixes the code style with PHP-CS-Fixer. + +.. index:: Commands; composer fix:php:sniff +.. code-block:: bash + + ddev composer fix:php:sniff + +Fixes the code style with PHP_CodeSniffer. + +.. index:: Commands; composer phpstan:baseline +.. code-block:: bash + + ddev composer phpstan:baseline + +Updates the PHPStan baseline file to match the code. + +.. _running-unit-and-functional-tests: + +Running unit and functional tests +================================= + +You can currently run these tests and coverages on the command line (if working locally without ddev, omit the :bash:`ddev` part): + +.. index:: Commands; composer ci:coverage +.. code-block:: bash + + ddev composer ci:coverage + +Runs the ci:coverage script as defined in composer.json. + +.. index:: Commands; composer ci:coverage:functional +.. code-block:: bash + + ddev composer ci:coverage:functional + +Generates the code coverage report for functional tests. + +.. index:: Commands; composer ci:coverage:merge +.. code-block:: bash + + ddev composer ci:coverage:merge + +Merges the code coverage reports for unit and functional tests. + +.. index:: Commands; composer ci:coverage:unit +.. code-block:: bash + + ddev composer ci:coverage:unit + +Generates the code coverage report for unit tests. + +.. index:: Commands; composer ci:dynamic +.. code-block:: bash + + ddev composer ci:dynamic + +Runs all PHPUnit tests (unit and functional). + +.. index:: Commands; composer ci:tests +.. code-block:: bash + + ddev composer ci:tests + +Runs all PHPUnit tests (unit and functional). + +.. index:: Commands; composer ci:tests:functional +.. code-block:: bash + + ddev composer ci:tests:functional + +Runs the functional tests. + +.. index:: Commands; composer ci:tests:unit +.. code-block:: bash + + ddev composer ci:tests:unit + +Runs the unit tests. + +.. _running-unit-and-functional-tests-in-phpstorm: + +Running unit and functional tests in PHPStorm +============================================= + +General setup +------------- + +- Open :guilabel:`File > Settings > PHP > Test Frameworks`. +- (*) Use Composer autoloader. +- Path to script: select `.Build/vendor/autoload.php` in your project folder. + +In the Run configurations, edit the PHPUnit configuration and use these +settings so this configuration can serve as a template: + +- Directory: use the `Tests/Unit` directory in your project. +- (*) Use alternative configuration file. +- Use `.Build/vendor/typo3/testing-framework/Resources/Core/Build/UnitTests.xml` + in your project folder. +- Add the following environment variables: + + - typo3DatabaseUsername + - typo3DatabasePassword + - typo3DatabaseHost + - typo3DatabaseName + +Unit tests configuration +------------------------ + +In the Run configurations, copy the PHPUnit configuration and use these +settings: + +- Directory: use the `Tests/Unit` directory in your project + +Functional tests configuration +------------------------------ + +In the Run configurations, copy the PHPUnit configuration and use these +settings: + +- Directory: use the `Tests/Functional` directory in your project. +- (*) Use alternative configuration file. +- Use + `.Build/vendor/typo3/testing-framework/Resources/Core/Build/FunctionalTests.xml`. + +.. _running-acceptance-tests: + +Running acceptance tests +======================== + +1. Make sure you have Chrome installed on your machine. +2. `Download the latest version of ChromeDriver `__. +3. Unzip it. +4. Execute `chromedriver --url-base=wd/hub`. +5. In another terminal, run `.Build/vendor/bin/codecept run`. + +.. _running-acceptance-tests-in-phpstorm: + +Running acceptance tests in PhpStorm +==================================== + +1. Make sure the "Codeception Framework" plugin is activated. +2. Right-click on `Tests/Acceptance/StarterCest.php`. +3. Run 'Acceptance (Codeception)'. diff --git a/Documentation/Security.rst b/Documentation/Security.rst new file mode 100644 index 0000000..8760ea9 --- /dev/null +++ b/Documentation/Security.rst @@ -0,0 +1,16 @@ +.. include:: /Includes.rst.txt + +.. _security: + +======== +Security +======== + +Libraries and extensions do not need the security check as they should not have +any restrictions concerning the other libraries they are installed alongside +with (unless those would create breakage). Libraries and extension also should +not have a version-controlled `composer.lock` (which usually is used for +security checks). + +Instead, the projects and distributions (i.e., for TYPO3 installations) need to +have the security checks. diff --git a/Documentation/Settings.cfg b/Documentation/Settings.cfg index dac93f2..0fa8cdc 100644 --- a/Documentation/Settings.cfg +++ b/Documentation/Settings.cfg @@ -1,66 +1,62 @@ +# More information about this file: +# https://docs.typo3.org/m/typo3/docs-how-to-document/main/en-us/GeneralConventions/FileStructure.html#settings-cfg + [general] -# ................................................................................. -# ... (required) title (displayed in left sidebar (desktop) or top panel (mobile) -# ................................................................................. -project = TYPO3 EXT:tea - -# ................................................................................. -# ... (recommended) version, displayed next to title (desktop) and in `__ +can support multiple TYPO3 versions at a time, and +it provides version-independent abstractions for testing, making it the perfect +companion for this approach. + +This is the approach that we have chosen for this extension as we do not want +to maintain two branches in parallel. + +.. _testing-framework-approach-one-version: + +Approach 2: One branch per TYPO3 LTS version +============================================ + +With this approach, there are two main branches that get new features in +parallel. Each branch supports exactly one TYPO3 LTS version. + +The upside is that this slightly decreases code complexity as +version-dependent code switches are not necessary. The downside is that there +are two branches to maintain, which makes adding new features (and all other +code changes) more of a hassle. + +For this approach, the +`TYPO3 testing framework `__ +- which supports only one TYPO3 LTS version at a time - will work just fine. + diff --git a/Documentation/genindex.rst b/Documentation/genindex.rst new file mode 100644 index 0000000..806ec56 --- /dev/null +++ b/Documentation/genindex.rst @@ -0,0 +1,7 @@ +.. include:: /Includes.rst.txt + +===== +Index +===== + +.. Sphinx will insert here the general index automatically. diff --git a/README.md b/README.md index d7a48aa..11a1a27 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,29 @@ # Example TYPO3 extension for code quality checks and automated tests +[![Latest stable version](https://poser.pugx.org/ttn/tea/v/stable.svg)](https://packagist.org/packages/ttn/tea) +[![Total downloads](https://poser.pugx.org/ttn/tea/downloads.svg)](https://packagist.org/packages/ttn/tea) +[![Monthly Downloads](https://poser.pugx.org/ttn/tea/d/monthly)](https://packagist.org/packages/ttn/tea) +[![TYPO3 V10](https://img.shields.io/badge/TYPO3-10-orange.svg)](https://get.typo3.org/version/10) +[![TYPO3 V11](https://img.shields.io/badge/TYPO3-11-orange.svg)](https://get.typo3.org/version/11) [![GitHub CI status](https://github.com/TYPO3-Documentation/tea/workflows/CI/badge.svg?branch=main)](https://github.com/TYPO3-Documentation/tea/actions) [![GitLab CI status](https://gitlab.typo3.org/qa/example-extension/badges/main/pipeline.svg)](https://gitlab.typo3.org/qa/example-extension/-/pipelines) -[![Latest stable version](https://poser.pugx.org/ttn/tea/v/stable.svg)](https://packagist.org/packages/ttn/tea) -[![TYPO3](https://img.shields.io/badge/TYPO3-10-orange.svg)](https://get.typo3.org/version/10) -[![TYPO3](https://img.shields.io/badge/TYPO3-11-orange.svg)](https://get.typo3.org/version) [![Code Coverage Badge](https://github.com/TYPO3-Documentation/tea/blob/code-coverage-badge/badge.svg)](https://github.com/TYPO3-Documentation/tea/blob/code-coverage-badge/clover.xml) [![Total downloads](https://poser.pugx.org/ttn/tea/downloads.svg)](https://packagist.org/packages/ttn/tea) [![License](https://poser.pugx.org/ttn/tea/license.svg)](https://packagist.org/packages/ttn/tea) [![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.0-4baaaa.svg)](CODE_OF_CONDUCT.md) -## What is this all about? - -This Extbase/Fluid-based TYPO3 extension is an example showcase for best -practices in continuous integration, automated code checks and unit and -functional testing. +This TYPO3 extension, based on Extbase and Fluid, is an example of best +practices in automated code checks, unit/functional/acceptance testing and +continuous integration. You can also use this extension to manage your collection of delicious teas. +| | URL | +|------------------|----------------------------------------------| +| **Repository:** | https://github.com/TYPO3-Documentation/tea | +| **Read online:** | https://docs.typo3.org/p/ttn/tea/main/en-us/ | +| **TER:** | https://extensions.typo3.org/extension/tea/ | + ## Presentation at the TYPO3 Online Days 2021 At the TYPO3 Online Days 2021, [Oliver Klee](https://www.oliverklee.de/) held a @@ -31,209 +37,3 @@ extensions. ### Video recording [![video still](https://img.youtube.com/vi/_oe8ku2GM84/0.jpg)](https://youtu.be/_oe8ku2GM84?t=6983) - -## Extension manual - -The rendered extension manual is available -[on docs.typo3.org](https://docs.typo3.org/p/ttn/tea/master/en-us/). - -## Used testing framework and approach to TYPO3 version support - -Extensions usually needs to support two LTS versions of TYPO3 in parallel -(assuming that they should support all currently supported TYPO3 LTS versions). -To achieve this, there are two different approaches, which also affect the -choice of a testing framework for unit and functional tests: - -### Approach 1: single branch with multi-version support - -With this approach, there is one main branch that gets new features. It needs to -support two TYPO3 LTS versions in parallel. - -The downside is that this slightly increases code complexity (as -version-dependent code switches might be necessary). The upside is that there -is only one branch to maintain, which makes adding new features (and all other -code changes) a lot less of a hassle. - -As the [TYPO3 testing framework](https://github.com/TYPO3/testing-framework) -supports only one TYPO3 LTS version at a time, you will need to use the -[Nimut testing framework](https://github.com/Nimut/testing-framework) instead. -This testing framework can support multiple TYPO3 versions at a time, and -it provides version-independent abstractions for testing. - -(This is the approach that we have chosen for this extension as we do not want -to maintain two branches in parallel.) - -### Approach 2: multiple branches for each TYPO3 version - -With this approach, there is are two main branches that get new features in -parallel. Each branch supports exactly one TYPO3 LTS version. - -The upside is that this slightly decreases code complexity (as -version-dependent code switches are not necessary). The downside is that there -are two branches to maintain, which makes adding new features (and all other -code changes) more of a hassle. - -For this approach, the -[TYPO3 testing framework](https://github.com/TYPO3/testing-framework) (which -supports only one TYPO3 LTS version at a time) will work just fine. - -## Working locally or Docker-based with ddev - -You can run the automated tests and code quality checks either locally (with a -local PHP, Composer and database), or you can use -[ddev](https://github.com/drud/ddev) for a Docker-based setup. - -## Composer, PHIVE, GitHub Actions and GitLab CI - -### Development tools: Composer, PHIVE and dependency hell - -To keep things simple, most development tools (e.g., PHP_CodeSniffer) are -installed as development Composer dependencies. - -For cases where an installation via Composer is not possible, we are using -[PHIVE](https://phar.io/). PHIVE packages each tool with all its dependencies as -a separate PHAR. This helps avoid dependency hell (which means that you cannot -install or upgrade some tool as the tool's dependencies conflict with the -dependencies on another library). It also allows running versions of tools -that require a PHP version that is higher than the lowest allowed PHP version -for this project. - -Currently, this is the case for -[PHP Copy/Paste Detector (PHPCPD)](https://github.com/sebastianbergmann/phpcpd), -which requires PHP >= 7.3, which conflicts with this project's PHP version -support (we also support PHP 7.2). - -### Running the code quality checks locally and in a CI environment - -As an example, this extension provides several redundant ways to run the code -quality checks. (Running the unit and functional tests is a bit different.) -You can copy the corresponding configuration depending on which Git hosting -service and which CI platform you plan to use and whether you would like to run -the code quality checks locally: - -#### GitHub Actions - -This extension has two code-checking workflows for -[GitHub Actions](https://github.com/TYPO3-Documentation/tea/actions): - -- [one that uses the local tools](.github/workflows/ci.yml): - This is the workflow you most probably would want to use: - This workflow uses the development tools installed via Composer and PHIVE and - calls them using the provided Composer scripts. Use this workflow if you want - to run the code quality checks locally as well as in GitHub Actions. - -- [one that completely relies on predefined actions](.github/workflows/predefined.yml): - This workflow does not need the development tools to be installed locally. - Use this workflow if you only want to run the code quality checks in GitHub - Actions, but not locally. - -#### GitLab CI - -This extension also provides [configuration](.gitlab/pipeline/.gitlab-ci.yml) -for [GitLab CI](https://gitlab.typo3.org/qa/example-extension/-/pipelines). - -## Composer scripts - -For most development-related tasks, this extension provides Composer scripts. -If you are working locally, you can run them using `composer `. If -you are working with ddev, you can run them with `ddev composer `. -(You do not need to start or build the containers for this as this happens -automatically.) - -The code-quality-related Composer scripts make use of the PHIVE-installed tools. -This means that for non-ddev-based development, you need to run `phive install` -before you can use the Composer scripts. - -### Available Composer scripts - -You can run `composer` (or `ddev composer`) to display a list of all available -Composer commands and scripts. (For all custom Composer scripts, are descriptions -in the `composer.json` in the `script-description` section.) - -## Running the unit and functional tests - -### On the command line - -To run the unit tests with ddev, use this command: - -```bash -ddev composer ci:tests:unit -``` -To run the functional tests with ddev, use this command: - -```bash -ddev composer ci:tests:functional -``` - -If you are working locally without ddev, omit the `ddev` part. - -### In PhpStorm - -#### General setup for PHPUnit - -File > Settings > PHP > Test Frameworks - -- (*) Use Composer autoloader -- Path to script: select `.Build/vendor/autoload.php` in your project folder - -In the Run configurations, edit the PHPUnit configuration and use these -settings so this configuration can serve as a template: - -- Directory: use the `Tests/Unit` directory in your project -- (*) Use alternative configuration file -- use `.Build/vendor/typo3/testing-framework/Resources/Core/Build/UnitTests.xml` - in your project folder -- add the following environment variables: - - typo3DatabaseUsername - - typo3DatabasePassword - - typo3DatabaseHost - - typo3DatabaseName - -#### Unit tests configuration - -In the Run configurations, copy the PHPUnit configuration and use these -settings: - -- Directory: use the `Tests/Unit` directory in your project - -#### Functional tests configuration - -In the Run configurations, copy the PHPUnit configuration and use these -settings: - -- Directory: use the `Tests/Functional` directory in your project -- (*) Use alternative configuration file -- use - `.Build/vendor/typo3/testing-framework/Resources/Core/Build/FunctionalTests.xml` - -## Running the acceptance tests - -### On the command line - -1. make sure you have Chrome installed on your machine -1. [download the latest version of ChromeDriver](http://chromedriver.chromium.org/downloads) -1. unzip it -1. `chromedriver --url-base=wd/hub` -1. `.Build/vendor/bin/codecept run` (in another terminal) - -### In PhpStorm - -1. make sure the "Codeception Framework" plugin is activated -2. right-click on `Tests/Acceptance/StarterCest.php` -3. Run 'Acceptance (Codeception)' - -## Security - -Libraries and extensions do not need the security check as they should not have -any restrictions concerning the other libraries they are installed alongside -with (unless those would create breakage). Libraries and extension also should -not have a version-controlled `composer.lock` (which usually is used for -security checks). - -Instead, the projects and distributions (i.e., for TYPO3 installations) need to -have the security checks. - -## Rendering the documentation - -After you have cloned the git repository, follow -[the TYPO3 documentation quickstart guide](https://docs.typo3.org/m/typo3/docs-how-to-document/master/en-us/RenderingDocs/Quickstart.html). diff --git a/composer.json b/composer.json index 5dbc408..858e72f 100644 --- a/composer.json +++ b/composer.json @@ -20,9 +20,11 @@ "role": "developer" } ], + "homepage": "https://extensions.typo3.org/extension/tea/", "support": { "issues": "https://github.com/TYPO3-Documentation/tea/issues", - "source": "https://github.com/TYPO3-Documentation/tea" + "source": "https://github.com/TYPO3-Documentation/tea", + "docs": "https://docs.typo3.org/p/ttn/tea/main/en-us/" }, "require": { "php": "~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0 || ~8.1",