diff --git a/.github/workflows/regression-tests.yml b/.github/workflows/regression-tests.yml new file mode 100644 index 00000000..fcdcb426 --- /dev/null +++ b/.github/workflows/regression-tests.yml @@ -0,0 +1,64 @@ +name: 🦄 Regression Tests + +on: + workflow_dispatch: + inputs: + version: + type: string + description: Terrabuild version + default: latest + prerelease: + type: boolean + description: use Terrabuild prerelease + default: false + +jobs: + + regression-test: + runs-on: ubuntu-latest + + permissions: + contents: read + packages: write + + steps: + - name: Cloning repository + uses: actions/checkout@v4 + + - name: Install Terrabuild + uses: magnusopera/action-install-gh-release@feature/prerelease + with: + repo: magnusopera/terrabuild + tag: ${{ inputs.version }} + prerelease: ${{ inputs.prerelease }} + + - name: Info + run: | + echo 'Regression tests for ${{ github.ref }}' + terrabuild version + + - name: Self Integration Tests + run: make self-test-all terrabuild=terrabuild + + - name: Include Build Logs + if: always() + run: | + ls -alR > terrabuild-debug.files.txt + + echo "# Self Tests" >> $GITHUB_STEP_SUMMARY + echo "## simple" >> $GITHUB_STEP_SUMMARY + cat tests/simple/terrabuild-debug.md >> $GITHUB_STEP_SUMMARY + + echo "## multirefs" >> $GITHUB_STEP_SUMMARY + cat tests/multirefs/terrabuild-debug.md >> $GITHUB_STEP_SUMMARY + + echo "## cluster-layers" >> $GITHUB_STEP_SUMMARY + cat tests/cluster-layers/terrabuild-debug.md >> $GITHUB_STEP_SUMMARY + + - name: Upload Terrabuild Debug + if: always() + uses: actions/upload-artifact@v4 + with: + name: Terrabuild Debug + path: | + **/terrabuild-debug.* diff --git a/Makefile b/Makefile index c2e985f6..e01c7cca 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,6 @@ config ?= default env ?= default +terrabuild = $(current_dir)/.out/dotnet/terrabuild version ?= 0.0.0 @@ -12,6 +13,10 @@ endif current_dir = $(shell pwd) + + + + # # _______ ___________ ____ # | \ | ____\ \ / / @@ -74,7 +79,7 @@ docs: dotnet run --project tools/DocGen -- src/Terrabuild.Extensions/bin/$(buildconfig)/net9.0/Terrabuild.Extensions.xml ../../websites/terrabuild.io/content/docs/extensions self: clean publish - .out/dotnet/terrabuild run build test dist --configuration $(env) --retry --debug --logs --local-only + $(terrabuild) run build test dist --configuration $(env) --retry --debug --logs --local-only terrabuild: terrabuild run build test dist --configuration $(env) --retry --debug --logs --local-only @@ -145,8 +150,9 @@ endef define run_integration_test @printf "\n*** Running integration test %s ***\n" $(1) + @$(terrabuild) version -cd $(1); rm terrabuild-debug.* - cd $(1); GITHUB_SHA=1234 GITHUB_REF_NAME=main GITHUB_STEP_SUMMARY=terrabuild-debug.md GITHUB_REPOSITORY=magnusopera/terrabuild GITHUB_RUN_ID=42 $(current_dir)/.out/dotnet/terrabuild $(2) + cd $(1); GITHUB_SHA=1234 GITHUB_REF_NAME=main GITHUB_STEP_SUMMARY=terrabuild-debug.md GITHUB_REPOSITORY=magnusopera/terrabuild GITHUB_RUN_ID=42 $(terrabuild) $(2) $(call diff_results,$(1)) endef @@ -161,4 +167,4 @@ self-test-multirefs: self-test-simple: $(call run_integration_test, tests/simple, run build --force --debug -p 2 --logs --container-tool docker) -self-test-all: publish self-test-cluster-layers self-test-multirefs self-test-simple +self-test-all: self-test-cluster-layers self-test-multirefs self-test-simple diff --git a/tests/simple/WORKSPACE b/tests/simple/WORKSPACE index b0ff8771..4e6d1634 100644 --- a/tests/simple/WORKSPACE +++ b/tests/simple/WORKSPACE @@ -53,3 +53,8 @@ extension @terraform { extension @cargo { container = "rust:1.81.0-slim" } + +extension npmext { + container = "node:20" + script = "/scripts/npm.fsx" +} diff --git a/tests/simple/libraries/npm-lib/PROJECT b/tests/simple/libraries/npm-lib/PROJECT index 4a43e2bc..b1e24ddf 100644 --- a/tests/simple/libraries/npm-lib/PROJECT +++ b/tests/simple/libraries/npm-lib/PROJECT @@ -1,14 +1,8 @@ -extension @npm { - container = "node:20" -# script = "../../scripts/npm.fsx" -} - - -project @npm { +project npmext { labels = [ "app" ] } target build { - @npm build { } + npmext build { } } diff --git a/tests/simple/projects/npm-app/PROJECT b/tests/simple/projects/npm-app/PROJECT index 4a43e2bc..b1e24ddf 100644 --- a/tests/simple/projects/npm-app/PROJECT +++ b/tests/simple/projects/npm-app/PROJECT @@ -1,14 +1,8 @@ -extension @npm { - container = "node:20" -# script = "../../scripts/npm.fsx" -} - - -project @npm { +project npmext { labels = [ "app" ] } target build { - @npm build { } + npmext build { } } diff --git a/tests/simple/results/terrabuild-debug.build-graph.json b/tests/simple/results/terrabuild-debug.build-graph.json index 19066691..844546df 100644 --- a/tests/simple/results/terrabuild-debug.build-graph.json +++ b/tests/simple/results/terrabuild-debug.build-graph.json @@ -55,7 +55,7 @@ "*.planfile" ], "projectHash": "9FA318E272735D841D292D7D78A58E7AF5BDFAF96DDD745761807419308C8BC5", - "targetHash": "CAB8238674448CA93042A09B3DE76E889B8BA13023DBD9111FE7E8FBB488115B", + "targetHash": "5FECAE3D3D34E9893748175B100279E8FDED03C090FA30A352C9A5C1CFBFBA6C", "operations": [ { "container": null, @@ -150,7 +150,7 @@ "project": "libraries/npm-lib", "target": "build", "configurationTarget": { - "hash": "3E35FE4CDBC58941D9C1FD7D9ACAC561D8397441268E863F8BFDD72EC9AE1E1A", + "hash": "6FF9DA1627A7C747024ACB388F9EDE0C888DB6279C1741C21CE10925AC7B8271", "rebuild": false, "dependsOn": [ "^build" @@ -160,10 +160,10 @@ ], "operations": [ { - "hash": "8020766CA6489DE8B88803B5BE7CBC336B9BB27FEE455F2AA4A96306A85EB557", - "container": null, + "hash": "D9D320BB6A8CAFCC2A18FEC98A30C89D0D1526D887C5A7626CBF0E8E066A4AE0", + "container": "node:20", "containerVariables": [], - "extension": "@npm", + "extension": "npmext", "command": "build", "script": {}, "context": [ @@ -178,19 +178,19 @@ "dist/" ], "projectHash": "813635EFA9D98FB042EF8A761A4433B34B95BA40E1D1231B79CBDC4D29E21AF6", - "targetHash": "C31CA645B9EA52F50397213F7C65C115C26B08B5A924760E5EE1813AF2133B3B", + "targetHash": "DFB9E748B9E41C783059F0629CBE81D0348FBA319600D20BA0496D318CC9A031", "operations": [ { - "container": null, + "container": "node:20", "containerVariables": [], - "metaCommand": "@npm build", + "metaCommand": "npmext build", "command": "npm", "arguments": "ci" }, { - "container": null, + "container": "node:20", "containerVariables": [], - "metaCommand": "@npm build", + "metaCommand": "npmext build", "command": "npm", "arguments": "run build -- " } @@ -399,7 +399,7 @@ "project": "projects/npm-app", "target": "build", "configurationTarget": { - "hash": "3E35FE4CDBC58941D9C1FD7D9ACAC561D8397441268E863F8BFDD72EC9AE1E1A", + "hash": "6FF9DA1627A7C747024ACB388F9EDE0C888DB6279C1741C21CE10925AC7B8271", "rebuild": false, "dependsOn": [ "^build" @@ -409,10 +409,10 @@ ], "operations": [ { - "hash": "8020766CA6489DE8B88803B5BE7CBC336B9BB27FEE455F2AA4A96306A85EB557", - "container": null, + "hash": "D9D320BB6A8CAFCC2A18FEC98A30C89D0D1526D887C5A7626CBF0E8E066A4AE0", + "container": "node:20", "containerVariables": [], - "extension": "@npm", + "extension": "npmext", "command": "build", "script": {}, "context": [ @@ -429,19 +429,19 @@ "dist/" ], "projectHash": "84DFD1B132F2D433231EF2345DB2CF32D7D3867BB5C1795B3DCFE0F0304A7353", - "targetHash": "50DE791CFFFCD69DA1BFBA9A902EAC469C094EABD0C1FD299BA58978C79FC0B7", + "targetHash": "504FCB25A46AC48E00ACBCE1E7B526B375192991C331D7F898AF6AEDBB678141", "operations": [ { - "container": null, + "container": "node:20", "containerVariables": [], - "metaCommand": "@npm build", + "metaCommand": "npmext build", "command": "npm", "arguments": "ci" }, { - "container": null, + "container": "node:20", "containerVariables": [], - "metaCommand": "@npm build", + "metaCommand": "npmext build", "command": "npm", "arguments": "run build -- " } diff --git a/tests/simple/results/terrabuild-debug.config.json b/tests/simple/results/terrabuild-debug.config.json index 03f59514..bdfad65a 100644 --- a/tests/simple/results/terrabuild-debug.config.json +++ b/tests/simple/results/terrabuild-debug.config.json @@ -208,7 +208,7 @@ ], "targets": { "build": { - "hash": "3E35FE4CDBC58941D9C1FD7D9ACAC561D8397441268E863F8BFDD72EC9AE1E1A", + "hash": "6FF9DA1627A7C747024ACB388F9EDE0C888DB6279C1741C21CE10925AC7B8271", "rebuild": false, "dependsOn": [ "^build" @@ -218,10 +218,10 @@ ], "operations": [ { - "hash": "8020766CA6489DE8B88803B5BE7CBC336B9BB27FEE455F2AA4A96306A85EB557", - "container": null, + "hash": "D9D320BB6A8CAFCC2A18FEC98A30C89D0D1526D887C5A7626CBF0E8E066A4AE0", + "container": "node:20", "containerVariables": [], - "extension": "@npm", + "extension": "npmext", "command": "build", "script": {}, "context": [ @@ -489,7 +489,7 @@ ], "targets": { "build": { - "hash": "3E35FE4CDBC58941D9C1FD7D9ACAC561D8397441268E863F8BFDD72EC9AE1E1A", + "hash": "6FF9DA1627A7C747024ACB388F9EDE0C888DB6279C1741C21CE10925AC7B8271", "rebuild": false, "dependsOn": [ "^build" @@ -499,10 +499,10 @@ ], "operations": [ { - "hash": "8020766CA6489DE8B88803B5BE7CBC336B9BB27FEE455F2AA4A96306A85EB557", - "container": null, + "hash": "D9D320BB6A8CAFCC2A18FEC98A30C89D0D1526D887C5A7626CBF0E8E066A4AE0", + "container": "node:20", "containerVariables": [], - "extension": "@npm", + "extension": "npmext", "command": "build", "script": {}, "context": [ diff --git a/tests/simple/scripts/npm.fsx b/tests/simple/scripts/npm.fsx index d7170c1e..ba5d136c 100644 --- a/tests/simple/scripts/npm.fsx +++ b/tests/simple/scripts/npm.fsx @@ -1,35 +1,115 @@ #if !TERRABUILD_SCRIPT -#r "../../../src/Terrabuild/bin/Debug/net8.0/Terrabuild.Extensibility.dll" +#r "../../../src/Terrabuild/bin/Debug/net9.0/Terrabuild.Extensibility.dll" #endif open Terrabuild.Extensibility -let __defaults__() = +module String = + open System.Text.RegularExpressions + + let (|Regex|_|) pattern input = + let m = Regex.Match(input, pattern) + if m.Success then Some(List.tail [ for g in m.Groups -> g.Value ]) + else None + + +module NpmHelpers = + open System.Text.Json.Serialization + open System.Text.Json + open System.Collections.Generic + + [] + type Package = { + [] + Dependencies: Dictionary + + [] + DevDependencies: Dictionary + } + + let findProjectFile (directory: string) = + let projects = + System.IO.Directory.EnumerateFiles(directory, "package.json") + |> List.ofSeq + match projects with + | [ project ] -> project + | [] -> failwith "No project found" + | _ -> failwith "Multiple projects found" + + let findDependencies (projectFile: string) = + let json = System.IO.File.ReadAllText projectFile + let package = JsonSerializer.Deserialize(json) + + let dependencies = seq { + if package.Dependencies|> isNull |> not then + for (KeyValue(_, value)) in package.Dependencies do + match value with + | String.Regex "^file:(.*)$" [project] -> yield project + | _ -> () + + if package.DevDependencies|> isNull |> not then + for (KeyValue(_, value)) in package.DevDependencies do + match value with + | String.Regex "^file:(.*)$" [project] -> yield project + | _ -> () + } + Set dependencies + + + + + +let __defaults__ (context: ExtensionContext) = + let projectFile = NpmHelpers.findProjectFile context.Directory + let dependencies = projectFile |> NpmHelpers.findDependencies let projectInfo = - { ProjectInfo.Default - with Ignores = Set [ "node_modules/" ] - Outputs = Set [ "dist/" ] } + { ProjectInfo.Default with + Ignores = Set [ "node_modules/" ] + Outputs = Set [ "dist/" ] + Dependencies = dependencies } projectInfo -let install () = - let ops = All [ shellOp "npm" "ci" ] - execRequest Cacheability.Always [] ops -let build (arguments: string option) = +let __dispatch__ (context: ActionContext) (arguments: string option) = + let cmd = context.Command + let arguments = arguments |> Option.defaultValue "" + + let ops = [ + shellOp "npm" "ci" + shellOp "npm" $"run {cmd} -- {arguments}" + ] + execRequest Cacheability.Always ops + + +let install (context: ActionContext) = + let ops = [ shellOp "npm" "ci" ] + execRequest Cacheability.Always ops + + +let build (context: ActionContext) (arguments: string option) = let args = arguments |> Option.defaultValue "" - let ops = All [ + let ops = [ shellOp "npm" "ci" - shellOp "npm" $"run build -- {args}" + shellOp "npm" $"run build -- {args}" ] - execRequest Cacheability.Always [] ops + execRequest Cacheability.Always ops + -let test (arguments: string option) = +let test (context: ActionContext) (arguments: string option) = let args = arguments |> Option.defaultValue "" - let ops = All [ + let ops = [ shellOp "npm" "ci" - shellOp "npm" $"run test -- {args}" + shellOp "npm" $"run test -- {args}" + ] + execRequest Cacheability.Always ops + +let run (context: ActionContext) (command: string) (arguments: string option) = + let args = arguments |> Option.defaultValue "" + + let ops = [ + shellOp "npm" $"run {command} -- {args}" ] - execRequest Cacheability.Always [] ops + execRequest Cacheability.Always ops