From db2d8b6dbd9dd96dd99c7059e993e93356c233d4 Mon Sep 17 00:00:00 2001 From: Webber Takken Date: Thu, 4 Aug 2022 02:09:32 +0200 Subject: [PATCH] fix: make v character in version tags optional (#423) * fix: make v character in version tags optional * fix: cross platform regex * fix: test regex within grep. * fix: add semantic tags prepended with v --- .prettierrc.json | 3 +- CONTRIBUTING.md | 12 ++-- dist/index.js | Bin 21859157 -> 21859369 bytes dist/index.js.map | Bin 16236369 -> 16236623 bytes src/model/__data__/versions.ts | 112 +++++++++++++++++++++++++++++++++ src/model/versioning.test.ts | 21 +++++++ src/model/versioning.ts | 16 +++-- 7 files changed, 154 insertions(+), 10 deletions(-) create mode 100644 src/model/__data__/versions.ts diff --git a/.prettierrc.json b/.prettierrc.json index a4175b70..23de5dff 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -2,5 +2,6 @@ "semi": true, "singleQuote": true, "trailingComma": "all", - "printWidth": 120 + "printWidth": 120, + "proseWrap": "always" } diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c89492c1..669adb1b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,13 +4,12 @@ #### Code of Conduct -This repository has adopted the Contributor Covenant as it's -Code of Conduct. It is expected that participants adhere to it. +This repository has adopted the Contributor Covenant as it's Code of Conduct. It is expected that participants adhere to +it. #### Proposing a Change -If you are unsure about whether or not a change is desired, -you can create an issue. This is useful because it creates +If you are unsure about whether or not a change is desired, you can create an issue. This is useful because it creates the possibility for a discussion that's visible to everyone. When fixing a bug it is fine to submit a pull request right away. @@ -34,6 +33,11 @@ Please note that commit hooks will run automatically to perform some tasks; - run tests - build distributable files +#### Windows users + +Make sure your editor and terminal that run the tests are set to `Powershell 7` or above with +`Git's Unix tools for Windows` installed. Some tests require you to be able to run `sh` and other unix commands. + #### License By contributing to this repository, you agree that your contributions will be licensed under its MIT license. diff --git a/dist/index.js b/dist/index.js index b650f026ef90dc5b39937dc60d065069af691b60..d6aa5db97ba59687ac540f637e16ce562b908cf5 100644 GIT binary patch delta 1738 zcmajf_jeRk7=Yok$s~bC=Y03f{4j@h^vCbo*&n~Y$JP_o z6WynECs_x!L?xuR8+xcZ=nr{JZ;MZ_4TK_Qy>5iP!N6j@UGMDO(2$zuT(P=5b9uh2 zv?-^tF)u6o*fKBMxo1_9w%w6vcIc`#ViIJgBK{WLsB0T|%Hejae5-0FAsH!1#R!bVDADslhk^qWAm?Xb5+=imOk^P&Imm?zd6c^Q6lIu!nQ&tk%29zzRG}KPQG+>{i+QNUd@R619EU}y!|^x)i?IYt zu?+QSz==2sCu2Dp(S#LPiDr1vf>xXY9c^ew2fR2Hr@;q50th06RWJ~Si3nC>4LZ?< z)3Fxo(2X;2Ce~vE&ca6Y;B1_OO*j|l;e2ey1-KAfuoc^I5w@cj7vmD_fQ6m76qn(0 zT!AZb6|TlLxE9ypdfb2;aT9LFE!c%yaT{*O9k>&_aTo5!J-8QrxDWl9xvbk4&p_;gqQIOUd3xTgxB!~-o#sY8}Hy< zyodMk0Y1b>_!ytyQ+$Tc@ddubSNIy=;9Go$@9_hE#9{n|pYaQR#c%i>f8b9X!C&|r z|KMNzx4Ej=wiS{nNwh?h#7JT#agsrj!IF4Mf@FwfsAQOAxFk`MBuSQ}NKz#uBqJrG zBz8%fWVB?AWUOSIWV|F@q9hK<1j$56hGddtvcxILlw?V=B{`B@iA$0vnIg%T6iB8@ z3MEC7fe%q4t7($yl2S>TWQJs>#4VX6DVJ18DkW8tYRPO#jbx5wu4JC1Rx)3*K(f%b KkAI0RrT!={21$?r delta 1544 zcmXBUXLyYV7>Due$Sa6M5=jUmP6&xeh~yj*1Q9z%TYIEtkdhodIihBbV{2`%9a?H{ zV%Kib8ZC;}F0B!(TBAkXe?I)~>$$Gy+w9!fEmI(8V z%?S6)=@J{0m=^@P-eH!54n;M{xuo5J4z`k_bjAltvkZpe#aB4pxMr zJSrd@6;TNhh(u*Xp$eiAgQ}>8SX4(G;$edwHIRUsNJK5vMja%fF6yB^lF=JvyKxI-xVVpexewF}k5UdY~tIp*Pae2Yt~G z8TbVKF#ws!f&&BbDV)fL3xkk@!T1bAFciZu93wCipJNn8V+_W^jd2){37CjUn2afy ziZAdbreQi}U?yf^Hs)Y1Ow7Z4EWko6!eT5zE|y{$zQWg7jurR@E3pczu?B0g4(qW2 z8?gzSu?1VP4cn229oUIo*o{5di+%VO`*8pVaR`TT1V`~5zQ-{f#|iv^A8`_=a2jXu z6Mn{7oWptif(y8aOZXMP;WDn^Dz4!=Zr~<<$1U8(ANUh@a2NM*ANhEIhj@g?c!Iz1 z6o2C%Ji~Lmz)Sp#|L_X0@dp1-$+ugkK`EekD27r{@l*;ag_RmQ{Ek-hNc9irjn@CQfe!8lq99DQctO`Br6S+6s4ikNNKDzQJN~v Rl;%pR(!#QzUt&pW{}yJk;cfr` diff --git a/dist/index.js.map b/dist/index.js.map index 0fd01a8a1010adc8c0f6f6871a3a31dc78409713..f420bac27d77f050bb5e816044850dd3189180ce 100644 GIT binary patch delta 1385 zcmaLSS5#D26vpvIL{YF{Ma0O#I}t<%h{lGFCLt!l2A0?h172Xv%$@PxJ35Fc#soA) zB~g!Q_JT15>nMqesTRtpQDg5lQHkx*m4Eczv-a;{uf5l|*E#a!d`NB4g^=LD2Q(EuT6h(-uS z7#gDqnxYxP(Ht$%60Oi0Z4iOBh(tR?p*>zi2Sh_41|9vyKE;+K!#gRBJLsw>)$Q`w zO-GhfP18JHbCjwZ4!1U3%~gHUzAq-CUF@Xk{o}?bTYFFJGJ%)aIsRFb7%#WPDJ^AD zjnc+{YNImP5^m9)65vk9H&U|6!ISfJRUQIYO zVRt%3`UurX5QdwXDvW&1wEKk1YnUR7RNZYDR*%ze=D2m2jHy+kq*kSv^+wur<;^N3 zGbmH0RV$Y6)&U~cQt*FzV(#;QR~Rd1i5c0#>dch;%c3LXl4>Qd0eOb7$?$*@`7}Ez zz@_rCWx=v?b96`x&Fjii_4J&lYcV#PNS37)(H-T*14H?&yJ@=!M=$K_B#m4gJs`ui`blj#RvX0eBN{;ccX0AO>MD zhF~btk%3_tju9A%cQ6X0F$QBX4&yNa6EO*skqJApkc}x&k%L_1!GWoG7f!gK!3__l zL5BeoUQEXf_>hm8D8MWfVm9WW2y^is=HY#OfMS$jJ{I6Ze1wnj2^L}z7NZoO;xjD4 zQY?eSa(s?2@Fl*&*I0p-ScTPCgSA+P_1J)oD8nXvgU$FB-{E`wfO2fXR&2v|?7&X= zu?xFVfgkY`_Fymep%VM?Gk(FZ_zl0~4;;Wj9KvB#p&B))MF2-|6vyxf>J$U%N{LlH$`AkWb7Un+{7P*EPS)J)(qX@`Lt}0TVgcYn|gSxPV9qi$NdZ-UaG=LKt!WoUw7%pgnrf7!dXaNDPXlc|- zVz6g=wrD4(nnX)uNS5fQbka&fv{onR!ovh9EJhm}q0>qUa(=O>lz$hB4zhoVsFPJ@ z(Oxbu5d#$}*}YU$I>ZI3J-mY5ghU}eRPcyY$;nwQoaKyCG2F^m8x<9yixo7oomupj zeN3XG?f>Sg(FkfeEl2EN-~yCrh1O7^4cfvD?q~-Ow8y`V8XeIIozVrJ=!$OW4lj74 z2YNz-Ug!-U^g&S7YUe$`AEb9EQB6ONX8My za1+HSK`BfqgBiC_j@!6{ySRt@cz}m^gvWS-3RL1Ls_+cY@d7XL3a{}7Z}ATA@c|$4 V37=7oFZhaY_>LdORMXFb>c2nheK-IB diff --git a/src/model/__data__/versions.ts b/src/model/__data__/versions.ts new file mode 100644 index 00000000..56ad4a9c --- /dev/null +++ b/src/model/__data__/versions.ts @@ -0,0 +1,112 @@ +export const completelyValidSemanticVersions = [ + '0.0.4', + '1.2.3', + '10.20.30', + '1.1.2-prerelease+meta', + '1.1.2+meta', + '1.1.2+meta-valid', + '1.0.0-alpha', + '1.0.0-beta', + '1.0.0-alpha.beta', + '1.0.0-alpha.beta.1', + '1.0.0-alpha.1', + '1.0.0-alpha0.valid', + '1.0.0-alpha.0valid', + '1.0.0-alpha-a.b-c-somethinglong+build.1-aef.1-its-okay', + '1.0.0-rc.1+build.1', + '2.0.0-rc.1+build.123', + '1.2.3-beta', + '10.2.3-DEV-SNAPSHOT', + '1.2.3-SNAPSHOT-123', + '1.0.0', + '2.0.0', + '1.1.7', + '2.0.0+build.1848', + '2.0.1-alpha.1227', + '1.0.0-alpha+beta', + '1.2.3----RC-SNAPSHOT.12.9.1--.12+788', + '1.2.3----R-S.12.9.1--.12+meta', + '1.2.3----RC-SNAPSHOT.12.9.1--.12', + '1.0.0+0.build.1-rc.10000aaa-kk-0.1', + '99999999999999999999999.999999999999999999.99999999999999999', + '1.0.0-0A.is.legal', +]; + +export const notCompletelyValidSemanticVersions = [ + '1', + '1.2', + '1.2.3-0123', + '1.2.3-0123.0123', + '1.1.2+.123', + '+invalid', + '-invalid', + '-invalid+invalid', + '-invalid.01', + 'alpha', + 'alpha.beta', + 'alpha.beta.1', + 'alpha.1', + 'alpha+beta', + 'alpha_beta', + 'alpha.', + 'alpha..', + 'beta', + '1.0.0-alpha_beta', + '-alpha.', + '1.0.0-alpha..', + '1.0.0-alpha..1', + '1.0.0-alpha...1', + '1.0.0-alpha....1', + '1.0.0-alpha.....1', + '1.0.0-alpha......1', + '1.0.0-alpha.......1', + '01.1.1', + '1.01.1', + '1.1.01', + '1.2', + '1.2.3.DEV', + '1.2-SNAPSHOT', + '1.2.31.2.3----RC-SNAPSHOT.12.09.1--..12+788', + '1.2-RC-SNAPSHOT', + '-1.0.3-gamma+b7718', + '+justmeta', + '9.8.7+meta+meta', + '9.8.7-whatever+meta+meta', + '99999999999999999999999.999999999999999999.99999999999999999----RC-SNAPSHOT.12.09.1--------------------------------..12', +]; + +const addVariantsPrependingV = (array: string[]) => array.map((tag) => [tag, `v${tag}`]).flat(); + +/** + * Array of versions that will be detected as version tags. Not all of these are + * "semantic versions", but can be used to generate one. Especially using the + * `versioning: Semantic` option. + */ +export const validVersionTagInputs = addVariantsPrependingV([ + '0', + '1', + '0.1', + '1.0', + '1.1.0', + '1.2.3', + ...completelyValidSemanticVersions, +]); + +export const invalidVersionTagInputs = addVariantsPrependingV([ + '+invalid', + '-invalid', + '-invalid+invalid', + '-invalid.01', + 'alpha', + 'alpha.beta', + 'alpha.beta.1', + 'alpha.1', + 'alpha+beta', + 'alpha_beta', + 'alpha.', + 'alpha..', + 'beta', + '-alpha.', + '-1.0.3-gamma+b7718', + '+justmeta', +]); diff --git a/src/model/versioning.test.ts b/src/model/versioning.test.ts index 5cd7f857..0451c74f 100644 --- a/src/model/versioning.test.ts +++ b/src/model/versioning.test.ts @@ -2,6 +2,7 @@ import * as core from '@actions/core'; import NotImplementedException from './error/not-implemented-exception'; import System from './system'; import Versioning from './versioning'; +import { validVersionTagInputs, invalidVersionTagInputs } from './__data__/versions'; afterEach(() => { jest.restoreAllMocks(); @@ -34,6 +35,26 @@ describe('Versioning', () => { }); }); + describe('grepCompatibleInputVersionRegex', () => { + // eslint-disable-next-line unicorn/consistent-function-scoping + const matchInputUsingGrep = async (input) => { + const output = await System.run('sh', undefined, { + input: Buffer.from(`echo '${input}' | grep -E '${Versioning.grepCompatibleInputVersionRegex}'`), + silent: true, + }); + + return output.trim(); + }; + + it.concurrent.each(validVersionTagInputs)(`accepts valid tag input '%s'`, async (input) => { + expect(await matchInputUsingGrep(input)).toStrictEqual(input); + }); + + it.concurrent.each(invalidVersionTagInputs)(`rejects non-version tag input '%s'`, async (input) => { + await expect(async () => matchInputUsingGrep(input)).rejects.toThrowError(/^Failed to run/); + }); + }); + describe('branch', () => { it('returns headRef when set', () => { const headReference = jest.spyOn(Versioning, 'headRef', 'get').mockReturnValue('feature-branch-1'); diff --git a/src/model/versioning.ts b/src/model/versioning.ts index a4f858b6..7ef0ca47 100644 --- a/src/model/versioning.ts +++ b/src/model/versioning.ts @@ -17,6 +17,10 @@ export default class Versioning { return { None: 'None', Semantic: 'Semantic', Tag: 'Tag', Custom: 'Custom' }; } + static get grepCompatibleInputVersionRegex() { + return '^v?([0-9]+\\.)*[0-9]+.*'; + } + /** * Get the branch name of the (related) branch */ @@ -272,18 +276,20 @@ export default class Versioning { } /** - * Whether or not the repository has any version tags yet. + * Whether the current tree has any version tags yet. + * + * Note: Currently this is run in all OSes, so the syntax must be cross-platform. */ static async hasAnyVersionTags() { - const numberOfCommitsAsString = await System.run('sh', undefined, { - input: Buffer.from('git tag --list --merged HEAD | grep v[0-9]* | wc -l'), + const numberOfTagsAsString = await System.run('sh', undefined, { + input: Buffer.from(`git tag --list --merged HEAD | grep -E '${this.grepCompatibleInputVersionRegex}' | wc -l`), cwd: this.projectPath, silent: false, }); - const numberOfCommits = Number.parseInt(numberOfCommitsAsString, 10); + const numberOfTags = Number.parseInt(numberOfTagsAsString, 10); - return numberOfCommits !== 0; + return numberOfTags !== 0; } /**