diff --git a/.github/process-release-notes.elv b/.github/process-release-notes.elv new file mode 100644 index 000000000..0473e6e95 --- /dev/null +++ b/.github/process-release-notes.elv @@ -0,0 +1,22 @@ +use str +use github.com/giancosta86/aurora-elvish/edit + +var notes-file = $args[0] + +{ + tmp pwd = actions + + edit:file $notes-file { |content| + var actual-content = $content + + put * | each { |action-name| + var tick-quoted-name = '`'$action-name'`' + + var markdown-link = '['$action-name'](actions/'$action-name'/README.md)' + + set actual-content = (str:replace $tick-quoted-name $markdown-link $actual-content) + } + + put $actual-content + } +} \ No newline at end of file diff --git a/.github/process-release-notes.sh b/.github/process-release-notes.sh deleted file mode 100644 index b4fef5f99..000000000 --- a/.github/process-release-notes.sh +++ /dev/null @@ -1,8 +0,0 @@ -notesFile="$1" - -for actionFolder in actions/* -do - action="$(basename "$actionFolder")" - - sed -i "s/\`$action\`/[$action](actions\/$action\/README.md)/" "$notesFile" -done \ No newline at end of file diff --git a/.github/test-actions/test-check-project-license/action.yml b/.github/test-actions/test-check-project-license/action.yml index f744bd247..83cd498f6 100644 --- a/.github/test-actions/test-check-project-license/action.yml +++ b/.github/test-actions/test-check-project-license/action.yml @@ -1,10 +1,10 @@ -name: Test check-rust-versions +name: Test check-project-license runs: using: composite steps: - shell: bash - run: echo "🎭Checking project license..." + run: echo "🎭 Checking project license..." - name: Check project license uses: ./actions/check-project-license diff --git a/.github/test-actions/test-check-rust-versions/action.yml b/.github/test-actions/test-check-rust-versions/action.yml deleted file mode 100644 index bd5057b9c..000000000 --- a/.github/test-actions/test-check-rust-versions/action.yml +++ /dev/null @@ -1,20 +0,0 @@ -name: Test check-rust-versions - -runs: - using: composite - steps: - - shell: bash - run: echo "🎭Testing on Rust crate..." - - - name: Checking Rust versions for Rust crate should work - uses: ./actions/check-rust-versions - with: - project-directory: tests/rust-crate - - - shell: bash - run: echo "🎭Testing on Rust Wasm..." - - - name: Checking Rust versions for Rust web assembly should work - uses: ./actions/check-rust-versions - with: - project-directory: tests/rust-wasm diff --git a/.github/test-actions/test-check-subpath-exports/action.yml b/.github/test-actions/test-check-subpath-exports/action.yml index 793dc4ad6..cad6cf9d7 100644 --- a/.github/test-actions/test-check-subpath-exports/action.yml +++ b/.github/test-actions/test-check-subpath-exports/action.yml @@ -3,54 +3,54 @@ name: Test check-subpath-exports runs: using: composite steps: - - name: When the "exports" field is missing - uses: ./.github/test-actions/test-check-subpath-exports/scenario + - uses: ./.github/test-actions/test-check-subpath-exports/scenario with: + header: Test when the "exports" field is missing... jq-operation: del(.exports) - - name: When the "exports" field is present but empty - uses: ./.github/test-actions/test-check-subpath-exports/scenario + - uses: ./.github/test-actions/test-check-subpath-exports/scenario with: + header: Test when the "exports" field is present but empty... jq-operation: .exports={} - - name: When the "exports" field is a string - uses: ./.github/test-actions/test-check-subpath-exports/scenario + - uses: ./.github/test-actions/test-check-subpath-exports/scenario with: + header: Test when the "exports" field is a string... jq-operation: .exports="./src/beta/index.js" - - name: When the "exports" field contains a string field - uses: ./.github/test-actions/test-check-subpath-exports/scenario + - uses: ./.github/test-actions/test-check-subpath-exports/scenario with: + header: Test when the "exports" object contains a string field... jq-operation: | .exports={ "beta": "./src/beta/index.js" } - - name: When the "exports" field contains an object field - uses: ./.github/test-actions/test-check-subpath-exports/scenario + - uses: ./.github/test-actions/test-check-subpath-exports/scenario with: + header: Test when the "exports" object contains an object field... jq-operation: | .exports={ "beta": { - "import": "./src/beta/index.js", + "import": "./src/beta/index.d.ts", "default": "./src/beta/index.js" } } - - name: When the "exports" field contains multiple fields - uses: ./.github/test-actions/test-check-subpath-exports/scenario + - uses: ./.github/test-actions/test-check-subpath-exports/scenario with: + header: Test when the "exports" object contains multiple fields... jq-operation: | .exports={ "alpha": { - "import": "./src/alpha/index.ts", - "default": "./src/alpha/index.ts" + "types": "./src/alpha/index.d.ts", + "default": "./src/alpha/index.js" }, "beta": { - "import": "./src/beta/index.js", + "types": "./src/beta/index.d.ts", "default": "./src/beta/index.js" }, - "omega": "./src/omega/index.ts" + "omega": "./src/omega/index.js" } diff --git a/.github/test-actions/test-check-subpath-exports/scenario/action.yml b/.github/test-actions/test-check-subpath-exports/scenario/action.yml index f192551a4..ce1100b77 100644 --- a/.github/test-actions/test-check-subpath-exports/scenario/action.yml +++ b/.github/test-actions/test-check-subpath-exports/scenario/action.yml @@ -1,12 +1,18 @@ name: Update and check subpath exports in the npm test project inputs: + header: + description: Header for this scenario. + jq-operation: - description: The operation altering the package.json descriptor + description: The jq operation altering the package.json descriptor. runs: using: composite steps: + - shell: bash + run: echo "🎭 ${{inputs.header}}" + - name: Run the requested jq operation on package.json shell: bash working-directory: tests/npm-package @@ -14,7 +20,7 @@ runs: jq '${{ inputs.jq-operation }}' package.json > package.json.temp mv package.json.temp package.json - echo "🔎The 'exports' field is:" + echo "🔎 The 'exports' field is:" jq -C '.exports' package.json - uses: ./actions/check-subpath-exports diff --git a/.github/test-actions/test-detect-branch-version/action.yml b/.github/test-actions/test-detect-branch-version/action.yml index dbb098b95..65b9a47f7 100644 --- a/.github/test-actions/test-detect-branch-version/action.yml +++ b/.github/test-actions/test-detect-branch-version/action.yml @@ -13,25 +13,9 @@ runs: if [[ -n "$branch" ]] then - echo "🌲Branch retrieved from action: '$branch'" + echo "✅ Branch retrieved from action: '$branch'" else - echo "❌The branch could not be detected!" >&2 - exit 1 - fi - - - name: The detected branch should be the one starting the pull request for this test - shell: bash - run: | - headRef="${{ github.head_ref }}" - branch="${{ steps.detector.outputs.branch }}" - - echo "🌲Head ref in pull request: '$headRef'" - - if [[ "$branch" == "$headRef" ]] - then - echo "✅The detected branch coincides with the head ref!" - else - echo "❌The branch ('$branch') should match the head_ref ('$headRef')!" >&2 + echo "❌ The branch could not be detected!" >&2 exit 1 fi @@ -42,9 +26,9 @@ runs: if [[ -n "$version" ]] then - echo "🔎Version retrieved from action: '$version'" + echo "✅ Version retrieved from action: '$version'" else - echo "❌The version could not be detected!" >&2 + echo "❌ The version could not be detected!" >&2 exit 1 fi @@ -53,13 +37,13 @@ runs: run: | escapedVersion="${{ steps.detector.outputs.escaped-version }}" - echo "🔎Escaped version retrieved from action: '$escapedVersion'" + echo "🔎 Escaped version retrieved from action: '$escapedVersion'" if echo "$escapedVersion" | grep -Pq "\\\." then - echo "✅The escaped version contains '\.', as expected!" + echo "✅ The escaped version contains '\.', as expected!" else - echo "❌The escaped version should include '\.'!" >&2 + echo "❌ The escaped version should include '\.'!" >&2 exit 1 fi @@ -70,8 +54,13 @@ runs: if [[ -n "$major" ]] then - echo "🪩Major version component: '$major'" + echo "✅ Major version component: '$major'" else - echo "❌The major component could not be detected!" >&2 + echo "❌ The major component could not be detected!" >&2 exit 1 fi + + - name: Display completion message + shell: bash + run: | + echo '✅ All tests successful!' diff --git a/.github/test-actions/test-enforce-branch-version/action.yml b/.github/test-actions/test-enforce-branch-version/action.yml index 5a232c9e7..3826f965a 100644 --- a/.github/test-actions/test-enforce-branch-version/action.yml +++ b/.github/test-actions/test-enforce-branch-version/action.yml @@ -3,143 +3,69 @@ name: Test enforce-branch-version runs: using: composite steps: + - uses: ./actions/detect-branch-version + id: version-detector + - shell: bash - run: echo "🎭Testing 'skip' mode..." + run: echo "🎭 Testing 'skip' mode..." - uses: ./actions/enforce-branch-version with: mode: skip project-directory: tests/rust-crate - - shell: bash - run: echo "🎭Testing 'inject' mode for 📦NodeJS package..." - - - uses: ./actions/enforce-branch-version + - uses: ./.github/test-actions/test-enforce-branch-version/scenario with: - mode: inject + project-type: 📦 NodeJS package project-directory: tests/npm-package + artifact-descriptor: package.json + expected-version: ${{ steps.version-detector.outputs.version }} - - shell: bash - run: echo "🎭Testing 'inject' mode for 🦀Rust crate..." - - - uses: ./actions/enforce-branch-version + - uses: ./.github/test-actions/test-enforce-branch-version/scenario with: - mode: inject + project-type: 🦀 Rust crate project-directory: tests/rust-crate + artifact-descriptor: Cargo.toml + expected-version: ${{ steps.version-detector.outputs.version }} - - shell: bash - run: echo "🎭Testing 'inject' mode for 🦀Rust 🌐WebAssembly..." - - - uses: ./actions/enforce-branch-version + - uses: ./.github/test-actions/test-enforce-branch-version/scenario with: - mode: inject + project-type: 🦀🌐 Rust WebAssembly project-directory: tests/rust-wasm + artifact-descriptor: Cargo.toml + expected-version: ${{ steps.version-detector.outputs.version }} - - shell: bash - run: echo "🎭Testing 'inject' mode for 🪶Maven project..." - - - uses: ./actions/enforce-branch-version + - uses: ./.github/test-actions/test-enforce-branch-version/scenario with: - mode: inject + project-type: 🪶 Maven project project-directory: tests/maven-project + artifact-descriptor: pom.xml + expected-version: ${{ steps.version-detector.outputs.version }} - - shell: bash - run: echo "🎭Testing 'inject' mode for 🐘Gradle project..." - - - uses: ./actions/enforce-branch-version + - uses: ./.github/test-actions/test-enforce-branch-version/scenario with: - mode: inject + project-type: 🐘 Gradle project project-directory: tests/gradle-project + artifact-descriptor: build.gradle.kts + expected-version: ${{ steps.version-detector.outputs.version }} - - shell: bash - run: echo "🎭Testing 'inject' mode for 🐍Python library..." - - - uses: ./actions/enforce-branch-version + - uses: ./.github/test-actions/test-enforce-branch-version/scenario with: - mode: inject + project-type: 🐍 Python library project-directory: tests/python-lib + artifact-descriptor: pyproject.toml + expected-version: ${{ steps.version-detector.outputs.version }} - - shell: bash - run: echo "🎭Testing 'inject' mode for 🎁unknown tech stack..." - - - uses: ./actions/enforce-branch-version + - uses: ./.github/test-actions/test-enforce-branch-version/scenario with: - mode: inject - artifact-descriptor: some-descriptor.txt + project-type: 🎁 unknown tech stack project-directory: tests/unknown-tech - - - shell: bash - run: echo "🎭Testing 'check' mode for 📦NodeJS package..." - - - uses: ./actions/enforce-branch-version - with: - mode: check - project-directory: tests/npm-package - - - shell: bash - run: echo "🎭Testing 'check' mode for 🦀Rust crate..." - - - uses: ./actions/enforce-branch-version - with: - mode: check - project-directory: tests/rust-crate - - - shell: bash - run: echo "🎭Testing 'check' mode for 🦀Rust 🌐WebAssembly..." - - - uses: ./actions/enforce-branch-version - with: - mode: check - project-directory: tests/rust-wasm - - - shell: bash - run: echo "🎭Testing 'check' mode for 🪶Maven project..." - - - uses: ./actions/enforce-branch-version - with: - mode: check - project-directory: tests/maven-project - - - shell: bash - run: echo "🎭Testing 'check' mode for 🐘Gradle project..." - - - uses: ./actions/enforce-branch-version - with: - mode: check - project-directory: tests/gradle-project - - - shell: bash - run: echo "🎭Testing 'check' mode for 🐍Python library..." - - - uses: ./actions/enforce-branch-version - with: - mode: check - project-directory: tests/python-lib - - - shell: bash - run: echo "🎭Testing 'check' mode for 🎁unknown tech stack..." - - - name: Check version for unknown tech - uses: ./actions/enforce-branch-version - with: - mode: check artifact-descriptor: some-descriptor.txt - project-directory: tests/unknown-tech - - - shell: bash - run: echo "🎭Now testing the NodeJS package scenario, passing an explicit descriptor..." - - - uses: ./actions/enforce-branch-version - with: - mode: check - artifact-descriptor: package.json - project-directory: tests/npm-package - - - uses: ./actions/detect-branch-version - id: version-detector + expected-version: ${{ steps.version-detector.outputs.version }} + can-infer-descriptor: false - shell: bash - run: echo "🎭Verifying that the version has been injected multiple times..." + run: echo "🎭 Verifying that the version has been injected multiple times..." - shell: bash working-directory: tests/unknown-tech @@ -148,8 +74,8 @@ runs: if grep "A: v$version" some-descriptor.txt && grep "B: '$version'" some-descriptor.txt then - echo "✅The version was injected multiple times into the 🎁unknown tech descriptor!" + echo "✅ The version was injected multiple times into the 🎁 unknown tech descriptor!" else - echo "❌The version was not injected multiple times into the 🎁unknown tech descriptor!" >&2 + echo "❌ The version was not injected multiple times into the 🎁 unknown tech descriptor!" >&2 exit 1 fi diff --git a/.github/test-actions/test-enforce-branch-version/scenario/action.yml b/.github/test-actions/test-enforce-branch-version/scenario/action.yml new file mode 100644 index 000000000..d5cf44300 --- /dev/null +++ b/.github/test-actions/test-enforce-branch-version/scenario/action.yml @@ -0,0 +1,95 @@ +name: Run a project-specific scenario for enforce-branch-version + +inputs: + project-type: + description: A brief description of the project. + + project-directory: + description: The project directory. + + artifact-descriptor: + description: The descriptor file name - relative to the project directory. + + expected-version: + description: The expected version after injection. + + can-infer-descriptor: + description: Whether the descriptor can be inferred from the directory. + default: true + +runs: + using: composite + steps: + - shell: bash + run: | + header() { + local text="$1" + + local line + line="$(printf '=%.0s' $(seq 1 "${#text}"))" + + echo -e "$line\n$text\n$line" >&2 + } + + header "${{ inputs.project-type }}" + + - name: Backup the descriptor in preparation for multiple tests + if: inputs.can-infer-descriptor == 'true' + shell: bash + working-directory: ${{ inputs.project-directory }} + run: cp "${{ inputs.artifact-descriptor }}" "${{ inputs.artifact-descriptor }}.orig" + + - shell: bash + run: echo "🎭 Testing 'inject' mode (with declared descriptor)..." + + - uses: ./actions/enforce-branch-version + with: + mode: inject + project-directory: ${{ inputs.project-directory }} + artifact-descriptor: ${{ inputs.artifact-descriptor }} + + - shell: bash + run: | + grep --color=always -F -Hn '${{ inputs.expected-version }}' ${{ inputs.project-directory }}/${{ inputs.artifact-descriptor }} + echo '✅ Grep found the expected version!' + + - name: Restore the original descriptor + if: inputs.can-infer-descriptor == 'true' + shell: bash + working-directory: ${{ inputs.project-directory }} + run: cp "${{ inputs.artifact-descriptor }}.orig" "${{ inputs.artifact-descriptor }}" + + - shell: bash + if: inputs.can-infer-descriptor == 'true' + run: echo "🎭 Testing 'inject' mode (with inferred descriptor)..." + + - uses: ./actions/enforce-branch-version + if: inputs.can-infer-descriptor == 'true' + with: + mode: inject + project-directory: ${{ inputs.project-directory }} + + - shell: bash + if: inputs.can-infer-descriptor == 'true' + run: | + grep --color=always -F -Hn '${{ inputs.expected-version }}' ${{ inputs.project-directory }}/${{ inputs.artifact-descriptor }} + echo '✅ Grep found the expected version!' + + - shell: bash + run: echo "🎭 Testing 'check' mode (with declared descriptor)..." + + - uses: ./actions/enforce-branch-version + with: + mode: check + project-directory: ${{ inputs.project-directory }} + artifact-descriptor: ${{ inputs.artifact-descriptor }} + + - shell: bash + if: inputs.can-infer-descriptor == 'true' + run: echo "🎭 Testing 'check' mode (with inferred descriptor)..." + + - uses: ./actions/enforce-branch-version + if: inputs.can-infer-descriptor == 'true' + with: + mode: check + project-directory: ${{ inputs.project-directory }} diff --git a/.github/test-actions/test-extract-rust-snippets/action.yml b/.github/test-actions/test-extract-rust-snippets/action.yml index 90cd15e48..52de15e86 100644 --- a/.github/test-actions/test-extract-rust-snippets/action.yml +++ b/.github/test-actions/test-extract-rust-snippets/action.yml @@ -4,7 +4,7 @@ runs: using: composite steps: - shell: bash - run: echo "🎭Trying to generate test files from Markdown file without snippets..." + run: echo "🎭 Trying to generate test files from Markdown file without snippets..." - uses: ./actions/extract-rust-snippets with: @@ -12,29 +12,22 @@ runs: markdown-file: NO-SNIPPETS.md test-filename-prefix: fake-tests/fake- - - name: The Rust test files should not have been created + - name: The test directory should not have been created shell: bash - working-directory: tests/unknown-tech/fake-tests + working-directory: tests/unknown-tech run: | - echo "🔎Inspecting the 'fake-tests' subdirectory..." - ls -1 2>/dev/null - echo "🔎🔎🔎" - - files="$(ls -1 2>/dev/null)" - - if [[ -z "$files" ]] + if [[ ! -d fake-tests ]] then - echo "✅No generated test files, as expected" + echo "✅ The test directory was not even created, as expected!" else - echo "❌There should be no generated test files!" >&2 + echo "❌ The test directory should not have been created!" exit 1 fi - shell: bash - run: echo "🎭Generating test files from Markdown file with snippets..." + run: echo "🎭 Generating test files from Markdown file with snippets..." - - name: - uses: ./actions/extract-rust-snippets + - uses: ./actions/extract-rust-snippets with: project-directory: tests/unknown-tech @@ -42,23 +35,23 @@ runs: shell: bash working-directory: tests/unknown-tech/tests run: | - echo "🔎Inspecting the 'tests' subdirectory..." + echo "🔎 Inspecting the 'tests' subdirectory..." ls -1 2>/dev/null echo "🔎🔎🔎" - echo "🔎Now ensuring all the 3 test files exist..." + echo "🔎 Now ensuring all the 3 test files exist..." for i in {1..3} do testFile="readme_test_${i}.rs" if [[ ! -f "$testFile" ]] then - echo "❌Missing Rust test file: '$testFile'" + echo "❌ Missing Rust test file: '$testFile'" exit 1 fi done - echo "✅All the test files exist!" + echo "✅ All the test files exist!" - name: The first test must contain the expected Rust source code shell: bash @@ -66,14 +59,14 @@ runs: run: | testFile="readme_test_1.rs" - echo "🔎Inspecting the content of the first test file..." + echo "🔎 Inspecting the content of the first test file..." cat $testFile echo "🔎🔎🔎" grep -q 'Alpha' "$testFile" grep -q 'Beta' "$testFile" grep -q 'main().unwrap();' "$testFile" - echo "✅First test file OK!" + echo "✅ First test file OK!" - name: The second test must contain the expected Rust source code shell: bash @@ -81,7 +74,7 @@ runs: run: | testFile="readme_test_2.rs" - echo "🔎Inspecting the content of the second test file..." + echo "🔎 Inspecting the content of the second test file..." cat $testFile echo "🔎🔎🔎" @@ -89,7 +82,7 @@ runs: grep -q 'Delta' "$testFile" grep -q 'Epsilon' "$testFile" grep -q 'main().unwrap();' "$testFile" - echo "✅Second test file OK!" + echo "✅ Second test file OK!" - name: The third test must contain the expected Rust source code shell: bash @@ -97,21 +90,21 @@ runs: run: | testFile="readme_test_3.rs" - echo "🔎Inspecting the content of the third test file..." + echo "🔎 Inspecting the content of the third test file..." cat $testFile echo "🔎🔎🔎" grep -q 'Sigma' "$testFile" grep -q 'Tau' "$testFile" grep -q 'main().unwrap();' "$testFile" - echo "✅Third test file OK!" + echo "✅ Third test file OK!" - shell: bash - run: echo "🎭Trying to generate test files from inexisting Markdown file..." + run: echo "🎭 Trying to generate test files from inexistent Markdown file..." - uses: ./actions/extract-rust-snippets with: project-directory: tests/unknown-tech - markdown-file: JUST_INEXISTING_MARKDOWN.md + markdown-file: JUST_INEXISTENT_MARKDOWN.md optional: true test-filename-prefix: fake-tests/fake- diff --git a/.github/test-actions/test-find-critical-todos/action.yml b/.github/test-actions/test-find-critical-todos/action.yml index 80df62a73..311df45e4 100644 --- a/.github/test-actions/test-find-critical-todos/action.yml +++ b/.github/test-actions/test-find-critical-todos/action.yml @@ -3,7 +3,7 @@ runs: using: composite steps: - shell: bash - run: echo "🎭Find existing critical TODOs without crashing..." + run: echo "🎭 Find existing critical TODOs without crashing..." - uses: ./actions/find-critical-todos id: find-existing-critical-todos @@ -20,20 +20,20 @@ runs: if [[ "$found" == "true" ]] then - echo "✅Critical TODOs found, as expected" + echo "✅ Critical TODOs found, as expected" else - echo "❌The expected critical TODOs have not been found!" >&2 + echo "❌ The expected critical TODOs have not been found!" >&2 exit 1 fi - shell: bash - run: echo "🎭Look for inexisting critical TODOs..." + run: echo "🎭 Look for inexistent critical TODOs..." - uses: ./actions/find-critical-todos id: look-for-missing-critical-todos with: root-directory: tests/custom - source-file-regex: .* + source-file-regex: \.(rs|elv)$ crash-on-found: true verbose: true @@ -44,8 +44,8 @@ runs: if [[ "$found" != "true" ]] then - echo "✅Critical TODOs not found, as expected" + echo "✅ Critical TODOs not found, as expected" else - echo "❌Critical TODOs have been found where they should be missing!" >&2 + echo "❌ Critical TODOs have been found where they should be missing!" >&2 exit 1 fi diff --git a/.github/test-actions/test-generate-wasm-target/action.yml b/.github/test-actions/test-generate-wasm-target/action.yml index 19d2bb0f8..be3f52af1 100644 --- a/.github/test-actions/test-generate-wasm-target/action.yml +++ b/.github/test-actions/test-generate-wasm-target/action.yml @@ -16,7 +16,7 @@ runs: project-directory: tests/rust-wasm - shell: bash - run: echo "🎭Now generating a dev project with 'web' target..." + run: echo "🎭 Now generating a dev project with 'web' target..." - name: Set up the expected versions shell: bash @@ -40,13 +40,13 @@ runs: working-directory: tests/rust-wasm/pkg-web run: | packageName="$(jq -r '.name' package.json)" - echo "🔎Name field in the generated package.json: '$packageName'" + echo "🔎 Name field in the generated package.json: '$packageName'" if [[ "$packageName" == "@giancosta86/test-wasm" ]] then - echo "✅The generated package.json has the expected name!" + echo "✅ The generated package.json has the expected name!" else - echo "❌Unexpected value for the 'name' field in package.json!" + echo "❌ Unexpected value for the 'name' field in package.json!" exit 1 fi @@ -55,13 +55,13 @@ runs: working-directory: tests/rust-wasm/pkg-web run: | packageVersion="$(jq -r '.version' package.json)" - echo "🔎Version field in the generated package.json: '$packageVersion'" + echo "🔎 Version field in the generated package.json: '$packageVersion'" if [[ "$packageVersion" == "${{ steps.version-detector.outputs.version }}" ]] then - echo "✅The generated package.json has the expected version!" + echo "✅ The generated package.json has the expected version!" else - echo "❌Unexpected value for the 'version' field in package.json!" + echo "❌ Unexpected value for the 'version' field in package.json!" exit 1 fi @@ -70,13 +70,13 @@ runs: working-directory: tests/rust-wasm/pkg-web run: | nodeJsVersion="$(jq -r '.engines.node' package.json)" - echo "🔎NodeJS version field in the generated package.json: '$nodeJsVersion'" + echo "🔎 NodeJS version field in the generated package.json: '$nodeJsVersion'" if [[ "$nodeJsVersion" == "${{ env.expectedNodeJsVersion }}" ]] then - echo "✅The generated package.json requires the expected NodeJS version!" + echo "✅ The generated package.json requires the expected NodeJS version!" else - echo "❌Unexpected value for the 'engines / node' field in package.json!" + echo "❌ Unexpected value for the 'engines / node' field in package.json!" exit 1 fi @@ -85,18 +85,18 @@ runs: working-directory: tests/rust-wasm/pkg-web run: | pnpmReference="$(jq -r '.packageManager' package.json)" - echo "🔎pnpm reference field in the generated package.json: '$pnpmReference'" + echo "🔎 pnpm reference field in the generated package.json: '$pnpmReference'" if [[ "$pnpmReference" == "pnpm@${{ env.expectedPnpmVersion }}" ]] then - echo "✅The generated package.json references the expected pnpm version!" + echo "✅ The generated package.json references the expected pnpm version!" else - echo "❌Unexpected value for the 'packageManager' field in package.json!" + echo "❌ Unexpected value for the 'packageManager' field in package.json!" exit 1 fi - shell: bash - run: echo "🎭Now generating a release project with 'deno' target..." + run: echo "🎭 Now generating a release project with 'deno' target..." - uses: ./actions/generate-wasm-target with: @@ -111,8 +111,8 @@ runs: run: | if [[ ! -f "package.json" ]] then - echo "✅No package.json was generated for Deno, as expected!" + echo "✅ No package.json was generated for Deno, as expected!" else - echo "❌Why was package.json generated for Deno?" + echo "❌ Why was package.json generated for Deno?" exit 1 fi diff --git a/.github/test-actions/test-inject-subpath-exports/action.yml b/.github/test-actions/test-inject-subpath-exports/action.yml index cd6c48f54..6d06c0324 100644 --- a/.github/test-actions/test-inject-subpath-exports/action.yml +++ b/.github/test-actions/test-inject-subpath-exports/action.yml @@ -21,29 +21,19 @@ runs: run: rm -f "$rootIndexFile" - shell: bash - run: echo "🎭Run with prefer-index mode - when the root index file is missing..." + run: echo "🎭 Run with prefer-index mode - when the root index file is missing..." - uses: ./actions/inject-subpath-exports with: project-directory: tests/npm-package mode: prefer-index - - name: A subpath export should be generated for each subdirectory - shell: bash - working-directory: tests/npm-package - run: | - echo "🔎Asserting injected subpath exports from subdirectories only..." - grep -q '"./alpha"' package.json - grep -q '"./beta"' package.json - grep -q '"./omega"' package.json - - [[ "$(jq -r '.exports."./alpha".types' package.json)" == "./dist/alpha/index.d.ts" ]] || exit 1 - - [[ "$(jq -r '.exports."./alpha".import' package.json)" == "./dist/alpha/index.js" ]] || exit 1 - - ! grep -q '"."' package.json - ! grep -q '"./sigma"' package.json - echo "✅OK!" + - uses: ./.github/test-actions/test-inject-subpath-exports/scenario + with: + should-have-root: false + should-have-subdirectories: true + should-have-initial: false + working-directory: tests/npm-package - name: Restore package.json and add a root index file shell: bash @@ -53,31 +43,21 @@ runs: touch "$rootIndexFile" - shell: bash - run: echo "🎭Run again with prefer-index mode - now that the root index exists..." + run: echo "🎭 Run again with prefer-index mode - now that the root index exists..." - uses: ./actions/inject-subpath-exports with: project-directory: tests/npm-package mode: prefer-index - - name: A subpath export should be generated only for the root index - shell: bash - working-directory: tests/npm-package - run: | - echo "🔎Asserting injected subpath export for root index only..." - ! grep -q '"./alpha"' package.json - ! grep -q '"./beta"' package.json - ! grep -q '"./omega"' package.json - grep -q '"."' package.json - - [[ "$(jq -r '.exports.".".types' package.json)" == "./dist/index.d.ts" ]] || exit 1 - - [[ "$(jq -r '.exports.".".import' package.json)" == "./dist/index.js" ]] || exit 1 - - ! grep -q '"./sigma"' package.json - echo "✅OK!" + - uses: ./.github/test-actions/test-inject-subpath-exports/scenario + with: + should-have-root: true + should-have-subdirectories: false + should-have-initial: false + working-directory: tests/npm-package - - name: Restore package descriptor with custom export + - name: Restore package descriptor and add a custom export shell: bash working-directory: tests/npm-package run: | @@ -88,22 +68,16 @@ runs: mv package.json.temp package.json - shell: bash - run: echo "🎭Run action with 'all' mode..." + run: echo "🎭 Run action with 'all' mode..." - uses: ./actions/inject-subpath-exports with: project-directory: tests/npm-package mode: all - - name: Subpath exports should be generated for both root index and subdirectories - shell: bash - working-directory: tests/npm-package - run: | - echo "🔎Asserting that all exports exist, including the manual ones..." - grep -q '"./my-export"' package.json - grep -q '"./alpha"' package.json - grep -q '"./beta"' package.json - grep -q '"./omega"' package.json - grep -q '"."' package.json - ! grep -q '"./sigma"' package.json - echo "✅OK!" + - uses: ./.github/test-actions/test-inject-subpath-exports/scenario + with: + should-have-root: true + should-have-subdirectories: true + should-have-initial: true + working-directory: tests/npm-package diff --git a/.github/test-actions/test-inject-subpath-exports/scenario/action.yml b/.github/test-actions/test-inject-subpath-exports/scenario/action.yml new file mode 100644 index 000000000..e79aa3eb4 --- /dev/null +++ b/.github/test-actions/test-inject-subpath-exports/scenario/action.yml @@ -0,0 +1,98 @@ +name: Verify injected subpath exports + +inputs: + should-have-root: + description: Whether the root index file should have been injected. + + should-have-subdirectories: + description: Whether the index files in subdirectories should have been injected. + + should-have-initial: + description: Whether the initial exports should be found. + + working-directory: + description: The directory containing package.json. + +runs: + using: composite + steps: + - shell: bash + if: inputs.should-have-root == 'true' + working-directory: ${{ inputs.working-directory }} + run: | + echo "🔎 Asserting exports for root index file..." + + grep -q '"."' package.json || exit 1 + [[ "$(jq -r '.exports.".".types' package.json)" == "./dist/index.d.ts" ]] || exit 1 + [[ "$(jq -r '.exports.".".import' package.json)" == "./dist/index.js" ]] || exit 1 + + echo "✅ OK!" + + - shell: bash + if: inputs.should-have-root != 'true' + working-directory: ${{ inputs.working-directory }} + run: | + echo "🔎 Asserting no exports for root index file..." + + ! grep -q '"."' package.json || exit 1 + + echo "✅ OK!" + + - shell: bash + if: inputs.should-have-subdirectories == 'true' + working-directory: ${{ inputs.working-directory }} + run: | + echo "🔎 Asserting exports for subdirectories..." + + [[ "$(jq -r '.exports."./alpha".types' package.json)" == "./dist/alpha/index.d.ts" ]] || exit 1 + [[ "$(jq -r '.exports."./alpha".import' package.json)" == "./dist/alpha/index.js" ]] || exit 1 + + [[ "$(jq -r '.exports."./beta".types' package.json)" == "./dist/beta/index.d.ts" ]] || exit 1 + [[ "$(jq -r '.exports."./beta".import' package.json)" == "./dist/beta/index.js" ]] || exit 1 + + [[ "$(jq -r '.exports."./omega".types' package.json)" == "./dist/omega/index.d.ts" ]] || exit 1 + [[ "$(jq -r '.exports."./omega".import' package.json)" == "./dist/omega/index.js" ]] || exit 1 + + echo "✅ OK!" + + - shell: bash + if: inputs.should-have-subdirectories != 'true' + working-directory: ${{ inputs.working-directory }} + run: | + echo "🔎 Asserting no exports for subdirectories..." + + ! grep -q '"./alpha"' package.json || exit 1 + ! grep -q '"./beta"' package.json || exit 1 + ! grep -q '"./omega"' package.json || exit 1 + + echo "✅ OK!" + + - shell: bash + if: inputs.should-have-initial == 'true' + working-directory: ${{ inputs.working-directory }} + run: | + echo "🔎 Asserting the initial exports are untouched..." + + [[ "$(jq -r '.exports."./my-export".types' package.json)" == "./dist/my-export/index.d.ts" ]] || exit 1 + [[ "$(jq -r '.exports."./my-export".import' package.json)" == "./dist/my-export/index.js" ]] || exit 1 + + echo "✅ OK!" + + - shell: bash + if: inputs.should-have-initial != 'true' + working-directory: ${{ inputs.working-directory }} + run: | + echo "🔎 Asserting no initial exports have been declared..." + + ! grep -q '"./my-export"' package.json || exit 1 + + echo "✅ OK!" + + - shell: bash + working-directory: ${{ inputs.working-directory }} + run: | + echo "🔎 Asserting no exports for second-level subdirectories..." + + ! grep -q '"./sigma"' package.json || exit 1 + + echo "✅ OK!" diff --git a/.github/test-actions/test-install-system-packages/action.yml b/.github/test-actions/test-install-system-packages/action.yml index 26c5485e8..f33a86cd1 100644 --- a/.github/test-actions/test-install-system-packages/action.yml +++ b/.github/test-actions/test-install-system-packages/action.yml @@ -12,12 +12,12 @@ runs: run: | if which "$expectedCommand" then - echo "❌This test must be revised, as the '$expectedCommand' command is already installed." + echo "❌ This test must be revised, as the '$expectedCommand' command is already installed." exit 1 fi - shell: bash - run: echo "🎭Running unconditional installation..." + run: echo "🎭 Running unconditional installation..." - uses: ./actions/install-system-packages with: @@ -26,18 +26,18 @@ runs: - name: The expected command should now be available shell: bash run: | - echo "🔎Now looking for the '$expectedCommand' command..." + echo "🔎 Now looking for the '$expectedCommand' command..." if which "$expectedCommand" then - echo "✅The expected command is now available!" + echo "✅ The expected command is now available!" else - echo "❌The expected command was not installed!" >&2 + echo "❌ The expected command was not installed!" >&2 exit 1 fi - shell: bash - run: echo "🎭Running conditional installation for existing command..." + run: echo "🎭 Running conditional installation for existing command - which should be skipped..." - uses: ./actions/install-system-packages with: diff --git a/.github/test-actions/test-install-via-sdkman/action.yml b/.github/test-actions/test-install-via-sdkman/action.yml index d76be9c8c..ed17b70d0 100644 --- a/.github/test-actions/test-install-via-sdkman/action.yml +++ b/.github/test-actions/test-install-via-sdkman/action.yml @@ -10,36 +10,28 @@ runs: echo "expectedGradleVersion=8.2.1" >> $GITHUB_ENV - shell: bash - run: echo "🎭Checking the test environment..." + run: echo "🎭 Checking the test environment..." - name: Ensure the expected Maven version is not installed shell: bash run: | - mavenVersion="$(mvn --version | head -n 1 | cut -d ' ' -f 3)" - - echo "🔎Initial Maven version: '$mavenVersion'" - - if [[ "$mavenVersion" == "$expectedMavenVersion" ]] + if mvn --version | grep --color=always "$expectedMavenVersion" then - echo "❌The installed Maven version coincides with the expected one, making the test meaningless" + echo "❌ The installed Maven version coincides with the expected one, making the test meaningless" exit 1 fi - name: Ensure the expected Gradle version is not installed shell: bash run: | - gradleVersion="$(gradle --version | grep "Gradle" | head -n 1 | cut -d ' ' -f 2)" - - echo "🔎Initial Gradle version: '$gradleVersion'" - - if [[ "$gradleVersion" == "$expectedGradleVersion" ]] + if gradle --version | grep --color=always "$expectedGradleVersion" then - echo "❌The installed Gradle version coincides with the expected one, making the test meaningless" + echo "❌ The installed Gradle version coincides with the expected one, making the test meaningless" exit 1 fi - shell: bash - run: echo "🎭Installing 🪶Maven..." + run: echo "🎭 Installing 🪶 Maven..." - uses: ./actions/install-via-sdkman with: @@ -49,20 +41,16 @@ runs: - name: The expected Maven version should be available shell: bash run: | - mavenVersion="$(mvn --version | head -n 1 | cut -d ' ' -f 3)" - - echo "🔎Detected Maven version: '$mavenVersion'" - - if [[ "$mavenVersion" == "$expectedMavenVersion" ]] + if mvn --version | grep --color=always "$expectedMavenVersion" then - echo "✅The requested Maven version is ready!" + echo "✅ The requested Maven version is ready!" else - echo "❌The expected Maven version ('$expectedMavenVersion') is not installed!" >&2 + echo "❌ The expected Maven version ('$expectedMavenVersion') is not installed!" >&2 exit 1 fi - shell: bash - run: echo "🎭Installing 🐘Gradle..." + run: echo "🎭 Installing 🐘 Gradle..." - uses: ./actions/install-via-sdkman with: @@ -74,8 +62,8 @@ runs: run: | if gradle --version | grep --color=always "$expectedGradleVersion" then - echo "✅The requested Gradle version is ready!" + echo "✅ The requested Gradle version is ready!" else - echo "❌The expected Gradle version ('$expectedGradleVersion') is not installed!" >&2 + echo "❌ The expected Gradle version ('$expectedGradleVersion') is not installed!" >&2 exit 1 fi diff --git a/.github/test-actions/test-install-wasm-pack/action.yml b/.github/test-actions/test-install-wasm-pack/action.yml index c40a77928..cf6a590ef 100644 --- a/.github/test-actions/test-install-wasm-pack/action.yml +++ b/.github/test-actions/test-install-wasm-pack/action.yml @@ -7,21 +7,31 @@ runs: shell: bash run: echo "expectedVersion=0.13.1" >> $GITHUB_ENV + - name: The expected version should not be already installed + shell: bash + run: | + if type wasm-pack >/dev/null 2>&1 + then + if wasm-pack --version | grep --color=always "$expectedVersion" + then + echo "❌ The expected wasm-pack version ('$expectedVersion') is already installed - this test would be pointless!" >&2 + exit 1 + fi + else + echo "💭 The requested wasm-pack version is not running in this environment..." + fi + - uses: ./actions/install-wasm-pack with: wasm-pack-version: ${{ env.expectedVersion }} - - name: The expected wasm-pack version should be available + - name: The expected wasm-pack version should now be available shell: bash run: | - wasmPackVersion="$(wasm-pack --version | cut -d' ' -f2)" - - echo "🔎Detected wasm-pack version: '$wasmPackVersion'" - - if [[ "$wasmPackVersion" == "$expectedVersion" ]] + if wasm-pack --version | grep --color=always "$expectedVersion" then - echo "✅The requested wasm-pack version is in use!" + echo "✅ The requested wasm-pack version is in use!" else - echo "❌The expected wasm-pack version ('$expectedVersion') is not installed!" >&2 + echo "❌ The expected wasm-pack version ('$expectedVersion') is not installed!" >&2 exit 1 fi diff --git a/.github/test-actions/test-parse-npm-scope/action.yml b/.github/test-actions/test-parse-npm-scope/action.yml index dfaffa4a5..8e26cac2a 100644 --- a/.github/test-actions/test-parse-npm-scope/action.yml +++ b/.github/test-actions/test-parse-npm-scope/action.yml @@ -4,7 +4,7 @@ runs: using: composite steps: - shell: bash - run: echo "🎭Parsing root scope..." + run: echo "🎭 Parsing root scope..." - name: Parse root scope uses: ./actions/parse-npm-scope @@ -17,17 +17,17 @@ runs: run: | rootScope="${{ steps.root-detector.outputs.actual-scope }}" - echo "🔎Root scope parsed by action: '$rootScope'" + echo "🔎 Root scope parsed by action: '$rootScope'" if [[ -z "$rootScope" ]] then - echo "✅Root scope detected!" + echo "✅ Root scope detected!" else - echo "❌The parsed root scope must be empty!" >&2 + echo "❌ The parsed root scope must be empty!" >&2 exit 1 fi - shell: bash - run: echo "🎭Parsing scope without leading @..." + run: echo "🎭 Parsing scope without leading @..." - name: Parse scope without leading '@' uses: ./actions/parse-npm-scope @@ -40,17 +40,17 @@ runs: run: | actualScope="${{ steps.without-leading-detector.outputs.actual-scope }}" - echo "🔎Scope parsed by action: '$actualScope'" + echo "🔎 Scope parsed by action: '$actualScope'" if [[ "$actualScope" == 'giancosta86' ]] then - echo "✅Scope without '@' detected!" + echo "✅ Scope without '@' detected!" else - echo "❌Incorrect scope detected!" >&2 + echo "❌ Incorrect scope detected!" >&2 exit 1 fi - shell: bash - run: echo "🎭Parsing scope with leading @..." + run: echo "🎭 Parsing scope with leading @..." - name: Parse scope with leading '@' uses: ./actions/parse-npm-scope @@ -63,11 +63,11 @@ runs: run: | actualScope="${{ steps.with-leading-detector.outputs.actual-scope }}" - echo "🔎Scope parsed by action: '$actualScope'" + echo "🔎 Scope parsed by action: '$actualScope'" if [[ "$actualScope" == 'giancosta86' ]] then - echo "✅Scope with '@' detected!" + echo "✅ Scope with '@' detected!" else - echo "❌Incorrect scope detected!" >&2 + echo "❌ Incorrect scope detected!" >&2 exit 1 fi diff --git a/.github/test-actions/test-publish-github-pages/action.yml b/.github/test-actions/test-publish-github-pages/action.yml index 9b0962a5d..4f89186f2 100644 --- a/.github/test-actions/test-publish-github-pages/action.yml +++ b/.github/test-actions/test-publish-github-pages/action.yml @@ -4,7 +4,7 @@ runs: using: composite steps: - shell: bash - run: echo "🎭Now publishing static files with dry-run enabled..." + run: echo "🎭 Now publishing (in dry-run) static files..." - name: A static website should be publishable uses: ./actions/publish-github-pages @@ -13,7 +13,7 @@ runs: dry-run: true - shell: bash - run: echo "🎭Now publishing a Maven-generated site with dry-run enabled..." + run: echo "🎭 Now publishing (in dry-run) a Maven-generated site..." - name: A Maven-generated website should be publishable uses: ./actions/publish-github-pages @@ -22,7 +22,7 @@ runs: dry-run: true - shell: bash - run: echo "🎭Now publishing a NextJS site..." + run: echo "🎭 Now publishing a NextJS site..." - name: A NextJS website should be publishable id: publish-nextjs-pages @@ -37,8 +37,24 @@ runs: if [[ -n "$websiteUrl" ]] then - echo "✅Website published and available at: '$websiteUrl'" + echo "✅ Website published and available at: '$websiteUrl'" else - echo "❌Website not available!" >&2 + echo "❌ Website not available!" >&2 exit 1 fi + + - shell: bash + run: echo "🎭 Now trying to publish an inexistent source directory..." + + - uses: ./actions/publish-github-pages + with: + source-directory: INEXISTENT_DIRECTORY + optional: true + + - shell: bash + run: echo "🎭 Now trying to omit the source directory..." + + - uses: ./actions/publish-github-pages + with: + source-directory: "" + optional: true diff --git a/.github/test-actions/test-publish-jvm-project/action.yml b/.github/test-actions/test-publish-jvm-project/action.yml index bdc2a5280..e34bc198f 100644 --- a/.github/test-actions/test-publish-jvm-project/action.yml +++ b/.github/test-actions/test-publish-jvm-project/action.yml @@ -2,13 +2,13 @@ name: Test publish-jvm-project inputs: jvm-token: - description: The token used when publishing to a Maven repo + description: The token used when publishing to a Maven repo. runs: using: composite steps: - shell: bash - run: echo "🎭Testing publication via Maven..." + run: echo "🎭 Testing publication via Maven..." - uses: ./actions/publish-jvm-project with: @@ -18,7 +18,7 @@ runs: auth-token: ${{ inputs.jvm-token }} - shell: bash - run: echo "🎭Testing publication via Gradle..." + run: echo "🎭 Testing publication via Gradle..." - uses: ./actions/publish-jvm-project with: diff --git a/.github/test-actions/test-publish-python-package/action.yml b/.github/test-actions/test-publish-python-package/action.yml index 04c4590d7..7fb4eb37c 100644 --- a/.github/test-actions/test-publish-python-package/action.yml +++ b/.github/test-actions/test-publish-python-package/action.yml @@ -2,7 +2,7 @@ name: Test publish-python-package inputs: index-secret: - description: The password/token for publishing to the index + description: The password/token for publishing to the index. runs: using: composite diff --git a/.github/test-actions/test-publish-rust-crate/action.yml b/.github/test-actions/test-publish-rust-crate/action.yml index 7534cf086..c9563b188 100644 --- a/.github/test-actions/test-publish-rust-crate/action.yml +++ b/.github/test-actions/test-publish-rust-crate/action.yml @@ -3,7 +3,28 @@ name: Test publish-rust-crate runs: using: composite steps: - - uses: ./actions/publish-rust-crate + - name: Backup Cargo.toml + shell: bash + working-directory: tests/rust-crate + run: cp Cargo.toml Cargo.toml.bak + + - uses: ./.github/test-actions/test-publish-rust-crate/scenario + with: + header: Testing publication with no initial addendum - and injection disabled + pre-existing-addendum: false + document-all-features: false + should-contain-addendum: false + + - uses: ./.github/test-actions/test-publish-rust-crate/scenario + with: + header: Testing publication with no initial addendum - and injection enabled + pre-existing-addendum: false + document-all-features: true + should-contain-addendum: true + + - uses: ./.github/test-actions/test-publish-rust-crate/scenario with: - dry-run: true - project-directory: tests/rust-crate + header: Testing publication with initial addendum - and injection enabled + pre-existing-addendum: true + document-all-features: true + should-contain-addendum: true diff --git a/.github/test-actions/test-publish-rust-crate/assert-doc-addendum/action.yml b/.github/test-actions/test-publish-rust-crate/assert-doc-addendum/action.yml new file mode 100644 index 000000000..d9bbcd531 --- /dev/null +++ b/.github/test-actions/test-publish-rust-crate/assert-doc-addendum/action.yml @@ -0,0 +1,22 @@ +name: Assert that the documentation addendum appears a given number of times in Cargo.toml + +inputs: + expected-count: + description: How many times the documentation addendum should appear in Cargo.toml. + +runs: + using: composite + steps: + - shell: bash + working-directory: tests/rust-crate + run: | + expectedCount="${{ inputs.expected-count }}" + actualCount="$(grep -c '\[package.metadata.docs.rs\]' Cargo.toml || true)" + + if [[ "$actualCount" == $expectedCount ]] + then + echo "✅ Instances of the documentation addendum: $actualCount - as expected!" + else + echo "❌ Instances of the documentation addendum: $actualCount. Expected: $expectedCount" + exit 1 + fi diff --git a/.github/test-actions/test-publish-rust-crate/scenario/action.yml b/.github/test-actions/test-publish-rust-crate/scenario/action.yml new file mode 100644 index 000000000..81b1a2699 --- /dev/null +++ b/.github/test-actions/test-publish-rust-crate/scenario/action.yml @@ -0,0 +1,54 @@ +name: Runs a scenario for publish-rust-crate + +inputs: + header: + description: The header for this test. + + pre-existing-addendum: + description: Whether the documentation addendum should exist before running the action. + + document-all-features: + description: Forwarded to the action. + + should-contain-addendum: + description: Whether Cargo.toml should contain the documentation addendum. + +runs: + using: composite + steps: + - name: Display the header + shell: bash + run: echo "🎭 ${{ inputs.header }}" + + - name: Restore Cargo.toml + shell: bash + working-directory: tests/rust-crate + run: cp Cargo.toml.bak Cargo.toml + + - name: Manually add the documentation addendum + if: inputs.pre-existing-addendum == 'true' + shell: bash + working-directory: tests/rust-crate + run: | + echo >> Cargo.toml + echo '# Manually added' >> Cargo.toml + echo '[package.metadata.docs.rs]' >> Cargo.toml + echo 'all-features = true' >> Cargo.toml + + - uses: ./actions/publish-rust-crate + with: + dry-run: true + document-all-features: ${{ inputs.document-all-features }} + project-directory: tests/rust-crate + + - name: Verify that Cargo.toml actually includes the documentation addendum + uses: ./.github/test-actions/test-publish-rust-crate/assert-doc-addendum + if: inputs.should-contain-addendum == 'true' + with: + expected-count: 1 + + - name: Verify that Cargo.toml does not include the documentation addendum + uses: ./.github/test-actions/test-publish-rust-crate/assert-doc-addendum + if: inputs.should-contain-addendum != 'true' + with: + expected-count: 0 diff --git a/.github/test-actions/test-publish-rust-wasm/action.yml b/.github/test-actions/test-publish-rust-wasm/action.yml index cedf33cb3..96a4912be 100644 --- a/.github/test-actions/test-publish-rust-wasm/action.yml +++ b/.github/test-actions/test-publish-rust-wasm/action.yml @@ -9,4 +9,5 @@ runs: dry-run: true wasm-pack-version: 0.13.1 nodejs-version: 20.15.1 + pnpm-version: 10.6.1 npm-scope: giancosta86 diff --git a/.github/test-actions/test-run-custom-tests/action.yml b/.github/test-actions/test-run-custom-tests/action.yml index 666997595..63fe16f5d 100644 --- a/.github/test-actions/test-run-custom-tests/action.yml +++ b/.github/test-actions/test-run-custom-tests/action.yml @@ -3,79 +3,56 @@ name: Test run-custom-tests runs: using: composite steps: - - shell: bash - run: echo "🎭Testing the 'script' strategy..." - - - uses: ./actions/run-custom-tests + - uses: ./.github/test-actions/test-run-custom-tests/scenario with: - root-directory: tests/custom/script + strategy: bash + root-directory: tests/custom/bash - - name: The Bash script should have run correctly - shell: bash - working-directory: tests/custom/script - run: | - generatedContent="$(cat generated-file.txt)" + - uses: ./.github/test-actions/test-run-custom-tests/scenario + with: + strategy: elvish + root-directory: tests/custom/elvish - if [[ "$generatedContent" == "Bash-generated content" ]] - then - echo "✅The Bash test script completed perfectly!" - else - echo "❌Issues with the Bash test script!" >&2 - exit 1 - fi + - uses: ./.github/test-actions/test-run-custom-tests/scenario + with: + strategy: elvish + script-file: super-test.elv + root-directory: tests/custom/elvish-custom - - shell: bash - run: echo "🎭Testing the 'nodejs' strategy..." + - uses: ./.github/test-actions/test-run-custom-tests/scenario + with: + strategy: test-runner + root-directory: tests/custom/test-runner - - uses: ./actions/run-custom-tests + - uses: ./.github/test-actions/test-run-custom-tests/scenario with: + strategy: nodejs root-directory: tests/custom/nodejs - - name: The NodeJS script should have run correctly - shell: bash - working-directory: tests/custom/nodejs/ - run: | - generatedContent="$(cat generated-file.txt)" - - if [[ "$generatedContent" == "NodeJS-generated content" ]] - then - echo "✅The NodeJS test script completed perfectly!" - else - echo "❌Issues with the NodeJS test script!" >&2 - exit 1 - fi + - uses: ./.github/test-actions/test-run-custom-tests/scenario + with: + strategy: rust + root-directory: tests/custom/rust - shell: bash - run: echo "🎭Testing the 'rust' strategy..." + run: echo "🎭 Trying to run tests from an inexistent directory..." - uses: ./actions/run-custom-tests with: - root-directory: tests/custom/rust - - - name: The Rust tests should have run correctly - shell: bash - working-directory: tests/custom/rust/ - run: | - generatedContent="$(cat generated-file.txt)" - - if [[ "$generatedContent" == "Rust-generated content" ]] - then - echo "✅The Rust test script completed perfectly!" - else - echo "❌Issues with the Rust test script!" >&2 - exit 1 - fi + root-directory: tests/custom/TOTALLY_INEXISTENT + optional: true - shell: bash - run: echo "🎭Trying to run tests from inexisting directory..." + run: echo "🎭 Trying to run tests via an inexistent script..." - uses: ./actions/run-custom-tests with: - root-directory: tests/custom/TOTALLY_INEXISTING + root-directory: tests/custom optional: true + script-file: INEXISTENT - shell: bash - run: echo "🎭Trying to run tests from a directory containing no tests..." + run: echo "🎭 Trying to run tests from a directory containing no tests..." - uses: ./actions/run-custom-tests with: diff --git a/.github/test-actions/test-run-custom-tests/scenario/action.yml b/.github/test-actions/test-run-custom-tests/scenario/action.yml new file mode 100644 index 000000000..88dab2cb0 --- /dev/null +++ b/.github/test-actions/test-run-custom-tests/scenario/action.yml @@ -0,0 +1,34 @@ +name: Run a project-specific scenario for run-custom-tests + +inputs: + strategy: + description: The test strategy. + + script-file: + description: The script-file parameter forwarded to the action. + + root-directory: + description: The root directory for the tests. + +runs: + using: composite + steps: + - shell: bash + run: echo "🎭 Testing the '${{ inputs.strategy }}' strategy in directory '${{ inputs.root-directory }}'..." + + - uses: ./actions/run-custom-tests + with: + script-file: ${{ inputs.script-file }} + root-directory: ${{ inputs.root-directory }} + + - name: Ensure the expected output file was actually created by the tests + shell: bash + working-directory: ${{ inputs.root-directory }} + run: | + if [[ "$(cat out.txt)" == "TEST OK" ]] + then + echo "✅ The tests for the '${{ inputs.strategy }}' strategy completed perfectly!" + else + echo "❌ Issues with the '${{ inputs.strategy }}' test strategy!" >&2 + exit 1 + fi diff --git a/.github/test-actions/test-run-shell-script/action.yml b/.github/test-actions/test-run-shell-script/action.yml new file mode 100644 index 000000000..174275adf --- /dev/null +++ b/.github/test-actions/test-run-shell-script/action.yml @@ -0,0 +1,96 @@ +name: Test run-custom-tests + +runs: + using: composite + steps: + - uses: ./.github/test-actions/test-run-shell-script/scenario + with: + script-base: bash-test + script-extension: .sh + shell: bash + multiplier: 10 + + - uses: ./.github/test-actions/test-run-shell-script/scenario + with: + script-base: elvish-test + script-extension: .elv + shell: elvish + multiplier: 50 + + - shell: bash + run: echo "🎭 Testing script having an unknown extension..." + + - uses: ./actions/run-shell-script + with: + script-file: elvish-hidden.txt + shell: elvish + args: alpha, beta, gamma + working-directory: ${{ github.action_path }} + + - uses: ./.github/test-actions/test-run-shell-script/expect-result + with: + arg-count: 3 + multiplier: 400 + + - shell: bash + run: echo "🎭 Testing inexistent optional script..." + + - shell: bash + working-directory: ${{ github.action_path }} + run: rm -f result.txt + + - uses: ./actions/run-shell-script + with: + script-file: INEXISTENT-SCRIPT + optional: true + working-directory: ${{ github.action_path }} + + - shell: bash + working-directory: ${{ github.action_path }} + run: | + if [[ ! -f result.txt ]] + then + echo "✅ Result file missing, as expected!" + else + echo "❌ The result file was somehow created!" + exit 1 + fi + + - shell: bash + run: echo "🎭 Testing optional script with unsupported, undeclared shell..." + + - shell: bash + working-directory: ${{ github.action_path }} + run: rm -f result.txt + + - uses: ./actions/run-shell-script + with: + script-file: python-test.py + optional: true + working-directory: ${{ github.action_path }} + + - shell: bash + working-directory: ${{ github.action_path }} + run: | + if [[ ! -f result.txt ]] + then + echo "✅ Result file missing, as expected!" + else + echo "❌ The result file was somehow created!" + exit 1 + fi + + - shell: bash + run: echo "🎭 Testing script with unsupported but declared shell..." + + - uses: ./actions/run-shell-script + with: + script-file: python-test.py + shell: python3 + args: alpha, beta, gamma + working-directory: ${{ github.action_path }} + + - uses: ./.github/test-actions/test-run-shell-script/expect-result + with: + arg-count: 3 + multiplier: 2000 diff --git a/.github/test-actions/test-run-shell-script/bash-test.sh b/.github/test-actions/test-run-shell-script/bash-test.sh new file mode 100644 index 000000000..2efd01f53 --- /dev/null +++ b/.github/test-actions/test-run-shell-script/bash-test.sh @@ -0,0 +1,3 @@ +argCount="$#" + +echo $(($argCount * 10)) > result.txt \ No newline at end of file diff --git a/.github/test-actions/test-run-shell-script/elvish-hidden.txt b/.github/test-actions/test-run-shell-script/elvish-hidden.txt new file mode 100644 index 000000000..740ff3181 --- /dev/null +++ b/.github/test-actions/test-run-shell-script/elvish-hidden.txt @@ -0,0 +1,3 @@ +var arg-count = (count $args) + +echo (* $arg-count 400) > result.txt \ No newline at end of file diff --git a/.github/test-actions/test-run-shell-script/elvish-test.elv b/.github/test-actions/test-run-shell-script/elvish-test.elv new file mode 100644 index 000000000..04b598591 --- /dev/null +++ b/.github/test-actions/test-run-shell-script/elvish-test.elv @@ -0,0 +1,3 @@ +var arg-count = (count $args) + +echo (* $arg-count 50) > result.txt \ No newline at end of file diff --git a/.github/test-actions/test-run-shell-script/expect-result/action.yml b/.github/test-actions/test-run-shell-script/expect-result/action.yml new file mode 100644 index 000000000..29d8ca14f --- /dev/null +++ b/.github/test-actions/test-run-shell-script/expect-result/action.yml @@ -0,0 +1,27 @@ +name: Ensure that result.txt contains the expected value + +inputs: + multiplier: + description: The factor by which the tested script multiplies the number of arguments. + + arg-count: + description: The number of arguments that were passed to the tested script. + +runs: + using: composite + steps: + - name: Ensure the expected result was printed out to the result file + shell: bash + working-directory: ${{ github.action_path }}/.. + run: | + expected=$((${{ inputs.arg-count }} * ${{ inputs.multiplier }})) + + scriptResult="$(cat result.txt)" + + if [[ "$scriptResult" == "$expected" ]] + then + echo "✅ The script result was $expected, just as expected!" + else + echo "❌ The script result is $scriptResult, but $expected was expected!" >&2 + exit 1 + fi diff --git a/.github/test-actions/test-run-shell-script/python-test.py b/.github/test-actions/test-run-shell-script/python-test.py new file mode 100644 index 000000000..66c793b59 --- /dev/null +++ b/.github/test-actions/test-run-shell-script/python-test.py @@ -0,0 +1,6 @@ +import sys + +arg_count = len(sys.argv[1:]) + +with open("result.txt", "w") as f: + f.write(f"{2000 * arg_count}") \ No newline at end of file diff --git a/.github/test-actions/test-run-shell-script/scenario/action.yml b/.github/test-actions/test-run-shell-script/scenario/action.yml new file mode 100644 index 000000000..58609213a --- /dev/null +++ b/.github/test-actions/test-run-shell-script/scenario/action.yml @@ -0,0 +1,78 @@ +name: Runs a project-specific scenario for run-shell-script + +inputs: + script-base: + description: The extension-less name of the script file. + + script-extension: + description: | + The explicit extension of the script file (starting with .). + + The script must count its arguments, multiply them by a given factor + and finally write the resulting number to 'result.txt' in this directory. + + shell: + description: The explicit shell used to run the script. + + multiplier: + description: The factor by which the script multiplies the number of arguments. + +runs: + using: composite + steps: + - shell: bash + run: echo "🎭 Testing script '${{ inputs.script-base }}' with no extension and no shell..." + + - uses: ./actions/run-shell-script + with: + script-file: ${{ inputs.script-base }} + working-directory: ${{ github.action_path }}/.. + + - uses: ./.github/test-actions/test-run-shell-script/expect-result + with: + arg-count: 0 + multiplier: ${{ inputs.multiplier }} + + - shell: bash + run: echo "🎭 Testing script '${{ inputs.script-base }}' with no extension and explicit shell ('${{ inputs.shell }}')..." + + - uses: ./actions/run-shell-script + with: + script-file: ${{ inputs.script-base }} + shell: ${{ inputs.shell }} + args: alpha + working-directory: ${{ github.action_path }}/.. + + - uses: ./.github/test-actions/test-run-shell-script/expect-result + with: + arg-count: 1 + multiplier: ${{ inputs.multiplier }} + + - shell: bash + run: echo "🎭 Testing script '${{ inputs.script-base }}' with explicit extension ('${{ inputs.script-extension }}') and no shell..." + + - uses: ./actions/run-shell-script + with: + script-file: ${{ inputs.script-base }}${{ inputs.script-extension }} + args: alpha, beta + working-directory: ${{ github.action_path }}/.. + + - uses: ./.github/test-actions/test-run-shell-script/expect-result + with: + arg-count: 2 + multiplier: ${{ inputs.multiplier }} + + - shell: bash + run: echo "🎭 Testing script '${{ inputs.script-base }}' with explicit extension ('${{ inputs.script-extension }}') and explicit shell ('${{ inputs.shell }}')..." + + - uses: ./actions/run-shell-script + with: + script-file: ${{ inputs.script-base }}${{ inputs.script-extension }} + shell: ${{ inputs.shell }} + args: alpha, beta, gamma + working-directory: ${{ github.action_path }}/.. + + - uses: ./.github/test-actions/test-run-shell-script/expect-result + with: + arg-count: 3 + multiplier: ${{ inputs.multiplier }} diff --git a/.github/test-actions/test-setup-elvish-context/action.yml b/.github/test-actions/test-setup-elvish-context/action.yml index 8ff79c4f3..ecf392b65 100644 --- a/.github/test-actions/test-setup-elvish-context/action.yml +++ b/.github/test-actions/test-setup-elvish-context/action.yml @@ -1,52 +1,25 @@ name: Test setup-elvish-context +inputs: + skip-if-existing: + description: Forwarded to the action. + runs: using: composite steps: - shell: bash - run: echo "🎭Setup just the shell for the first time..." - - - uses: ./actions/setup-elvish-context - with: - skip-if-existing: false - - - shell: bash - run: echo "🎭Setup just the shell a second time..." - - - uses: ./actions/setup-elvish-context - with: - skip-if-existing: false - - - shell: bash - run: echo "🎭Setup the shell with startup packages..." + run: echo "🎭 Setup the Elvish shell..." - uses: ./actions/setup-elvish-context with: - packages: github.com/elves/sample-pkg, github.com/xiaq/edit.elv - skip-if-existing: false + skip-if-existing: ${{ inputs.skip-if-existing }} + quiet: false - shell: bash - run: echo "🎭Setup the shell with packages a second time..." - - - uses: ./actions/setup-elvish-context - with: - packages: github.com/elves/sample-pkg, github.com/xiaq/edit.elv - skip-if-existing: false - - - shell: bash - run: echo "🎭Try enabling the skip-if-existing flag..." - - - uses: ./actions/setup-elvish-context - with: - packages: github.com/elves/sample-pkg, github.com/xiaq/edit.elv - skip-if-existing: true - - - shell: bash - run: echo "🎭Run Elvish code to confirm..." + run: echo "🎭 Run Elvish code to confirm..." - shell: elvish {0} run: | - var message = '✅Elvish confirms: the shell is ready! 🚀' + var message = '✅ Elvish confirms: the shell is ready! 🚀' echo $message - diff --git a/.github/test-actions/test-setup-elvish-package/action.yml b/.github/test-actions/test-setup-elvish-package/action.yml new file mode 100644 index 000000000..f0c7e0944 --- /dev/null +++ b/.github/test-actions/test-setup-elvish-package/action.yml @@ -0,0 +1,58 @@ +name: Test setup-elvish-package + +runs: + using: composite + steps: + - name: Setup the environment variables for the test + shell: elvish {0} + run: | + use epm + + var package-path = (epm:metadata 'github.com/giancosta86/velvet')[dst] + + echo elvish-package-path=$package-path >> (get-env GITHUB_ENV) + + echo expectedTag=v1 >> (get-env GITHUB_ENV) + + - shell: bash + run: echo "🎭 Install the Velvet package from the main branch..." + + - uses: ./actions/setup-elvish-package + with: + package: github.com/giancosta86/velvet + quiet: false + + - shell: bash + working-directory: ${{ env.elvish-package-path }} + run: | + gitBranch="$(git branch --show-current)" + + if [[ "$gitBranch" == 'main' ]] + then + echo "✅The package is on the main branch, as expected!" + else + echo "❌Current Git branch instead of main: '$gitBranch'" + exit 1 + fi + + - shell: bash + run: echo "🎭 Setup the Velvet package to use tag $expectedTag..." + + - uses: ./actions/setup-elvish-package + with: + package: github.com/giancosta86/velvet + git-ref: ${{ env.expectedTag }} + quiet: false + + - shell: bash + working-directory: ${{ env.elvish-package-path }} + run: | + gitTag="$(git describe --tags --always)" + + if [[ "$gitTag" == "$expectedTag" ]] + then + echo "✅The package is on the $expectedTag tag, as expected!" + else + echo "❌Current Git tag instead of $expectedTag: '$gitTag'" + exit 1 + fi diff --git a/.github/test-actions/test-setup-nodejs-context/action.yml b/.github/test-actions/test-setup-nodejs-context/action.yml index cebd90429..61f93a945 100644 --- a/.github/test-actions/test-setup-nodejs-context/action.yml +++ b/.github/test-actions/test-setup-nodejs-context/action.yml @@ -3,54 +3,36 @@ name: Test setup-nodejs-context runs: using: composite steps: - - name: Setup environment variables + - name: Backup package.json and initialize environment variables shell: bash working-directory: tests/npm-package run: | - expectedNodeVersion="$(jq -r '.engines.node' package.json)" - echo "🔎Expected NodeJS version: '$expectedNodeVersion'" + cp package.json package.json.bak expectedPnpmVersion="$(jq -r '.packageManager' package.json | sed s/^pnpm@//)" - echo "🔎Expected pnpm version: '$expectedPnpmVersion'" + echo "🔎 Expected pnpm version: '$expectedPnpmVersion'" - echo "expectedNodeVersion=$expectedNodeVersion" >> $GITHUB_ENV echo "expectedPnpmVersion=$expectedPnpmVersion" >> $GITHUB_ENV echo "dependenciesDirectory=node_modules" >> $GITHUB_ENV - - name: The expected NodeJS version should not be pre-installed - shell: bash - working-directory: tests/npm-package - run: | - if type node &> /dev/null - then - installedNodeVersion="$(node --version | sed s/^v//)" - echo "🔎Pre-installed NodeJS version: '$installedNodeVersion'" - - if [[ "$installedNodeVersion" == "$expectedNodeVersion" ]] - then - echo "❌The expected NodeJS version is pre-installed!" >&2 - exit 1 - fi - else - echo "💭NodeJS not preinstalled..." - fi - - - name: The expected pnpm version should not be pre-installed + - name: The expected pnpm version should not be running shell: bash working-directory: tests/npm-package run: | if type pnpm &> /dev/null then installedPnpmVersion="$(pnpm --version)" - echo "🔎Pre-installed pnpm version: '$installedPnpmVersion'" + echo "🔎 Pre-installed pnpm version: '$installedPnpmVersion'" - if [[ "$installedPnpmVersion" == "$expectedPnpmVersion" ]] + if [[ "$installedPnpmVersion" != "$expectedPnpmVersion" ]] then - echo "❌The expected pnpm version is pre-installed!" >&2 + echo "✅ The expected pnpm version is not running!" + else + echo "❌ The expected pnpm version is running! This test would be pointless!" >&2 exit 1 fi else - echo "💭pnpm not preinstalled..." + echo "✅ pnpm not installed..." fi - name: Ensure the dependencies are not installed @@ -58,38 +40,28 @@ runs: working-directory: tests/npm-package run: rm -rf "$dependenciesDirectory" - - name: Setup the NodeJS context - uses: ./actions/setup-nodejs-context + - name: Setup NodeJS from .nvmrc + uses: ./.github/test-actions/test-setup-nodejs-context/scenario with: - project-directory: tests/npm-package - - - name: The expected NodeJS version should be used - shell: bash - working-directory: tests/npm-package - run: | - installedNodeVersion="$(node --version | sed s/^v//)" - echo "🔎Installed NodeJS version: '$installedNodeVersion'" + version-source: nvmrc - if [[ "$installedNodeVersion" == "$expectedNodeVersion" ]] - then - echo "✅The requested NodeJS version is being used!" - else - echo "❌The requested NodeJS version is not running!" >&2 - exit 1 - fi + - name: Setup NodeJS from package.json + uses: ./.github/test-actions/test-setup-nodejs-context/scenario + with: + version-source: package-json - - name: The expected pnpm version should be used + - name: The expected pnpm version should have been installed shell: bash working-directory: tests/npm-package run: | installedPnpmVersion="$(pnpm --version)" - echo "🔎Installed pnpm version: '$installedPnpmVersion'" + echo "🔎 Installed pnpm version: '$installedPnpmVersion'" if [[ "$installedPnpmVersion" == "$expectedPnpmVersion" ]] then - echo "✅The expected pnpm version is being used!" + echo "✅ The expected pnpm version is being used!" else - echo "❌The expected pnpm version is not running!" >&2 + echo "❌ The expected pnpm version is not running!" >&2 exit 1 fi @@ -99,8 +71,8 @@ runs: run: | if [[ -d "$dependenciesDirectory" ]] then - echo "✅The dependencies have been installed!" + echo "✅ The dependencies have been installed!" else - echo "❌The dependencies have not been installed!" >&2 + echo "❌ The dependencies have not been installed!" >&2 exit 1 fi diff --git a/.github/test-actions/test-setup-nodejs-context/scenario/action.yml b/.github/test-actions/test-setup-nodejs-context/scenario/action.yml new file mode 100644 index 000000000..45363df71 --- /dev/null +++ b/.github/test-actions/test-setup-nodejs-context/scenario/action.yml @@ -0,0 +1,93 @@ +name: Install the expected NodeJS context + +inputs: + version-source: + description: The source (`nvmrc` or `package-json`) containing the requested NodeJS version. + +runs: + using: composite + steps: + - name: Validate inputs + shell: bash + run: | + case '${{ inputs.version-source }}' in + nvmrc | package-json) + ;; + + *) + echo "❌ Invalid value for the 'version-source' input: '${{ inputs.version-source }}'" + exit 1 + ;; + esac + + - shell: bash + run: | + echo "🎭 Setting up NodeJS from source: '${{inputs.version-source}}'" + + - name: Initialize expected NodeJS version from .nvmrc + if: inputs.version-source == 'nvmrc' + shell: bash + working-directory: tests/npm-package + run: | + jq '(.engines | del(.node)) as $e | .engines = $e' package.json > temp-package + mv temp-package package.json + + echo v20.18.2 > .nvmrc + + expectedNodeVersion="$(cat .nvmrc | sed 's/v//')" + echo "🔎 Expected NodeJS version from .nvmrc: '$expectedNodeVersion'" + + echo "expectedNodeVersion=$expectedNodeVersion" >> $GITHUB_ENV + + - name: Initialize expected NodeJS version from package.json + if: inputs.version-source == 'package-json' + shell: bash + working-directory: tests/npm-package + run: | + rm .nvmrc + mv package.json.bak package.json + + expectedNodeVersion="$(jq -r '.engines.node' package.json)" + echo "🔎 Expected NodeJS version from package.json: '$expectedNodeVersion'" + + echo "expectedNodeVersion=$expectedNodeVersion" >> $GITHUB_ENV + + - name: The expected NodeJS version should not be running + shell: bash + working-directory: tests/npm-package + run: | + if type node &> /dev/null + then + installedNodeVersion="$(node --version | sed s/^v//)" + echo "🔎 Pre-installed NodeJS version: '$installedNodeVersion'" + + if [[ "$installedNodeVersion" != "$expectedNodeVersion" ]] + then + echo "✅ The expected NodeJS version is not running!" + else + echo "❌ The expected NodeJS version is running! This test would be pointless!" >&2 + exit 1 + fi + else + echo "✅ NodeJS not installed..." + fi + + - name: Setup NodeJS context + uses: ./actions/setup-nodejs-context + with: + project-directory: tests/npm-package + + - name: The expected NodeJS version should be in use + shell: bash + working-directory: tests/npm-package + run: | + installedNodeVersion="$(node --version | sed s/^v//)" + echo "🔎 Installed NodeJS version: '$installedNodeVersion'" + + if [[ "$installedNodeVersion" == "$expectedNodeVersion" ]] + then + echo "✅ The requested NodeJS version is being used!" + else + echo "❌ The requested NodeJS version is not running!" >&2 + exit 1 + fi diff --git a/.github/test-actions/test-setup-rust-context/action.yml b/.github/test-actions/test-setup-rust-context/action.yml new file mode 100644 index 000000000..fafdf217a --- /dev/null +++ b/.github/test-actions/test-setup-rust-context/action.yml @@ -0,0 +1,20 @@ +name: Test setup-rust-context + +runs: + using: composite + steps: + - shell: bash + run: echo "🎭 Testing on Rust crate..." + + - name: Run for Rust crate project + uses: ./actions/setup-rust-context + with: + project-directory: tests/rust-crate + + - shell: bash + run: echo "🎭 Testing on Rust Wasm..." + + - name: Run for Rust web assembly project + uses: ./actions/setup-rust-context + with: + project-directory: tests/rust-wasm diff --git a/.github/test-actions/test-tag-and-release/action.yml b/.github/test-actions/test-tag-and-release/action.yml index 688afc640..a1756cec2 100644 --- a/.github/test-actions/test-tag-and-release/action.yml +++ b/.github/test-actions/test-tag-and-release/action.yml @@ -4,7 +4,7 @@ runs: using: composite steps: - shell: bash - run: echo "🎭Testing the creation of a 'draft' release in dry-run, without notes processor..." + run: echo "🎭 Testing the creation of a 'draft' release in dry-run, without notes processor..." - name: Draft a release id: draft-release-without-major @@ -19,18 +19,18 @@ runs: shell: bash run: | majorTag="${{ steps.draft-release-without-major.outputs.major-tag }}" - echo "🔎Major tag: '$majorTag'" + echo "🔎 Major tag: '$majorTag'" if [[ -z "$majorTag" ]] then - echo "✅The major tag is empty, as expected, because it was not requested!" + echo "✅ The major tag is empty, as expected, because it was not requested!" else - echo "❌The major tag should be empty when not requested!" >&2 + echo "❌ The major tag should be empty when not requested!" >&2 exit 1 fi - shell: bash - run: echo "🎭Testing the creation of a release in dry-run, with notes processor..." + run: echo "🎭 Testing the creation of a release in dry-run, with notes processor..." - name: Publish a release id: publish-release @@ -39,7 +39,7 @@ runs: dry-run: true draft-release: false set-major-tag: true - notes-file-processor: .github/process-release-notes.sh + notes-file-processor: .github/process-release-notes git-strategy: rebase - uses: ./actions/detect-branch-version @@ -49,32 +49,32 @@ runs: shell: bash run: | branchVersion="${{ steps.version-detector.outputs.version }}" - echo "🔎Branch version: '$branchVersion'" + echo "🔎 Branch version: '$branchVersion'" releaseTag="${{ steps.publish-release.outputs.release-tag }}" - echo "🔎Release tag: '$releaseTag'" + echo "🔎 Release tag: '$releaseTag'" if [[ "$releaseTag" == "v$branchVersion" ]] then - echo "✅The release tag derives from the current branch version!" + echo "✅ The release tag derives from the current branch version!" else - echo "❌The release tag does not derive from the current branch version!" >&2 + echo "❌ The release tag does not derive from the current branch version!" >&2 exit 1 fi - - name: Verify the major tag is correct when it was requested + - name: Verify the major tag is correct, as it was requested shell: bash run: | majorVersion="${{ steps.version-detector.outputs.major }}" - echo "🔎Major version: '$majorVersion'" + echo "🔎 Major version: '$majorVersion'" majorTag="${{ steps.publish-release.outputs.major-tag }}" - echo "🔎Major tag: '$majorTag'" + echo "🔎 Major tag: '$majorTag'" if [[ "$majorTag" == "v$majorVersion" ]] then - echo "✅The major tag derives from the current major version!" + echo "✅ The major tag derives from the current major version!" else - echo "❌The major tag does not derive from the current major version!" >&2 + echo "❌ The major tag does not derive from the current major version!" >&2 exit 1 fi diff --git a/.github/test-actions/test-upload-release-assets/action.yml b/.github/test-actions/test-upload-release-assets/action.yml index 123c1d73d..f33d166db 100644 --- a/.github/test-actions/test-upload-release-assets/action.yml +++ b/.github/test-actions/test-upload-release-assets/action.yml @@ -13,30 +13,34 @@ runs: - shell: bash run: | - echo "🧹Preventively deleting the '$tag' release and its tag, if existing..." + echo "🧹 Preventively deleting the '$tag' release and its tag, if existing..." if gh release delete --cleanup-tag --yes "$tag" > /dev/null 2>&1 then - echo "✅Pre-existing test release and tag deleted!" + echo "✅ Pre-existing test release does not exist now!" fi + + git tag --delete "$tag" > /dev/null 2>&1 || true + git push origin --delete "$tag" > /dev/null 2>&1 || true + echo "✅ Pre-existing tag does not exist now!" env: GH_TOKEN: ${{ github.token }} - shell: bash run: | - echo "📝Now creating a '$tag' tag just for the tests..." + echo "📝 Now creating a '$tag' tag just for the tests..." git tag -f "$tag" git push origin "$tag" - echo "✅Test tag created!" + echo "✅ Test tag created!" - echo "📝Now creating a '$tag' draft release just for the tests..." + echo "📝 Now creating a '$tag' draft release just for the tests..." gh release create "$tag" --draft --title "Test release" --notes "This volatile release is only used by the tests!" - echo "✅Test release created!" + echo "✅ Test release created!" env: GH_TOKEN: ${{ github.token }} - shell: bash - run: echo "🎭Uploading a single asset..." + run: echo "🎭 Uploading a single asset..." - uses: ./actions/upload-release-assets with: @@ -45,16 +49,16 @@ runs: files: index.html - shell: bash - run: echo "🎭Uploading multiple assets - also using quotes..." + run: echo "🎭 Uploading multiple assets..." - uses: ./actions/upload-release-assets with: release-tag: ${{ env.tag }} source-directory: website/nextjs/public - files: next.svg 'favicon.png' + files: next.svg, favicon.png - shell: bash - run: echo "🎭Re-uploading one of the previous assets..." + run: echo "🎭 Re-uploading one of the previous assets..." - uses: ./actions/upload-release-assets with: @@ -64,7 +68,7 @@ runs: overwrite: true - shell: bash - run: echo "🎭Downloading the uploaded assets..." + run: echo "🎭 Downloading the uploaded assets..." - shell: bash run: | @@ -76,7 +80,7 @@ runs: GH_TOKEN: ${{ github.token }} - shell: bash - run: echo "🎭Checking the integrity of the downloaded assets..." + run: echo "🎭 Checking the integrity of the downloaded assets..." - shell: bash run: | @@ -89,9 +93,9 @@ runs: if cmp -s "$downloadedFile" "$originalFile" then - echo "✅Asset '$fileName' is OK!" + echo "✅ Asset '$fileName' from '$sourceDirectory' is OK!" else - echo "❌Asset '$fileName' is corrupted!" + echo "❌ Asset '$fileName' from '$sourceDirectory' is corrupted!" exit 1 fi } @@ -102,8 +106,8 @@ runs: - shell: bash run: | - echo "🚮Now deleting the '$tag' release and its tag..." + echo "🚮 Now deleting the '$tag' release and its tag..." gh release delete --cleanup-tag --yes "$tag" - echo "✅Test release and tag deleted!" + echo "✅ Test release and tag deleted!" env: GH_TOKEN: ${{ github.token }} diff --git a/.github/test-actions/test-verify-elvish-package/action.yml b/.github/test-actions/test-verify-elvish-package/action.yml new file mode 100644 index 000000000..38ca07f76 --- /dev/null +++ b/.github/test-actions/test-verify-elvish-package/action.yml @@ -0,0 +1,8 @@ +name: Test verify-elvish-package + +runs: + using: composite + steps: + - uses: ./actions/verify-elvish-package + with: + project-directory: tests/elvish-library diff --git a/.github/test-actions/test-verify-jvm-project/action.yml b/.github/test-actions/test-verify-jvm-project/action.yml index b7bddfebf..f6a9ce3c3 100644 --- a/.github/test-actions/test-verify-jvm-project/action.yml +++ b/.github/test-actions/test-verify-jvm-project/action.yml @@ -4,23 +4,24 @@ runs: using: composite steps: - shell: bash - run: echo "🎭Displaying JVM versions..." + run: echo "🎭 Displaying JVM versions..." - shell: bash run: | - echo "☕Java version: $(java --version | head -n 1)" + echo "☕ Java version: $(java --version | head -n 1)" - echo "🪶Maven version: $(mvn --version | head -n 1)" + echo "🪶 Maven version: $(mvn --version | head -n 1)" - echo "🐘Gradle version: $(gradle --version | grep -P '^Gradle \d+\.\d+(\.\d+)?$' | head -n 1 | cut -d ' ' -f 2)" + echo "🐘 Gradle version: $(gradle --version | grep -P '^Gradle \d+\.\d+(\.\d+)?$' | head -n 1 | cut -d ' ' -f 2)" - uses: ./actions/detect-branch-version id: version-detector - shell: bash - run: echo "🎭Build and verify the Maven project..." + run: echo "🎭 Build and verify the Maven project..." - - uses: ./actions/verify-jvm-project + - name: Build and verify the Maven project + uses: ./actions/verify-jvm-project with: project-directory: tests/maven-project @@ -32,18 +33,18 @@ runs: programOutput="$(java -jar target/maven-project-$version.jar)" - echo "🔎Maven program output: '$programOutput'" + echo "🔎 Maven program output: '$programOutput'" if [[ "$programOutput" == "Hello, world - from Kotlin and Maven! 🥳" ]] then - echo "🪶Maven project verified and run successfully!" + echo "🪶 Maven project verified and run successfully!" else - echo "❌Unexpected program output!" >&2 + echo "❌ Unexpected program output!" >&2 exit 1 fi - shell: bash - run: echo "🎭Build and verify the Gradle project..." + run: echo "🎭 Build and verify the Gradle project..." - name: Build and verify the Gradle project uses: ./actions/verify-jvm-project @@ -58,12 +59,12 @@ runs: programOutput="$(java -jar build/libs/gradle-project-$version.jar)" - echo "🔎Gradle program output: '$programOutput'" + echo "🔎 Gradle program output: '$programOutput'" if [[ "$programOutput" == "Hello, world - from Kotlin and Gradle! 🥳" ]] then - echo "🐘Gradle project verified and run successfully!" + echo "🐘 Gradle project verified and run successfully!" else - echo "❌Unexpected program output!" >&2 + echo "❌ Unexpected program output!" >&2 exit 1 fi diff --git a/.github/test-actions/test-verify-python-package/action.yml b/.github/test-actions/test-verify-python-package/action.yml index b2f310cc6..dc049baa3 100644 --- a/.github/test-actions/test-verify-python-package/action.yml +++ b/.github/test-actions/test-verify-python-package/action.yml @@ -4,7 +4,7 @@ runs: using: composite steps: - shell: bash - run: echo "🎭Verifying 🐍Python library..." + run: echo "🎭 Verifying 🐍 Python library..." - uses: ./actions/verify-python-package with: diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index b01c1e16f..5d239abef 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -13,5 +13,3 @@ jobs: with: set-major-tag: true notes-file-processor: .github/process-release-notes.sh - git-strategy: rebase - draft-release: true diff --git a/.github/workflows/verify.yml b/.github/workflows/verify.yml index 0c96eedfa..3159c9513 100644 --- a/.github/workflows/verify.yml +++ b/.github/workflows/verify.yml @@ -1,4 +1,5 @@ name: Verify +description: Runs the entire test network for the project. on: pull_request: @@ -8,25 +9,51 @@ on: jobs: test-setup-elvish-context: + if: false runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 + - uses: ./.github/test-actions/test-setup-elvish-context + with: + skip-if-existing: false test-setup-elvish-context-in-subsequent-job: + if: false runs-on: ubuntu-24.04 needs: test-setup-elvish-context steps: - uses: actions/checkout@v4 + + - uses: ./.github/test-actions/test-setup-elvish-context + with: + skip-if-existing: true + + - uses: ./.github/test-actions/test-setup-elvish-context + with: + skip-if-existing: true + + test-setup-elvish-package: + if: ${{ always() }} + runs-on: ubuntu-24.04 + needs: test-setup-elvish-context-in-subsequent-job + steps: + - uses: actions/checkout@v4 + - uses: ./actions/setup-elvish-context + - uses: ./.github/test-actions/test-setup-elvish-package + test-detect-branch-version: + if: false runs-on: ubuntu-24.04 + needs: test-setup-elvish-package steps: - uses: actions/checkout@v4 - uses: ./.github/test-actions/test-detect-branch-version test-check-action-references: + if: false runs-on: ubuntu-24.04 needs: test-detect-branch-version steps: @@ -34,6 +61,7 @@ jobs: - uses: ./actions/check-action-references test-check-project-license: + if: false runs-on: ubuntu-24.04 needs: test-check-action-references steps: @@ -41,6 +69,7 @@ jobs: - uses: ./.github/test-actions/test-check-project-license test-enforce-branch-version: + if: false runs-on: ubuntu-24.04 needs: test-check-action-references steps: @@ -48,262 +77,320 @@ jobs: - uses: ./.github/test-actions/test-enforce-branch-version test-find-critical-todos: + if: false runs-on: ubuntu-24.04 needs: test-check-action-references steps: - uses: actions/checkout@v4 - uses: ./.github/test-actions/test-find-critical-todos - test-tag-and-release: + test-install-wasm-pack: + if: false runs-on: ubuntu-24.04 needs: test-check-action-references steps: - uses: actions/checkout@v4 - - uses: ./.github/test-actions/test-tag-and-release + - uses: ./.github/test-actions/test-install-wasm-pack - test-install-wasm-pack: + test-setup-rust-context: + if: false runs-on: ubuntu-24.04 needs: test-check-action-references steps: - uses: actions/checkout@v4 - - uses: ./.github/test-actions/test-install-wasm-pack + - uses: ./.github/test-actions/test-setup-rust-context - test-check-rust-versions: + test-extract-rust-snippets: + if: false runs-on: ubuntu-24.04 needs: test-check-action-references steps: - uses: actions/checkout@v4 - - uses: ./.github/test-actions/test-check-rust-versions + - uses: ./.github/test-actions/test-extract-rust-snippets - test-extract-rust-snippets: + test-parse-npm-scope: + if: false runs-on: ubuntu-24.04 needs: test-check-action-references steps: - uses: actions/checkout@v4 - - uses: ./.github/test-actions/test-extract-rust-snippets + - uses: ./.github/test-actions/test-parse-npm-scope - test-verify-npm-package: + test-install-system-packages: + if: false runs-on: ubuntu-24.04 - needs: - - test-check-project-license - - test-enforce-branch-version - - test-find-critical-todos - - test-check-subpath-exports - - test-setup-nodejs-context - - test-run-custom-tests + needs: test-check-action-references steps: - uses: actions/checkout@v4 - - uses: ./.github/test-actions/test-verify-npm-package + - uses: ./.github/test-actions/test-install-system-packages - test-publish-npm-package: + test-inject-subpath-exports: + if: false runs-on: ubuntu-24.04 - needs: - - test-enforce-branch-version - - test-setup-nodejs-context - - test-publish-github-pages + needs: test-check-action-references steps: - uses: actions/checkout@v4 - - uses: ./.github/test-actions/test-publish-npm-package + - uses: ./.github/test-actions/test-inject-subpath-exports - test-verify-rust-crate: + test-check-subpath-exports: + if: false runs-on: ubuntu-24.04 - needs: - - test-check-project-license - - test-check-rust-versions - - test-enforce-branch-version - - test-find-critical-todos - - test-extract-rust-snippets + needs: test-check-action-references steps: - uses: actions/checkout@v4 - - uses: ./.github/test-actions/test-verify-rust-crate + - uses: ./.github/test-actions/test-check-subpath-exports - test-publish-rust-crate: + test-setup-nodejs-context: + if: false runs-on: ubuntu-24.04 - needs: - - test-publish-github-pages - - test-enforce-branch-version + needs: test-check-action-references steps: - uses: actions/checkout@v4 - - uses: ./.github/test-actions/test-publish-rust-crate + - uses: ./.github/test-actions/test-setup-nodejs-context - test-parse-npm-scope: + test-run-shell-script: + if: false runs-on: ubuntu-24.04 needs: test-check-action-references steps: - uses: actions/checkout@v4 - - uses: ./.github/test-actions/test-parse-npm-scope + - uses: ./.github/test-actions/test-run-shell-script - test-generate-wasm-target: + test-upload-release-assets: + if: false runs-on: ubuntu-24.04 - needs: test-parse-npm-scope + needs: test-check-action-references steps: - uses: actions/checkout@v4 - - uses: ./.github/test-actions/test-generate-wasm-target + - uses: ./.github/test-actions/test-upload-release-assets - test-verify-rust-wasm: + test-install-via-sdkman: + if: false runs-on: ubuntu-24.04 - needs: - - test-check-project-license - - test-verify-rust-crate - - test-install-wasm-pack - - test-generate-wasm-target - - test-run-custom-tests + needs: test-check-action-references steps: - uses: actions/checkout@v4 - - uses: ./.github/test-actions/test-verify-rust-wasm + - uses: ./.github/test-actions/test-install-via-sdkman - test-publish-rust-wasm: + test-verify-python-package: + if: false runs-on: ubuntu-24.04 needs: - - test-install-wasm-pack - - test-generate-wasm-target - - test-publish-npm-package + - test-check-project-license + - test-enforce-branch-version + - test-find-critical-todos steps: - uses: actions/checkout@v4 - - uses: ./.github/test-actions/test-publish-rust-wasm + - uses: ./.github/test-actions/test-verify-python-package - test-verify-jvm-project: + test-verify-rust-crate: + if: false runs-on: ubuntu-24.04 needs: - test-check-project-license + - test-setup-rust-context - test-enforce-branch-version - test-find-critical-todos - - test-install-via-sdkman + - test-extract-rust-snippets steps: - uses: actions/checkout@v4 - - uses: ./.github/test-actions/test-verify-jvm-project + - uses: ./.github/test-actions/test-verify-rust-crate - test-publish-jvm-project: + test-generate-wasm-target: + if: false runs-on: ubuntu-24.04 needs: + - test-parse-npm-scope - test-enforce-branch-version - - test-install-via-sdkman steps: - uses: actions/checkout@v4 - - uses: ./.github/test-actions/test-publish-jvm-project - with: - jvm-token: ${{ secrets.JVM_TOKEN }} + - uses: ./.github/test-actions/test-generate-wasm-target - test-verify-python-package: + test-publish-github-pages: + if: false runs-on: ubuntu-24.04 needs: - - test-check-project-license + - test-setup-nodejs-context - test-enforce-branch-version - - test-find-critical-todos + permissions: + pages: write + id-token: write steps: - uses: actions/checkout@v4 - - uses: ./.github/test-actions/test-verify-python-package + - uses: ./.github/test-actions/test-publish-github-pages - test-publish-python-package: + test-tag-and-release: + if: false + runs-on: ubuntu-24.04 + needs: test-run-shell-script + steps: + - uses: actions/checkout@v4 + - uses: ./.github/test-actions/test-tag-and-release + + test-run-custom-tests: + if: false runs-on: ubuntu-24.04 needs: + - test-run-shell-script + - test-setup-nodejs-context + - test-setup-rust-context + steps: + - uses: actions/checkout@v4 + - uses: ./.github/test-actions/test-run-custom-tests + + test-verify-jvm-project: + if: false + runs-on: ubuntu-24.04 + needs: + - test-check-project-license - test-enforce-branch-version - - test-publish-github-pages + - test-find-critical-todos + - test-install-via-sdkman steps: - uses: actions/checkout@v4 - - uses: ./.github/test-actions/test-publish-python-package - with: - index-secret: ${{ secrets.PY_TOKEN }} + - uses: ./.github/test-actions/test-verify-jvm-project - test-install-system-packages: + test-publish-rust-crate: + if: false runs-on: ubuntu-24.04 - needs: test-check-action-references + needs: + - test-setup-rust-context + - test-publish-github-pages + - test-enforce-branch-version + - test-verify-rust-crate steps: - uses: actions/checkout@v4 - - uses: ./.github/test-actions/test-install-system-packages + - uses: ./.github/test-actions/test-publish-rust-crate - test-inject-subpath-exports: + test-publish-python-package: + if: false runs-on: ubuntu-24.04 - needs: test-check-action-references + needs: + - test-enforce-branch-version + - test-publish-github-pages + - test-verify-python-package steps: - uses: actions/checkout@v4 - - uses: ./.github/test-actions/test-inject-subpath-exports + - uses: ./.github/test-actions/test-publish-python-package + with: + index-secret: FAKE-SECRET - test-check-subpath-exports: + test-verify-npm-package: + if: false runs-on: ubuntu-24.04 - needs: test-check-action-references + needs: + - test-check-project-license + - test-enforce-branch-version + - test-find-critical-todos + - test-check-subpath-exports + - test-setup-nodejs-context + - test-run-custom-tests steps: - uses: actions/checkout@v4 - - uses: ./.github/test-actions/test-check-subpath-exports + - uses: ./.github/test-actions/test-verify-npm-package - test-setup-nodejs-context: + test-verify-rust-wasm: + if: false runs-on: ubuntu-24.04 - needs: test-check-action-references + needs: + - test-check-project-license + - test-verify-rust-crate + - test-install-wasm-pack + - test-generate-wasm-target + - test-run-custom-tests steps: - uses: actions/checkout@v4 - - uses: ./.github/test-actions/test-setup-nodejs-context + - uses: ./.github/test-actions/test-verify-rust-wasm - test-publish-github-pages: + test-publish-jvm-project: + if: false runs-on: ubuntu-24.04 needs: - - test-setup-nodejs-context - test-enforce-branch-version - permissions: - pages: write - id-token: write + - test-install-via-sdkman + - test-verify-jvm-project + - test-publish-github-pages steps: - uses: actions/checkout@v4 - - uses: ./.github/test-actions/test-publish-github-pages + - uses: ./.github/test-actions/test-publish-jvm-project + with: + jvm-token: FAKE_TOKEN - test-run-custom-tests: + test-publish-npm-package: + if: false runs-on: ubuntu-24.04 needs: + - test-enforce-branch-version - test-setup-nodejs-context - - test-check-rust-versions + - test-publish-github-pages + - test-verify-npm-package steps: - uses: actions/checkout@v4 - - uses: ./.github/test-actions/test-run-custom-tests + - uses: ./.github/test-actions/test-publish-npm-package - test-upload-release-assets: + test-publish-rust-wasm: + if: false runs-on: ubuntu-24.04 - needs: test-check-action-references + needs: + - test-install-wasm-pack + - test-generate-wasm-target + - test-publish-npm-package + - test-verify-rust-wasm steps: - uses: actions/checkout@v4 - - uses: ./.github/test-actions/test-upload-release-assets + - uses: ./.github/test-actions/test-publish-rust-wasm - test-install-via-sdkman: + test-verify-elvish-package: + if: false runs-on: ubuntu-24.04 - needs: test-check-action-references + needs: + - test-check-project-license + - test-run-custom-tests + - test-find-critical-todos steps: - uses: actions/checkout@v4 - - uses: ./.github/test-actions/test-install-via-sdkman + - uses: ./.github/test-actions/test-verify-elvish-package verify: + if: ${{ always() }} runs-on: ubuntu-24.04 needs: - test-setup-elvish-context - test-setup-elvish-context-in-subsequent-job + - test-setup-elvish-package - test-detect-branch-version - test-check-action-references - test-check-project-license - test-enforce-branch-version - test-find-critical-todos - - test-tag-and-release - test-install-wasm-pack - - test-check-rust-versions + - test-setup-rust-context - test-extract-rust-snippets - - test-verify-npm-package - - test-publish-npm-package - - test-verify-rust-crate - - test-publish-rust-crate - test-parse-npm-scope - - test-generate-wasm-target - - test-verify-rust-wasm - - test-publish-rust-wasm - - test-verify-jvm-project - - test-publish-jvm-project - - test-verify-python-package - - test-publish-python-package - test-install-system-packages - test-inject-subpath-exports - test-check-subpath-exports - test-setup-nodejs-context - - test-publish-github-pages - - test-run-custom-tests + - test-run-shell-script - test-upload-release-assets - test-install-via-sdkman - + - test-verify-python-package + - test-verify-rust-crate + - test-generate-wasm-target + - test-publish-github-pages + - test-tag-and-release + - test-run-custom-tests + - test-verify-jvm-project + - test-publish-rust-crate + - test-publish-python-package + - test-verify-npm-package + - test-verify-rust-wasm + - test-publish-jvm-project + - test-publish-npm-package + - test-publish-rust-wasm + - test-verify-elvish-package steps: - - name: Show completion message - shell: bash - run: echo "✅Verification complete!" + - uses: actions/checkout@v4 + - uses: ./actions/check-required-jobs + with: + needs-as-json: ${{ toJSON(needs) }} diff --git a/.lefthook/post-checkout/update-action-references.elv b/.lefthook/post-checkout/update-action-references.elv index 864d9081f..9e2c2cd5c 100755 --- a/.lefthook/post-checkout/update-action-references.elv +++ b/.lefthook/post-checkout/update-action-references.elv @@ -1,5 +1,14 @@ use str +var _ _ flag = (all $args) + +var is-branch-change = (== $flag 1) + +if (not $is-branch-change) { + echo 💡 Skipping action reference update whe not changing branch! + exit 0 +} + var branch-version = "" try { @@ -8,32 +17,32 @@ try { #Just do nothing } -if (eq $branch-version main) { - echo "💡Skipping action reference update when on main!" +echo 🌲 Branch version: "'"$branch-version"'" + +if (==s $branch-version main) { + echo 💡 Skipping action reference update when on main! exit 0 } -if (eq $branch-version "") { - echo "💡Skipping action reference update when not in a checkout/switch!" +if (==s $branch-version "") { + echo 💡 Skipping action reference update when not in a checkout/switch! exit 0 } -echo 🌲Branch version: "'"$branch-version"'" - var major-version = (str:split . $branch-version | take 1) -echo 💎Major version: "'"$major-version"'" +echo 💎 Major version: "'"$major-version"'" -put actions/**.{yml md} | each { |file-path| +put actions/**[nomatch-ok].{yml md} | peach { |file-path| sed -i -E 's/(giancosta86\/aurora-github\/actions\/[^@]+)@v[0-9]+\.[0-9]+\.[0-9]+/\1@'$branch-version'/' $file-path sed -i -E 's/(giancosta86\/aurora-github\/actions\/[^@]+)@v[0-9]+/\1@'$major-version'/' $file-path } -if (not ?(git diff --quiet)) { - echo 🧭Creating a commit to track the updated action references... - git add . - git commit -m "Update action references" - echo ✅Commit created! -} else { - echo ✅The action references are already set up! -} \ No newline at end of file +if ?(git diff --quiet) { + echo ✅ The action references are already set up! +} + +echo 🧭 Creating a commit to track the updated action references... +git add . +git commit -m "Update action references" +echo ✅ Commit created! \ No newline at end of file diff --git a/.lefthook/pre-commit/check-elvish-syntax.elv b/.lefthook/pre-commit/check-elvish-syntax.elv new file mode 100755 index 000000000..668eca9ed --- /dev/null +++ b/.lefthook/pre-commit/check-elvish-syntax.elv @@ -0,0 +1,3 @@ +put core/**.elv | peach { + |script| elvish -compileonly $script +} \ No newline at end of file diff --git a/README.md b/README.md index 422f033ea..604702117 100644 --- a/README.md +++ b/README.md @@ -1,30 +1,36 @@ # aurora-github -_Elegant workflows for GitHub Actions_ +_Elegant CI/CD for GitHub Actions_ -![Schema](docs/schema.png) +![Logo](logo.jpg) -**aurora-github** is a gallery of GitHub actions designed to create elegant and minimalist _pipelines_ for a variety of technologies - focusing on best practices such as _default branch protection_, _pull requests_ and _convention-over-configuration_. +**aurora-github** is a gallery of **GitHub actions** - based on the superlative [Elvish](https://elv.sh/) shell - designed to create _elegant_ and _minimalist_ **workflows** for a variety of technologies, while focusing on best practices such as _default branch protection_, _pull requests_ and _convention-over-configuration_. -In particular, for most actions **it is essential to name branches according to semantic versioning** - like `v4.2.7`: this ensures a smooth workflow while remaning largely compatible with other flows - for example, multiple _feature branches_ can stem from a given _version branch_. +For most of the actions, **it is essential to name branches according to semantic versioning** - like `v4.2.7`: this ensures a smooth workflow while remaining largely compatible with other flow architectures - for example, multiple _feature branches_ can stem from a given _version branch_. The actions can be grouped by technology: -## 🔮Elvish shell +## 🔮 Elvish shell - [setup-elvish-context](actions/setup-elvish-context/README.md) -## 🦀Rust +- [install-elvish-package](actions/install-elvish-package/README.md) + +- [verify-elvish-package](actions/verify-elvish-package/README.md) + +## 🦀 Rust + +- [setup-rust-context](actions/setup-rust-context/README.md) - [verify-rust-crate](actions/verify-rust-crate/README.md) - [publish-rust-crate](actions/publish-rust-crate/README.md) -- [check-rust-versions](actions/check-rust-versions/README.md) - - [extract-rust-snippets](actions/extract-rust-snippets/README.md) -## 📦NodeJS package +## 📦 NodeJS + +- [setup-nodejs-context](actions/setup-nodejs-context/README.md) - [verify-npm-package](actions/verify-npm-package/README.md) @@ -34,11 +40,9 @@ The actions can be grouped by technology: - [check-subpath-exports](actions/check-subpath-exports/README.md) -- [setup-nodejs-context](actions/setup-nodejs-context/README.md) - - [parse-npm-scope](actions/parse-npm-scope/README.md) -## 🦀Rust 🌐WebAssembly +## 🦀🌐 Rust wasm-pack - [verify-rust-wasm](actions/verify-rust-wasm/README.md) @@ -48,7 +52,7 @@ The actions can be grouped by technology: - [generate-wasm-target](actions/generate-wasm-target/README.md) -## ☕Java ecosystem +## ☕ Java Virtual Machine ecosystem - [verify-jvm-project](actions/verify-jvm-project/README.md) @@ -56,13 +60,13 @@ The actions can be grouped by technology: - [install-via-sdkman](actions/install-via-sdkman/README.md) -## 🐍Python +## 🐍 Python - [verify-python-package](actions/verify-python-package/README.md) - [publish-python-package](actions/publish-python-package/README.md) -## 😺GitHub +## 😺 GitHub - [check-action-references](actions/check-action-references/README.md) @@ -72,7 +76,9 @@ The actions can be grouped by technology: - [check-project-license](actions/check-project-license/README.md) -## 🏷️Semantic versioning +- [check-required-jobs](actions/check-required-jobs/README.md) + +## 🏷️ Semantic versioning - [detect-branch-version](actions/detect-branch-version/README.md) @@ -82,12 +88,20 @@ The actions can be grouped by technology: - [upload-release-assets](actions/upload-release-assets/README.md) -## 🧰General-purpose utilities +## 🖥 Operating-system utilities + +- [run-shell-script](actions/run-shell-script/README.md) - [find-critical-todos](actions/find-critical-todos/README.md) - [install-system-packages](actions/install-system-packages/README.md) -## 🌐Further references +## 🌐 Further references - [GitHub actions](https://docs.github.com/en/actions) + +- [Elvish](https://elv.sh/) - Powerful modern shell scripting + +- [Google Gemini](https://gemini.google.com) - used to generate the logo + +- [GIMP](https://www.gimp.org/) - used to manually retouch the logo diff --git a/actions/check-action-references/README.md b/actions/check-action-references/README.md index d916fb565..888b9e273 100644 --- a/actions/check-action-references/README.md +++ b/actions/check-action-references/README.md @@ -1,29 +1,29 @@ # check-action-references -Prevents cross-branch `uses:` directives to **GitHub** actions residing below the same root directory. +Prevents cross-branch `uses:` directives between **GitHub** actions residing below the same root directory. -## 🃏Example +## 🃏 Example ```yaml steps: - - uses: giancosta86/aurora-github/actions/check-action-references@v10 + - uses: giancosta86/aurora-github/actions/check-action-references@v11 ``` -## 💡How it works +## 💡 How it works When creating actions in a repository acting as a library for GitHub Actions, you could need to reference one action from another: this action ensures that all the above local `@` tags only reference actions on the current branch. -## ☑️Requirements +## ☑️ Requirements - The check is only performed on [composite GitHub actions](https://docs.github.com/en/actions/sharing-automations/creating-actions/creating-a-composite-action), written in files having `.yml` extension and residing below the given `actions-directory`. -## 📥Inputs +## 📥 Inputs | Name | Type | Description | Default value | | :-----------------: | :--------: | :---------------------------------------------------: | :-----------: | | `actions-directory` | **string** | The root of the directory tree containing the actions | **actions** | -## 🌐Further references +## 🌐 Further references - [Composite GitHub actions](https://docs.github.com/en/actions/sharing-automations/creating-actions/creating-a-composite-action) diff --git a/actions/check-action-references/action.yml b/actions/check-action-references/action.yml index 2f6419990..272c3f005 100644 --- a/actions/check-action-references/action.yml +++ b/actions/check-action-references/action.yml @@ -1,5 +1,5 @@ name: Check GitHub Actions references -description: Prevents cross-branch 'uses:' directives to GitHub actions residing below the same root directory. +description: Prevents cross-branch `uses:` directives between GitHub actions residing below the same root directory. inputs: actions-directory: @@ -9,19 +9,12 @@ inputs: runs: using: composite steps: - - name: Setup Python context - shell: bash - run: | - pythonPath="${{ github.action_path }}/../../core/python" - echo "PYTHONPATH=$pythonPath" >> $GITHUB_ENV - - echo "INPUT_ACTIONS_DIRECTORY=${{ inputs.actions-directory }}" >> $GITHUB_ENV + - uses: giancosta86/aurora-github/actions/setup-elvish-context@v11.0.0 - - name: Call the Python implementation - shell: python + - shell: elvish {0} + working-directory: ${{ inputs.actions-directory }} run: | - from core.check_action_references import check_action_references, Inputs - - inputs = Inputs.from_env() + use aurora-github/action-references + use aurora-github/ci-cd/input - check_action_references(inputs) + action-references:check diff --git a/actions/check-project-license/README.md b/actions/check-project-license/README.md index 539c2ffc4..4bc6e79d5 100644 --- a/actions/check-project-license/README.md +++ b/actions/check-project-license/README.md @@ -1,12 +1,12 @@ # check-project-license -Ensures the validity of the project license file. +Checks the validity of the project license file. -## 🃏Example +## 🃏 Example ```yaml steps: - - uses: giancosta86/aurora-github/actions/check-project-license@v10 + - uses: giancosta86/aurora-github/actions/check-project-license@v11 ``` **Please, note**: this action is automatically run by: @@ -21,19 +21,23 @@ steps: - [verify-python-package](../verify-python-package/README.md) -## 💡How it works +## ☑️ Requirements + +- The POSIX `date` command must be available on the system. + +## 💡 How it works 1. Check that the `license-file` path actually points to an existing file. 1. Verify that the current year is mentioned within the license file. -## 📥Inputs +## 📥 Inputs | Name | Type | Description | Default value | | :------------: | :--------: | :--------------------------: | :-----------: | | `license-file` | **string** | The path to the license file | **LICENSE** | -## 🌐Further references +## 🌐 Further references - [verify-npm-package](../verify-npm-package/README.md) diff --git a/actions/check-project-license/action.yml b/actions/check-project-license/action.yml index 10806701a..11041cca3 100644 --- a/actions/check-project-license/action.yml +++ b/actions/check-project-license/action.yml @@ -1,5 +1,5 @@ name: Check project license -description: Ensures the validity of the project license file. +description: Checks the validity of the project license file. inputs: license-file: @@ -9,46 +9,13 @@ inputs: runs: using: composite steps: - - shell: bash - run: | - licenseFile="${{ inputs.license-file }}" - - main() { - licenseFileMustExist - - licenseMustIncludeCurrentYear - } - - licenseFileMustExist() { - if [[ -f "$licenseFile" ]] - then - echo "✅License file found: $licenseFile" - else - echo "❌Missing license file: '$licenseFile'" >&2 - exit 1 - fi - } + - uses: giancosta86/aurora-github/actions/setup-elvish-context@v11.0.0 - licenseMustIncludeCurrentYear() { - currentYear="$(date +"%Y")" - - if [[ -z "$currentYear" ]] - then - echo "❌Cannot detect the current year!" >&2 - exit 1 - fi - - echo "🔎Current year: $currentYear" - - echo "🔎Searching the license file for the current year..." + - shell: elvish {0} + run: | + use aurora-github/ci-cd/input + use aurora-github/license-file - if grep --color=always "$currentYear" "$licenseFile" - then - echo "✅Current year found in the license file!" - else - echo "❌Cannot find the current year in the license file!" >&2 - exit 1 - fi - } + var license-file = (input:file license-file '${{ inputs.license-file }}') - main + license-file:check $license-file diff --git a/actions/check-required-jobs/README.md b/actions/check-required-jobs/README.md new file mode 100644 index 000000000..b2c1e1084 --- /dev/null +++ b/actions/check-required-jobs/README.md @@ -0,0 +1,60 @@ +# check-required-jobs + +Verifies that all the jobs in the `needs:` directive of the current job have completed successfully. + +## 🃏 Example + +```yaml +steps: + - uses: giancosta86/aurora-github/actions/check-required-jobs@v11 + with: + needs-as-json: ${{ toJSON(needs) }} +``` + +## 💡 How it works + +1. Extract the list of required jobs from the `needs:` directive of the **job** containing this action. + +1. Wait for all the required jobs to provide an outcome (**success**, **failure**, **skipped**). + +1. Display, within a summary, the **outcome** of each required job. + +1. Ensure that every required job: + + 1. has actually run - **skipped** jobs trigger an error just like **failed** ones. + + 1. has completed successfully. + +## 💬 Remarks + +This action is especially effective in a **job** that: + +- is declared **at the end** of its workflow. + +- references **all** the previous jobs via the `needs:` directive. + +- is flagged (the containing job, _not_ the action) with `if: ${{ always() }}`, ensuring it will always run - even if the required jobs have a **failed** or **skipped** outcome. + +### Recommended strategy + +You might want to flag **all the other jobs** in the workflow with the `if: true` flag, which has no effect; however should you need to run only a selected number of jobs (for example, while developing a feature), you can: + +1. Replace `if: true` with `if: false` to skip inessential jobs. + +1. Replace `if: true` with `if: ${{ always() }}` for the jobs you want to run - so that _they will run even though their required jobs have been skipped_. + +1. Anyway, this action acts as a barrier preventing the CI/CD branch checks to pass - because **skipped jobs result in an overall failure**. + +## ☑️ Requirements + +The job containing this action should have a `need:` list mentioning previous jobs in the workflow. + +## 📥 Inputs + +| Name | Type | Description | Default value | +| :-------------: | :--: | :--------------------------------: | :-----------: | +| `needs-as-json` | | Always pass `${{ toJSON(needs) }}` | | + +## 🌐 Further references + +- [aurora-github](../../README.md) diff --git a/actions/check-required-jobs/action.yml b/actions/check-required-jobs/action.yml new file mode 100644 index 000000000..3feb7e102 --- /dev/null +++ b/actions/check-required-jobs/action.yml @@ -0,0 +1,21 @@ +name: Check required jobs +description: Verifies that all the jobs in the `needs:` directive of the current job have completed successfully. + +inputs: + needs-as-json: + description: Always pass the evaluation of `toJSON(needs)`. + +runs: + using: composite + steps: + - uses: giancosta86/aurora-github/actions/setup-elvish-context@v11.0.0 + + - name: Check the required jobs + shell: elvish {0} + run: | + use aurora-github/ci-cd/input + use aurora-github/ci-cd/required-jobs + + var needs-as-json = (input:string needs-as-json '${{ inputs.needs-as-json }}') + + required-jobs:check $needs-as-json diff --git a/actions/check-rust-versions/README.md b/actions/check-rust-versions/README.md deleted file mode 100644 index 37d50ca95..000000000 --- a/actions/check-rust-versions/README.md +++ /dev/null @@ -1,35 +0,0 @@ -# check-rust-versions - -Displays the current version of the main **Rust** components, after ensuring that `rust-toolchain.toml` is in the project directory. - -## 🃏Example - -```yaml -steps: - - uses: giancosta86/aurora-github/actions/check-rust-versions@v10 -``` - -**Please, note**: this action is automatically run by [verify-rust-crate](../verify-rust-crate/README.md). - -## ☑️Requirements - -- the [toolchain file](https://rust-lang.github.io/rustup/overrides.html#the-toolchain-file) file must exist within `project-directory`. - - It should include at least the required toolchain version, for example: - - ```toml - [toolchain] - channel = "1.80.0" - ``` - -## 📥Inputs - -| Name | Type | Description | Default value | -| :-----------------: | :--------: | :-----------------------------------------: | :-----------: | -| `project-directory` | **string** | The directory containing the toolchain file | **.** | - -## 🌐Further references - -- [verify-rust-crate](../verify-rust-crate/README.md) - -- [aurora-github](../../README.md) diff --git a/actions/check-rust-versions/action.yml b/actions/check-rust-versions/action.yml deleted file mode 100644 index 40297fc20..000000000 --- a/actions/check-rust-versions/action.yml +++ /dev/null @@ -1,41 +0,0 @@ -name: Check Rust version info -description: Displays the versions of the main Rust components, after ensuring that 'rust-toolchain.toml' is in the project directory. - -inputs: - project-directory: - description: The directory containing the toolchain file. - default: "." - -runs: - using: composite - steps: - - shell: bash - working-directory: ${{ inputs.project-directory }} - run: | - main() { - checkToolchainFile - printToolVersions - } - - checkToolchainFile() { - local toolchainFile="rust-toolchain.toml" - - if [[ -f "$toolchainFile" ]] - then - echo "✅Toolchain file found: $toolchainFile" - else - echo "❌Missing toolchain file: '$toolchainFile'" >&2 - exit 1 - fi - } - - printToolVersions() { - echo "🦀Rust toolchain versions:" - cargo --version - rustc --version - cargo fmt --version - cargo clippy --version - echo "🦀🦀🦀" - } - - main \ No newline at end of file diff --git a/actions/check-subpath-exports/README.md b/actions/check-subpath-exports/README.md index 4886d94ae..fc7008ea1 100644 --- a/actions/check-subpath-exports/README.md +++ b/actions/check-subpath-exports/README.md @@ -2,26 +2,26 @@ Verifies that all the [subpath exports](https://nodejs.org/api/packages.html#subpath-exports) in **package.json** actually match existing files. -## 🃏Example +## 🃏 Example ```yaml steps: - - uses: giancosta86/aurora-github/actions/check-subpath-exports@v10 + - uses: giancosta86/aurora-github/actions/check-subpath-exports@v11 ``` **Please, note**: this action is automatically run by [verify-npm-package](../verify-npm-package/README.md). -## ☑️Requirements +## ☑️ Requirements - The `jq` command (especially version **1.7**) must be available in the operating system. -## 📥Inputs +## 📥 Inputs | Name | Type | Description | Default value | | :-----------------: | :--------: | :-------------------------------------: | :-----------: | | `project-directory` | **string** | The directory containing `package.json` | **.** | -## 🌐Further references +## 🌐 Further references - [package.json - subpath exports](https://nodejs.org/api/packages.html#subpath-exports) diff --git a/actions/check-subpath-exports/action.yml b/actions/check-subpath-exports/action.yml index 9030edba2..06e67c516 100644 --- a/actions/check-subpath-exports/action.yml +++ b/actions/check-subpath-exports/action.yml @@ -3,95 +3,17 @@ description: Verifies that all the subpath exports in package.json actually matc inputs: project-directory: - description: The directory containing package.json. - default: "." + description: The directory containing `package.json`. + default: . runs: using: composite steps: - - shell: bash + - uses: giancosta86/aurora-github/actions/setup-elvish-context@v11.0.0 + + - shell: elvish {0} working-directory: ${{ inputs.project-directory }} run: | - main() { - validateInputs - - inspectRecursively - - echo "✅Export subpaths are OK!" - } - - validateInputs() { - if [[ ! -f "package.json" ]] - then - echo "❌The package.json descriptor file does not exist!" >&2 - exit 1 - fi - } - - inspectRecursively() { - local exports="$(jq -r '.exports' package.json)" - - if [[ "$exports" == "null" ]] - then - echo "💭No exports declared in package.json..." - exit 0 - fi - - echo "🔎 Now inspecting subpath exports..." - - checkJsonValue "exports" "$exports" - } - - checkJsonValue() { - local positionInJson="$1" - local jsonValue="$2" - - if isJsonObject "$jsonValue" - then - checkJsonObject "$positionInJson" "$jsonValue" - else - checkFilePattern "$positionInJson" "$jsonValue" - fi - } - - isJsonObject() { - local jsonValue="$1" - - if [[ "$jsonValue" =~ ^\{ ]] - then - return 0 - else - return 1 - fi - } - - checkJsonObject() { - local positionInJson="$1" - local jsonObject="$2" - - echo "$jsonObject" | jq -r '. | keys[]' | while IFS= read -r key - do - local jsonValue="$(echo "$jsonObject" | jq -r '.["'$key'"]')" - checkJsonValue "$positionInJson -> $key" "$jsonValue" - done - } - - checkFilePattern() { - local positionInJson="$1" - local filePattern="$2" - - echo -n "🔎 $positionInJson -> $filePattern... " - - local matches="$(find . -wholename "$filePattern" | wc -l)" - - if [[ "$matches" == 0 ]] - then - echo "❌" - echo "❌No file matching subpath pattern: '$filePattern'" - exit 1 - else - echo "✅" - fi - } + use aurora-github/nodejs/subpath-exports - main + subpath-exports:check diff --git a/actions/detect-branch-version/README.md b/actions/detect-branch-version/README.md index e9ecdb24c..adc98e817 100644 --- a/actions/detect-branch-version/README.md +++ b/actions/detect-branch-version/README.md @@ -1,35 +1,26 @@ # detect-branch-version -Extracts the version from the name of the current **Git** branch, returning both. +Extracts the version from the name of the current **Git** branch, returning a variety of info. -## 🃏Example +## 🃏 Example ```yaml steps: - id: detector - uses: giancosta86/aurora-github/actions/detect-branch-version@v10 - - - run: | - branch="${{ steps.detector.outputs.branch }}" - version="${{ steps.detector.outputs.version }}" - escapedVersion="${{ steps.detector.outputs.escaped-version }}" - major="${{ steps.detector.outputs.major }}" - - echo "🔎Detected version '$version' (escaped: '${escapedVersion}') from branch '$branch'" - echo "🔎Major component: '${major}'" + uses: giancosta86/aurora-github/actions/detect-branch-version@v11 ``` -## ☑️Requirements +## ☑️ Requirements - **Essential**: the branch name must have a [semantic version](https://semver.org/) format, optionally preceded by `v`. For example: `v1.0.2`. - the branch name is read from `github.head_ref` if such variable is available - because the action is especially designed for pull-request workflows - and from `github.ref` otherwise. -## 📥Inputs +## 📥 Inputs _No inputs required._ -## 📤Outputs +## 📤 Outputs | Name | Type | Description | Example | | :---------------: | :--------: | :----------------------------------------------------------: | :---------: | @@ -38,7 +29,7 @@ _No inputs required._ | `escaped-version` | **string** | The escaped version - for regular expressions | **2\.4\.8** | | `major` | **string** | The `major` component of the version | **2** | -## 🌐Further references +## 🌐 Further references - [semantic version](https://semver.org/) diff --git a/actions/detect-branch-version/action.yml b/actions/detect-branch-version/action.yml index b2c59b7d6..7eb1d384e 100644 --- a/actions/detect-branch-version/action.yml +++ b/actions/detect-branch-version/action.yml @@ -1,5 +1,5 @@ name: Detect branch version -description: Extracts the version from the name of the current Git branch, returning both. +description: Extracts the version from the name of the current Git branch, returning a variety of info. outputs: branch: @@ -11,26 +11,22 @@ outputs: value: ${{ steps.detect-version.outputs.version }} escaped-version: - description: The escaped version - for example, with '\.' in lieu of '.' - suitable for regular expressions. + description: The escaped version - for example, with `\.` in lieu of `.` - suitable for regular expressions. value: ${{ steps.detect-version.outputs.escaped-version }} major: - description: The 'major' component of the version. + description: The `major` component of the version. value: ${{ steps.detect-version.outputs.major }} runs: using: composite steps: - - name: Setup Python context - shell: bash - run: | - pythonPath="${{ github.action_path }}/../../core/python" - echo "PYTHONPATH=$pythonPath" >> $GITHUB_ENV + - uses: giancosta86/aurora-github/actions/setup-elvish-context@v11.0.0 - - name: Call the Python implementation - id: detect-version - shell: python + - id: detect-version + shell: elvish {0} run: | - from core.detect_branch_version import detect_branch_version_info + use aurora-github/branch-version/detection + use aurora-github/ci-cd/output - detect_branch_version_info().write_to_github_output() + output:map (detection:detect) diff --git a/actions/enforce-branch-version/README.md b/actions/enforce-branch-version/README.md index 8eef11ff7..9f5bd7d06 100644 --- a/actions/enforce-branch-version/README.md +++ b/actions/enforce-branch-version/README.md @@ -2,11 +2,11 @@ Ensures that the version in the artifact descriptor matches the **Git** branch version - by injecting or merely by checking. -## 🃏Example +## 🃏 Example ```yaml steps: - - uses: giancosta86/aurora-github/actions/enforce-branch-version@v10 + - uses: giancosta86/aurora-github/actions/enforce-branch-version@v11 with: mode: inject ``` @@ -37,7 +37,7 @@ and indirectly by: - [publish-rust-wasm](../publish-rust-wasm/README.md) -## 💡How it works +## 💡 How it works 1. If `mode` is **skip**, just exit the action flow. @@ -79,11 +79,11 @@ and indirectly by: - for any other technology, verify that the branch version exists at least once in the descriptor -## ☑️Requirements +## ☑️ Requirements - The `artifact-descriptor` - no matter whether declared or detected - must exist in the file system. -## 📥Inputs +## 📥 Inputs | Name | Type | Description | Default value | | :-------------------: | :---------------------: | :---------------------------------------: | :-----------: | @@ -91,7 +91,7 @@ and indirectly by: | `artifact-descriptor` | **string** | Relative path to the artifact descriptor | | | `project-directory` | **string** | The directory containing the project | **.** | -## 🌐Further references +## 🌐 Further references - [verify-npm-package](../verify-npm-package/README.md) diff --git a/actions/enforce-branch-version/action.yml b/actions/enforce-branch-version/action.yml index 836227754..93cea9444 100644 --- a/actions/enforce-branch-version/action.yml +++ b/actions/enforce-branch-version/action.yml @@ -3,7 +3,7 @@ description: Ensures that the version in the artifact descriptor matches the Git inputs: mode: - description: How to enforce the branch version. Can be "inject", "check" or "skip". + description: How to enforce the branch version. Can be `inject`, `check` or `skip`. artifact-descriptor: description: Relative path to the artifact descriptor. @@ -15,21 +15,16 @@ inputs: runs: using: composite steps: - - name: Setup Python context - shell: bash - run: | - pythonPath="${{ github.action_path }}/../../core/python" - echo "PYTHONPATH=$pythonPath" >> $GITHUB_ENV - - echo "INPUT_MODE=${{ inputs.mode }}" >> $GITHUB_ENV - echo "INPUT_ARTIFACT_DESCRIPTOR=${{ inputs.artifact-descriptor }}" >> $GITHUB_ENV - echo "INPUT_PROJECT_DIRECTORY=${{ inputs.project-directory }}" >> $GITHUB_ENV + - uses: giancosta86/aurora-github/actions/setup-elvish-context@v11.0.0 - - name: Call the Python implementation - shell: python + - shell: elvish {0} + working-directory: ${{ inputs.project-directory }} run: | - from core.enforce_branch_version import enforce_branch_version, Inputs + use aurora-github/ci-cd/input + use aurora-github/branch-version/enforcement + + var mode = (input:enum mode '${{ inputs.mode }}' [inject check skip]) - inputs = Inputs.from_env() + var artifact-descriptor = (input:file &optional artifact-descriptor '${{ inputs.artifact-descriptor }}') - enforce_branch_version(inputs) + enforcement:enforce &descriptor-name=$artifact-descriptor $mode diff --git a/actions/extract-rust-snippets/README.md b/actions/extract-rust-snippets/README.md index 49a1da7eb..51a6d45f2 100644 --- a/actions/extract-rust-snippets/README.md +++ b/actions/extract-rust-snippets/README.md @@ -1,36 +1,19 @@ # extract-rust-snippets -Extracts **Rust** code snippets from a **Markdown** file to standalone test files. +Extracts **Rust** test snippets from a **Markdown** file to standalone test files. -## 🃏Example +## 🃏 Example ```yaml steps: - - uses: giancosta86/aurora-github/actions/extract-rust-snippets@v10 + - uses: giancosta86/aurora-github/actions/extract-rust-snippets@v11 ``` **Please, note**: this action is automatically run by [verify-rust-crate](../verify-rust-crate/README.md). -## ☑️Requirements +## 💡 How it works -- each code snippet must reside in a ` ```rust` code block and must define a `main()`function returning a type supporting`.unwrap()`, such as `Result<(), Box`: - - ```rust - //Required imports here - use std::error::Error; - - fn main() -> Result<(), Box> { - //Code with assertions here - - Ok(()) - } - ``` - -- the Markdown file must exist unless `optional` is set to **true**, but it is never required to contain code snippets: in this case, no test file will be generated. - -## 💡How it works - -The action extracts each Rust snippet from the given Markdown file, creating a test file containing: +The action extracts Rust snippets from the given Markdown file, creating for each a test file containing: - the snippet itself @@ -49,16 +32,33 @@ Each test file has this relative path: where `N` is the position of the snippet within the Markdown content, starting from **1**. -## 📥Inputs +## ☑️ Requirements + +- each code snippet must reside in a `rust` triple-back-quoted code block and must define a `main()`function returning a type supporting`.unwrap()`, such as `Result<(), Box`: + + ```rust + //Required imports here + use std::error::Error; + + fn main() -> Result<(), Box> { + //Code with assertions here + + Ok(()) + } + ``` + +- the Markdown file must exist unless `optional` is set to **true**, but it is never required to contain code snippets: in this case, no test file will be generated. + +## 📥 Inputs | Name | Type | Description | Default value | | :--------------------: | :---------: | :--------------------------------------------------------: | :---------------------: | | `markdown-file` | **string** | Relative path of the Markdown file containing the snippets | **README.md** | -| `optional` | **boolean** | Just do nothing if `mardown-file` does not exist | **false** | +| `optional` | **boolean** | Just do nothing if `markdown-file` does not exist | **false** | | `test-filename-prefix` | **string** | Relative path prefix for each generated test source file | **tests/readme_test\_** | | `project-directory` | **string** | The directory containing Cargo.toml | **.** | -## 🌐Further references +## 🌐 Further references - [verify-rust-crate](../verify-rust-crate/README.md) diff --git a/actions/extract-rust-snippets/action.yml b/actions/extract-rust-snippets/action.yml index d2adc6aff..b809053e3 100644 --- a/actions/extract-rust-snippets/action.yml +++ b/actions/extract-rust-snippets/action.yml @@ -1,4 +1,4 @@ -name: Extract Rust code snippets +name: Extract Rust test snippets description: Extracts Rust code snippets from a Markdown file to standalone test files. inputs: @@ -7,7 +7,7 @@ inputs: default: README.md optional: - description: Just do nothing if `mardown-file` does not exist. + description: Just do nothing if `markdown-file` does not exist. default: false test-filename-prefix: @@ -21,22 +21,18 @@ inputs: runs: using: composite steps: - - name: Setup Python context - shell: bash - run: | - pythonPath="${{ github.action_path }}/../../core/python" - echo "PYTHONPATH=$pythonPath" >> $GITHUB_ENV - - echo "INPUT_MARKDOWN_FILE=${{ inputs.markdown-file }}" >> $GITHUB_ENV - echo "INPUT_OPTIONAL=${{ inputs.optional }}" >> $GITHUB_ENV - echo "INPUT_TEST_FILENAME_PREFIX=${{ inputs.test-filename-prefix }}" >> $GITHUB_ENV - echo "INPUT_PROJECT_DIRECTORY=${{ inputs.project-directory }}" >> $GITHUB_ENV + - uses: giancosta86/aurora-github/actions/setup-elvish-context@v11.0.0 - - name: Call the Python implementation - shell: python + - shell: elvish {0} + working-directory: ${{ inputs.project-directory }} run: | - from core.extract_rust_snippets import extract_rust_snippets, Inputs + use aurora-github/ci-cd/input + use aurora-github/rust/snippets + + snippets:extract [ + &markdown-path=(input:file &can-be-missing markdown-file '${{ inputs.markdown-file }}') - inputs = Inputs.from_env() + &optional=(input:bool optional '${{ inputs.optional }}') - extract_rust_snippets(inputs) + &test-filename-prefix=(input:string test-filename-prefix '${{ inputs.test-filename-prefix }}') + ] diff --git a/actions/find-critical-todos/README.md b/actions/find-critical-todos/README.md index dc40349d6..9154a2dd6 100644 --- a/actions/find-critical-todos/README.md +++ b/actions/find-critical-todos/README.md @@ -2,36 +2,46 @@ Looks for _critical TODOs_ - that is, instances of the `TODO!` string - in source files. -## 🃏Example +## 🃏 Example ```yaml steps: - - uses: giancosta86/aurora-github/actions/find-critical-todos@v10 + - uses: giancosta86/aurora-github/actions/find-critical-todos@v11 with: - source-file-regex: ^\.\/(src|tests)\/.+\.(c|m)?(j|t)sx?$ + source-file-regex: ^(src|tests)\/.+\.(c|m)?(j|t)sx?$ ``` -**Please, note**: this action is automatically run by [verify-rust-crate](../verify-rust-crate/README.md), [verify-npm-package](../verify-npm-package/README.md) and [verify-rust-wasm](../verify-rust-wasm/README.md). +**Please, note**: this action is automatically run by: -## 📥Inputs +- [verify-rust-crate](../verify-rust-crate/README.md) + +- [verify-npm-package](../verify-npm-package/README.md) + +- [verify-rust-wasm](../verify-rust-wasm/README.md) -| Name | Type | Description | Default value | -| :-----------------: | :---------: | :---------------------------------------------------------------: | :-----------: | -| `source-file-regex` | **string** | The **PCRE** pattern of source file names, for the `find` command | | -| `crash-on-found` | **boolean** | If **true**, exits with error when critical TODOs are found | **true** | -| `display-lines` | **boolean** | Display the lines with critical TODOs | **true** | -| `verbose` | **boolean** | Show details such as the filterable paths | **false** | -| `root-directory` | **string** | The root of the directory tree | **.** | +- [verify-jvm-project](../verify-jvm-project/README.md) -**Please, note**: `source-file-regex` should be designed keeping in mind that it will be applied to a path _always_ relative to `root-directory` and _always_ starting with `./`. +- [verify-python-package](../verify-python-package/README.md) -## 📤Outputs +## 📥 Inputs + +| Name | Type | Description | Default value | +| :-----------------: | :---------: | :---------------------------------------------------------: | :-----------: | +| `source-file-regex` | **string** | The **Perl regex** to select the source file names | | +| `crash-on-found` | **boolean** | If **true**, exits with error when critical TODOs are found | **true** | +| `display-lines` | **boolean** | Display the lines with critical TODOs | **true** | +| `verbose` | **boolean** | Show details such as the filterable paths | **false** | +| `root-directory` | **string** | The root of the directory tree | **.** | + +**Please, note**: `source-file-regex` should be designed keeping in mind that it will be applied to a path _always_ relative to `root-directory` and _never_ starting with `./`. + +## 📤 Outputs | Name | Type | Description | Example | | :-----: | :---------: | :--------------------------------------------------------------------------: | :-------: | | `found` | **boolean** | **true** if at least one `TODO!` was found in some file, **false** otherwise | **false** | -## 🌐Further references +## 🌐 Further references - [verify-rust-crate](../verify-rust-crate/README.md) @@ -39,4 +49,8 @@ steps: - [verify-rust-wasm](../verify-rust-wasm/README.md) +- [verify-jvm-project](../verify-jvm-project/README.md) + +- [verify-python-package](../verify-python-package/README.md) + - [aurora-github](../../README.md) diff --git a/actions/find-critical-todos/action.yml b/actions/find-critical-todos/action.yml index 874cdecfc..54da0f0c2 100644 --- a/actions/find-critical-todos/action.yml +++ b/actions/find-critical-todos/action.yml @@ -1,9 +1,9 @@ name: Find critical TODOs -description: Looks for "critical TODOs" - that is, instances of the "TODO!" string - in source files. +description: Looks for "critical TODOs" - that is, instances of the `TODO!` string - in source files. inputs: source-file-regex: - description: The PCRE pattern of source file names, for the "find" command. + description: The Perl regex to select the source file names. crash-on-found: description: If true, exits with error when critical TODOs are found. @@ -23,97 +23,30 @@ inputs: outputs: found: - description: true if at least one TODO! was found in some file, false otherwise. + description: true if at least one `TODO!` was found in some file, false otherwise. value: ${{ steps.main.outputs.found }} runs: using: composite steps: + - uses: giancosta86/aurora-github/actions/setup-elvish-context@v11.0.0 + - id: main - shell: bash + shell: elvish {0} working-directory: ${{ inputs.root-directory }} run: | - todoText="TODO!" - - main() { - validateInputs - scanDirectoryTree - } - - validateInputs() { - if [[ -z "${{ inputs.source-file-regex }}" ]] - then - echo "❌Missing action input: 'source-file-regex'!" >&2 - exit 1 - fi - - if [[ -z "${{ inputs.crash-on-found }}" ]] - then - echo "❌Missing action input: 'crash-on-found'!" >&2 - exit 1 - fi - - if [[ -z "${{ inputs.display-lines }}" ]] - then - echo "❌Missing action input: 'display-lines'!" >&2 - exit 1 - fi - - if [[ -z "${{ inputs.verbose }}" ]] - then - echo "❌Missing action input: 'verbose'!" >&2 - exit 1 - fi - } - - scanDirectoryTree() { - local sourceFileRegex="${{ inputs.source-file-regex }}" - echo "📥Source file regex: '$sourceFileRegex'" - - local crashOnFound="${{ inputs.crash-on-found }}" - echo "📥Crash on found: $crashOnFound" - - local displayLines="${{ inputs.display-lines }}" - echo "📥Display lines: $displayLines" - - local verbose="${{ inputs.verbose }}" - echo "📥Verbose: $verbose" - - if [[ "$verbose" == "true" ]] - then - echo "🔎File list to filter when looking for TODOs:" - find -type f -print - echo "🔎🔎🔎" - fi + use aurora-github/critical-todos + use aurora-github/ci-cd/input + use aurora-github/ci-cd/output - if [[ "$displayLines" == "true" ]] - then - local quietArg="" - else - local quietArg="-q" - fi + var found = (critical-todos:find [ + &source-file-regex=(input:string source-file-regex '${{ inputs.source-file-regex }}') - if find -type f -print0 | grep -zP "$sourceFileRegex" | xargs -0 grep --color=always -Hn $quietArg "$todoText" - then - local found=true - else - local found=false - fi + &crash-on-found=(input:bool crash-on-found '${{ inputs.crash-on-found }}') - if [[ "$found" == "true" ]] - then - if [[ "$crashOnFound" == "true" ]] - then - echo "❌Critical TODOs found!" >&2 - exit 1 - else - echo "⚠️Critical TODOs found!" - fi - else - echo "✅No critical TODOs found!" - fi + &display-lines=(input:bool display-lines '${{ inputs.display-lines }}') - echo "found=$found" >> $GITHUB_OUTPUT - } + &verbose=(input:bool verbose '${{ inputs.verbose }}') + ]) - main + output:write found $found diff --git a/actions/generate-wasm-target/README.md b/actions/generate-wasm-target/README.md index 970f2feb1..67c166eab 100644 --- a/actions/generate-wasm-target/README.md +++ b/actions/generate-wasm-target/README.md @@ -2,11 +2,11 @@ Generates the source files for a **WebAssembly** target from a **Rust** project. -## 🃏Example +## 🃏 Example ```yaml steps: - - uses: giancosta86/aurora-github/actions/generate-wasm-target@v10 + - uses: giancosta86/aurora-github/actions/generate-wasm-target@v11 with: target: web npm-scope: npmuser @@ -15,7 +15,7 @@ steps: project-directory: . ``` -## 💡How it works +## 💡 How it works 1. Invoke [wasm-pack](https://rustwasm.github.io/wasm-pack/) - with arguments depending on the inputs - to generate a WebAssembly project from the given Rust sources. @@ -25,11 +25,11 @@ steps: 1. If **package.json** was actually generated, display it -## ☑️Requirements +## ☑️ Requirements - The `wasm-pack` command must be available in the system - for example, via [install-wasm-pack](../install-wasm-pack/README.md). -## 📥Inputs +## 📥 Inputs | Name | Type | Description | Default value | | :-----------------: | :---------: | :------------------------------------------------------------------: | :-----------: | @@ -41,7 +41,7 @@ steps: | `target-directory` | **string** | Directory (relative to `project-directory`) for the generated target | | | `project-directory` | **string** | The directory containing `Cargo.toml` | **.** | -## 🌐Further references +## 🌐 Further references - [wasm-pack](https://rustwasm.github.io/wasm-pack/) diff --git a/actions/generate-wasm-target/action.yml b/actions/generate-wasm-target/action.yml index 9dcf68e9c..53597e4e1 100644 --- a/actions/generate-wasm-target/action.yml +++ b/actions/generate-wasm-target/action.yml @@ -1,164 +1,51 @@ -name: generate-wasm-target +name: Generate Rust web assembly target description: Generates the source files for a WebAssembly target from a Rust project. inputs: target: - description: The target of the 'wasm-pack build' command. + description: The target of the `wasm-pack build` command. npm-scope: - description: The package scope or "", for npm targets. + description: The package scope or ``, for npm targets. nodejs-version: - description: The "engines / node" version within package.json. + description: The `engines -> node` version within package.json. pnpm-version: - description: The "packageManager" reference to pnpm within package.json. + description: The `packageManager` reference to pnpm within package.json. development: description: Enable debugging info. target-directory: - description: Directory (relative to 'project-directory') for the generated target. + description: Directory (relative to `project-directory`) for the generated target. project-directory: - description: The directory containing Cargo.toml. + description: The directory containing `Cargo.toml`. default: "." runs: using: composite steps: - - name: Validate inputs - shell: bash - working-directory: ${{ inputs.project-directory }} - run: | - if [[ -z "${{ inputs.target }}" ]] - then - echo "❌Missing action input: 'target'!" >&2 - exit 1 - fi - - if [[ -z "${{ inputs.development }}" ]] - then - echo "❌Missing action input: 'development'!" >&2 - exit 1 - fi - - if [[ -z "${{ inputs.target-directory }}" ]] - then - echo "❌Missing action input: 'target-directory'!" >&2 - exit 1 - fi - - - name: Parse npm scope - id: parse-npm-scope - if: inputs.npm-scope != '' - uses: giancosta86/aurora-github/actions/parse-npm-scope@v10.2.0 - with: - scope: ${{ inputs.npm-scope }} + - uses: giancosta86/aurora-github/actions/setup-elvish-context@v11.0.0 - name: Generate the WebAssembly target - shell: bash + shell: elvish {0} working-directory: ${{ inputs.project-directory }} run: | - target="${{ inputs.target }}" - echo "📥Target: '$target'" - - echo "📥Requested npm-scope: '${{ inputs.npm-scope }}'" - scope="${{ steps.parse-npm-scope.outputs.actual-scope }}" - echo "🔎Actual npm scope: '$scope'" - - development="${{ inputs.development }}" - echo "📥Development? $development" - - nodejsVersion="${{ inputs.nodejs-version }}" - echo "📥NodeJS version: '$nodejsVersion'" - - pnpmVersion="${{ inputs.pnpm-version }}" - echo "📥pnpm version: '$pnpmVersion'" - - echo "📥Project directory: '${{ inputs.project-directory }}'" - - targetDirectory="${{ inputs.target-directory }}" - echo "📥Target directory: '$targetDirectory'" - - main() { - generateWebAssemblyTarget - - pushd "$targetDirectory" - - if [[ -n "$nodejsVersion" ]] - then - injectNodeJsVersion - fi - - if [[ -n "$pnpmVersion" ]] - then - injectPnpmVersion - fi - - tryToDisplayPackageJson - - popd - - echo "✅WebAssembly target ready in '$targetDirectory'!" - } - - generateWebAssemblyTarget() { - echo "📦Generating the WebAssembly project files..." - - if [[ "$development" == "true" ]] - then - local modeArg="--dev" - else - local modeArg="--release" - fi - - if [[ -n "$scope" ]] - then - local scopeArg="--scope $scope" - else - local scopeArg="" - fi - - wasm-pack build --target "$target" $modeArg $scopeArg --out-dir "$targetDirectory" - } - - injectNodeJsVersion() { - if [[ ! -f "package.json" ]] - then - echo "❌package.json was not generated for this target - cannot inject the requested NodeJS version!" - exit 1 - fi - - echo "🧬Injecting the requested NodeJS version ('$nodejsVersion')..." + use aurora-github/ci-cd/input + use aurora-github/rust/wasm-pack - local tempDescriptor="$(mktemp)" - jq '.engines.node = "'"$nodejsVersion"'"' package.json > "$tempDescriptor" - mv "$tempDescriptor" package.json - } + wasm-pack:generate-target [ + &target=(input:string target '${{ inputs.target }}') - injectPnpmVersion() { - if [[ ! -f "package.json" ]] - then - echo "❌package.json was not generated for this target - cannot inject the requested pnpm version!" - exit 1 - fi + &npm-scope=(input:string npm-scope '${{ inputs.npm-scope }}') - echo "🧬Injecting the requested pnpm version ('$pnpmVersion')..." + &nodejs-version=(input:string &optional nodejs-version '${{ inputs.nodejs-version }}') - local tempDescriptor="$(mktemp)" - jq '.packageManager = "pnpm@'"$pnpmVersion"'"' package.json > "$tempDescriptor" - mv "$tempDescriptor" package.json - } + &pnpm-version=(input:string &optional pnpm-version '${{ inputs.pnpm-version }}') - tryToDisplayPackageJson() { - if [[ -f "package.json" ]] - then - echo "📦Generated package.json descriptor for the '$target' target:" - jq -C '.' package.json - else - echo "💭No package.json descriptor generated for the '$target' target..." - fi - } + &development=(input:bool development '${{ inputs.development }}') - main + &target-directory=(input:string target-directory '${{ inputs.target-directory }}') + ] diff --git a/actions/inject-subpath-exports/README.md b/actions/inject-subpath-exports/README.md index 920811fc0..cadfbd957 100644 --- a/actions/inject-subpath-exports/README.md +++ b/actions/inject-subpath-exports/README.md @@ -2,14 +2,14 @@ Appends [subpath exports](https://nodejs.org/api/packages.html#subpath-exports) to **package.json** according to the directory tree. -## 🃏Example +## 🃏 Example ```yaml steps: - - uses: giancosta86/aurora-github/actions/inject-subpath-exports@v10 + - uses: giancosta86/aurora-github/actions/inject-subpath-exports@v11 ``` -## 💡How it works +## 💡 How it works Appends keys to the `exports` field of a `package.json` descriptor - according to the index files in the source directory tree. @@ -45,13 +45,13 @@ The `mode` input can have the following values: - The keys reference directories under `./dist`, **not** under `./`. -## ☑️Requirements +## ☑️ Requirements - The `jq` command (especially version **1.7**) must be available in the operating system. - The `source-directory` and the root `package.json` descriptor must exist. -## 📥Inputs +## 📥 Inputs | Name | Type | Description | Default value | | :-----------------: | :-------------------: | :-------------------------------------: | :--------------: | @@ -59,7 +59,7 @@ The `mode` input can have the following values: | `source-directory` | **string** | Relative path to the source directory | **src** | | `project-directory` | **string** | The directory containing `package.json` | **.** | -## 🌐Further references +## 🌐 Further references - [subpath exports](https://nodejs.org/api/packages.html#subpath-exports) diff --git a/actions/inject-subpath-exports/action.yml b/actions/inject-subpath-exports/action.yml index 6c5dd6221..f4b71f106 100644 --- a/actions/inject-subpath-exports/action.yml +++ b/actions/inject-subpath-exports/action.yml @@ -3,7 +3,7 @@ description: Appends subpath exports to package.json according to the directory inputs: mode: - description: Subpath exports generation mode; can be "prefer-index" or "all". + description: Subpath exports generation mode; can be `prefer-index` or `all`. default: prefer-index source-directory: @@ -11,135 +11,22 @@ inputs: default: src project-directory: - description: The directory containing package.json. + description: The directory containing `package.json`. default: . runs: using: composite steps: - - shell: bash + - uses: giancosta86/aurora-github/actions/setup-elvish-context@v11.0.0 + + - shell: elvish {0} working-directory: ${{ inputs.project-directory }} run: | - main() { - validateInputs - displayInitialExports - performInjection - displayFinalExports - } - - validateInputs() { - case "${{ inputs.mode }}" in - "prefer-index" | all) - ;; - *) - echo "❌Invalid value for 'mode' input: '${{ inputs.mode }}'!" >&2 - exit 1 - esac - - if [[ -z "${{ inputs.source-directory }}" ]] - then - echo "❌Missing action input: 'source-directory'!" >&2 - exit 1 - fi - - if [[ ! -f "package.json" ]] - then - echo "❌The package.json descriptor file does not exist!!" >&2 - exit 1 - fi - - if [[ ! -d "${{ inputs.source-directory }}" ]] - then - echo "❌Source directory '${{ inputs.source-directory }}' does not exist!" >&2 - exit 1 - fi - } - - displayInitialExports() { - echo "📦package.json exports at the beginning of inject-subpath-exports:" - jq -C .exports package.json - } - - performInjection() { - local mode="${{ inputs.mode }}" - local sourceDirectory="${{ inputs.source-directory }}" - - local rootIndexNames=("index.ts" "index.js") - - local rootIndexName - for rootIndexName in ${rootIndexNames[@]} - do - local potentialRootIndex="$sourceDirectory/$rootIndexName" - - echo "🔎Looking for potential root index: '${potentialRootIndex}'" - - if [[ -f "$potentialRootIndex" ]] - then - local rootIndex="$potentialRootIndex" - break - fi - done - - if [[ -n "$rootIndex" ]] - then - echo "✅Root index file found: '$rootIndex'!" - - updatePackageJson "$(cat < "$tempPackage" - mv "$tempPackage" package.json - } + use aurora-github/ci-cd/input + use aurora-github/nodejs/subpath-exports - displayFinalExports() { - echo "📦package.json exports at the end of inject-subpath-exports:" - jq -C .exports package.json - } + subpath-exports:inject [ + &source-directory=(input:directory source-directory '${{ inputs.source-directory }}') - main + &mode=(input:enum mode '${{ inputs.mode }}' [prefer-index all]) + ] diff --git a/actions/install-system-packages/README.md b/actions/install-system-packages/README.md index 4fc437dbe..625ce92d2 100644 --- a/actions/install-system-packages/README.md +++ b/actions/install-system-packages/README.md @@ -2,20 +2,16 @@ Installs software using the platform's package manager. -## 🃏Example +## 🃏 Example ```yaml steps: - - uses: giancosta86/aurora-github/actions/install-system-packages@v10 + - uses: giancosta86/aurora-github/actions/install-system-packages@v11 with: packages: moreutils ``` -## ☑️Requirements - -This action currently supports only the `apt-get` package manager. - -## 💡How it works +## 💡 How it works 1. If `required-command` is specified and can be found by the `type` command, just exit the action. @@ -23,14 +19,18 @@ This action currently supports only the `apt-get` package manager. 1. Install the requested packages. -## 📥Inputs +## ☑️ Requirements + +This action currently supports only the `apt-get` package manager. + +## 📥 Inputs | Name | Type | Description | Default value | | :----------------: | :---------: | :----------------------------------------------------------------------: | :-----------: | | `required-command` | **string** | When declared, the packages are installed only if the command is missing | | -| `packages` | **string** | The packages to install, separated by any spaces or commas | | +| `packages` | **string** | The packages to install, separated by commas | | | `initial-update` | **boolean** | Update the package list before the first installation | **true** | -## 🌐Further references +## 🌐 Further references - [aurora-github](../../README.md) diff --git a/actions/install-system-packages/action.yml b/actions/install-system-packages/action.yml index d7b32d61c..ea2a36064 100644 --- a/actions/install-system-packages/action.yml +++ b/actions/install-system-packages/action.yml @@ -6,7 +6,7 @@ inputs: description: When declared, the packages are installed only if the command is missing. packages: - description: The packages to install, separated by any spaces or commas. + description: The packages to install, separated by commas. initial-update: description: Update the package list before the first installation. @@ -15,102 +15,17 @@ inputs: runs: using: composite steps: - - shell: bash - run: | - main() { - validateInputs - - if ! shouldRunInstaller - then - exit 0 - fi - - if [[ "${{ inputs.initial-update }}" == 'true' ]] - then - tryToUpdatePackageList - fi - - installPackages - } - - validateInputs() { - if [[ -z "${{ inputs.packages }}" ]] - then - echo "❌Missing action input: 'packages'!" >&2 - exit 1 - fi - - if [[ -z "${{ inputs.initial-update }}" ]] - then - echo "❌Missing action input: 'initial-update'!" >&2 - exit 1 - fi - } - - shouldRunInstaller() { - local requiredCommand="${{inputs.required-command}}" - - if [[ -n "$requiredCommand" ]] - then - echo "📥Required command: '$requiredCommand'" - - if type "$requiredCommand" > /dev/null 2>&1 - then - echo "✅Required command '$requiredCommand' available - no need to install it!" - return 1 - else - echo "💫Required command '$requiredCommand' not available - now installing its packages..." - fi - else - echo "💫No required command passed - the requested packages will be installed unconditionally" - fi - - return 0 - } - - tryToUpdatePackageList() { - local flagFile="$HOME/.install-system-packages-updated" - - if [[ -f "$flagFile" ]] - then - echo "💡The package list has already been updated!" - return 0 - fi + - uses: giancosta86/aurora-github/actions/setup-elvish-context@v11.0.0 - echo "📥Updating the package list..." - - runQuietly "sudo apt-get update" - - touch "$flagFile" - } - - runQuietly() { - local commandLine="$1" - - local outputFile="$(mktemp)" - - if ! $commandLine &> "$outputFile" - then - echo "❌Error while running the command! Log:" - cat "$outputFile" - echo "❌❌❌" - - exit 1 - fi - } - - installPackages() { - local requestedPackages="${{ inputs.packages }}" - - echo "📥Requested packages: $requestedPackages" - - local actualPackages="$(echo "$requestedPackages" | perl -pe 's/[\s,]+/ /g')" - - echo "📦Installing packages..." + - shell: elvish {0} + run: | + use aurora-github/ci-cd/input + use aurora-github/system-packages - runQuietly "sudo apt-get install -y $actualPackages" + system-packages:install [ + &packages=(input:list '${{ inputs.packages }}') - echo "✅Packages installed!" - } + &required-command=(input:string &optional required-command '${{ inputs.required-command }}') - main + &initial-update=(input:bool initial-update '${{ inputs.initial-update}}') + ] diff --git a/actions/install-via-sdkman/README.md b/actions/install-via-sdkman/README.md index 1a3da7f32..65cade0a0 100644 --- a/actions/install-via-sdkman/README.md +++ b/actions/install-via-sdkman/README.md @@ -2,17 +2,17 @@ Installs the requested SDK using [SDKMAN!](https://sdkman.io/) -## 🃏Example +## 🃏 Example ```yaml steps: - - uses: giancosta86/aurora-github/actions/install-sdkman-candidate@v10 + - uses: giancosta86/aurora-github/actions/install-sdkman-candidate@v11 with: candidate: java version: 23-open ``` -## 💡How it works +## 💡 How it works 1. If SDKMAN is not installed, download and install it. @@ -20,7 +20,7 @@ steps: **Please, note**: all the SDKS are installed to `$HOME/.sdkman/candidates` -## ☑️Requirements +## ☑️ Requirements - `candidate` must be an identifier belonging to the [list of SDKs](https://sdkman.io/sdks) supported by SDKMAN. @@ -32,14 +32,14 @@ steps: where `candidate` is the identifier of the required SDK. -## 📥Inputs +## 📥 Inputs | Name | Type | Description | Default value | | :---------: | :--------: | :------------------------------------------: | :-----------: | | `candidate` | **string** | Identifier (in SDKMAN) of the SDK to install | | | `version` | **string** | Identifier (in SDKMAN) of the version | | -## 🌐Further references +## 🌐 Further references - [SDKMAN!](https://sdkman.io/) diff --git a/actions/install-via-sdkman/action.yml b/actions/install-via-sdkman/action.yml index 63ff17ba9..258dad2ec 100644 --- a/actions/install-via-sdkman/action.yml +++ b/actions/install-via-sdkman/action.yml @@ -1,4 +1,4 @@ -name: Install SDK via SDKMAN. +name: Install SDK via SDKMAN description: Installs the requested SDK using SDKMAN. inputs: @@ -11,70 +11,19 @@ inputs: runs: using: composite steps: - - shell: bash - run: | - sdkmanHome="$HOME/.sdkman" - - main() { - validateInputs - - ensureSdkmanInstalled - - ensureSdkmanReady - - installCandidateSdk - } - - validateInputs() { - if [[ -z "${{ inputs.candidate }}" ]] - then - echo "❌Missing action input: 'candidate'!" >&2 - exit 1 - fi - - if [[ -z "${{ inputs.version }}" ]] - then - echo "❌Missing action input: 'version'!" >&2 - exit 1 - fi - } - - ensureSdkmanInstalled() { - if [[ -d "$sdkmanHome" ]] - then - echo "☑It seems that SDKMAN was previously installed" - return 0 - fi + - uses: giancosta86/aurora-github/actions/setup-elvish-context@v11.0.0 - echo "📥Installing SDKMAN..." - - curl -s "https://get.sdkman.io" | bash - - echo "✅SDKMAN installed!" - } - - ensureSdkmanReady() { - if ! type -t sdk - then - echo '🚀Setting up SDKMAN...' - - source "$sdkmanHome/bin/sdkman-init.sh" - fi - - echo "✅SDKMAN ready!" - } - - installCandidateSdk() { - local candidate="${{ inputs.candidate }}" - local version="${{ inputs.version }}" - - echo "📥Installing $candidate($version)..." + - shell: elvish {0} + run: | + use github.com/giancosta86/aurora-elvish/curl + use aurora-github/ci-cd/input + use aurora-github/jvm/sdkman - sdk install "$candidate" "$version" + var candidate = (input:string candidate '${{ inputs.candidate }}') - echo "PATH=$sdkmanHome/candidates/candidate/$version:$PATH" >> $GITHUB_ENV + var version = (input:string version '${{ inputs.version }}') - echo "✅$candidate($version) installed!" - } + console:echo 📢 Configuring curl so that it outputs errors only... + curl:display-errors-only - main + sdkman:install-sdk $candidate $version diff --git a/actions/install-wasm-pack/README.md b/actions/install-wasm-pack/README.md index 6a5eb0124..3b64f4e2c 100644 --- a/actions/install-wasm-pack/README.md +++ b/actions/install-wasm-pack/README.md @@ -2,26 +2,26 @@ Installs [wasm-pack](https://rustwasm.github.io/wasm-pack/), for creating **Rust**-based web assemblies. -## 🃏Example +## 🃏 Example ```yaml steps: - - uses: giancosta86/aurora-github/actions/install-wasm-pack@v10 + - uses: giancosta86/aurora-github/actions/install-wasm-pack@v11 ``` **Please, note**: this action is automatically run by [verify-rust-wasm](../verify-rust-wasm/README.md) and [publish-rust-wasm](../publish-rust-wasm/README.md). -## ☑️Requirements +## ☑️ Requirements The **npm** command must be available on the system. -## 📥Inputs +## 📥 Inputs -| Name | Type | Description | Default value | -| :-----------------: | :--------: | :------------------------------: | :-----------: | -| `wasm-pack-version` | **string** | The wasm-pack version to install | | +| Name | Type | Description | Default value | +| :-----------------: | :--------: | :---------------------------------: | :-----------: | +| `wasm-pack-version` | **string** | The version of wasm-pack to install | | -## 🌐Further references +## 🌐 Further references - [verify-rust-wasm](../verify-rust-wasm/README.md) diff --git a/actions/install-wasm-pack/action.yml b/actions/install-wasm-pack/action.yml index bf6024314..41b487b50 100644 --- a/actions/install-wasm-pack/action.yml +++ b/actions/install-wasm-pack/action.yml @@ -3,43 +3,20 @@ description: Installs wasm-pack, for creating Rust-based web assemblies. inputs: wasm-pack-version: - description: The wasm-pack version to install. + description: The version of wasm-pack to install. runs: using: composite steps: - - shell: bash - run: | - main() { - validateInputs - installWasmPack - printWasmPackVersion - } - - validateInputs() { - if [[ -z "${{ inputs.wasm-pack-version }}" ]] - then - echo "❌Missing action input: 'wasm-pack-version'!" >&2 - exit 1 - fi - } - - installWasmPack() { - local requestedVersion="${{ inputs.wasm-pack-version }}" - - echo "🌐Installing wasm-pack $requestedVersion..." + - uses: giancosta86/aurora-github/actions/setup-elvish-context@v11.0.0 - npm install -g "wasm-pack@$requestedVersion" - - echo "✅wasm-pack installed!" - } - - printWasmPackVersion() { - echo "🔎Now ensuring wasm-pack is available..." - - wasm-pack --version + - shell: elvish {0} + run: | + use aurora-github/ci-cd/input + use aurora-github/rust/wasm-pack - echo "✅wasm-pack ready!" - } + var version = ( + input:string wasm-pack-version '${{ inputs.wasm-pack-version }}' + ) - main \ No newline at end of file + wasm-pack:install $version diff --git a/actions/parse-npm-scope/README.md b/actions/parse-npm-scope/README.md index ad2476c6c..c9a48cd53 100644 --- a/actions/parse-npm-scope/README.md +++ b/actions/parse-npm-scope/README.md @@ -2,17 +2,17 @@ Parses a mandatory [npm scope](https://docs.npmjs.com/cli/v10/using-npm/scope) declaration. -## 🃏Example +## 🃏 Example ```yaml steps: - id: scope-parser - uses: giancosta86/aurora-github/actions/parse-npm-scope@v10 + uses: giancosta86/aurora-github/actions/parse-npm-scope@v11 with: scope: giancosta86 ``` -## ☑️Requirements +## ☑️ Requirements - The `scope` input _must_ be declared. It can be: @@ -20,19 +20,19 @@ steps: - the _package scope_ as a string, with an optional leading `@` -## 📥Inputs +## 📥 Inputs | Name | Type | Description | Default value | | :-----: | :--------: | :--------------------: | :-----------: | | `scope` | **string** | The npm scope to parse | | -## 📤Outputs +## 📤 Outputs | Name | Type | Description | Example | | :------------: | :--------: | :-------------------------------------------------------: | :-------------: | | `actual-scope` | **string** | The scope without '@', or the empty string for root scope | **giancosta86** | -## 🌐Further references +## 🌐 Further references - [npm scope](https://docs.npmjs.com/cli/v10/using-npm/scope) diff --git a/actions/parse-npm-scope/action.yml b/actions/parse-npm-scope/action.yml index 6c47d705e..9ee2c06e5 100644 --- a/actions/parse-npm-scope/action.yml +++ b/actions/parse-npm-scope/action.yml @@ -3,30 +3,27 @@ description: Parses a mandatory npm scope declaration. inputs: scope: - description: The npm scope to parse. Can be either '' or a string with an optional leading "@". + description: The npm scope to parse. Can be either `` or a string with an optional leading `@`. outputs: actual-scope: - description: The scope without '@', or the empty string for root scope. + description: The scope without `@`, or the empty string for root scope. value: ${{ steps.parse-actual-scope.outputs.actual-scope }} runs: using: composite steps: - - name: Setup Python context - shell: bash - run: | - pythonPath="${{ github.action_path }}/../../core/python" - echo "PYTHONPATH=$pythonPath" >> $GITHUB_ENV - - echo "INPUT_SCOPE=${{ inputs.scope }}" >> $GITHUB_ENV + - uses: giancosta86/aurora-github/actions/setup-elvish-context@v11.0.0 - - name: Call the Python implementation - id: parse-actual-scope - shell: python + - id: parse-actual-scope + shell: elvish {0} run: | - from core.parse_npm_scope import parse_npm_scope, Inputs + use aurora-github/ci-cd/input + use aurora-github/ci-cd/output + use aurora-github/nodejs/pnpm + + var scope = (input:string scope '${{ inputs.scope }}') - inputs = Inputs.from_env() + var actual-scope = (pnpm:parse-scope $scope) - parse_npm_scope(inputs).write_to_github_output() + output:write actual-scope $actual-scope diff --git a/actions/publish-github-pages/README.md b/actions/publish-github-pages/README.md index 70dd3947e..b98040ee6 100644 --- a/actions/publish-github-pages/README.md +++ b/actions/publish-github-pages/README.md @@ -2,13 +2,11 @@ Publishes a directory as the [GitHub Pages](https://pages.github.com/) website for the current repository. -## 🃏Example +## 🃏 Example ```yaml steps: - - uses: actions/checkout@v4 - - - uses: giancosta86/aurora-github/actions/publish-github-pages@v10 + - uses: giancosta86/aurora-github/actions/publish-github-pages@v11 ``` **Please, note**: this action is automatically run by: @@ -23,7 +21,7 @@ steps: - [publish-rust-wasm](../publish-rust-wasm/README.md). -## 💡How it works +## 💡 How it works 1. If `source-directory` is set to an empty string (the default) or refers to a missing directory, if `optional` is set to **true** the action will simply exit, otherwise the workflow will fail. @@ -51,7 +49,7 @@ steps: 1. Publish the files to GitHub Pages. -## ☑️Requirements +## ☑️ Requirements - The following [permissions](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/controlling-permissions-for-github_token) must be set for the action to work: @@ -67,7 +65,7 @@ steps: - Please, refer to [setup-nodejs-context](../setup-nodejs-context/README.md) for details about setting up a NodeJS environment. -## 📥Inputs +## 📥 Inputs | Name | Type | Description | Default value | | :----------------------: | :---------------------: | :-----------------------------------------------------------------: | :-----------: | @@ -76,13 +74,13 @@ steps: | `enforce-branch-version` | `inject`,`check`,`skip` | How the branch version should be enforced | **inject** | | `dry-run` | **boolean** | Stop the publication just before uploading | **false** | -## 📤Outputs +## 📤 Outputs | Name | Type | Description | Example | | :---: | :--------: | :------------------------------: | :---------: | | `url` | **string** | The URL of the published website | _HTTPS url_ | -## 🌐Further references +## 🌐 Further references - [setup-nodejs-context](../setup-nodejs-context/README.md) diff --git a/actions/publish-github-pages/action.yml b/actions/publish-github-pages/action.yml index 4fb0b1ade..87748dbc3 100644 --- a/actions/publish-github-pages/action.yml +++ b/actions/publish-github-pages/action.yml @@ -7,7 +7,7 @@ inputs: default: . optional: - description: Whether "source-directory" can be empty string or missing directory. + description: Whether `source-directory` can be empty string or missing directory. default: false enforce-branch-version: @@ -26,166 +26,81 @@ outputs: runs: using: composite steps: + - uses: giancosta86/aurora-github/actions/setup-elvish-context@v11.0.0 + - name: Set up strategy - shell: bash + shell: elvish {0} run: | - strategy="exit" - - main() { - validateInputs - - if setupEnvironment - then - detectSourceStrategy - fi - - echo "🔎Website build strategy: '$strategy'" - echo "strategy=$strategy" >> $GITHUB_ENV - } - - validateInputs() { - if [[ -z "${{ inputs.optional }}" ]] - then - echo "❌Missing action input: 'optional'!" >&2 - exit 1 - fi - - if [[ -z "${{ inputs.enforce-branch-version }}" ]] - then - echo "❌Missing action input: 'enforce-branch-version'!" >&2 - exit 1 - fi - - if [[ -z "${{ inputs.dry-run }}" ]] - then - echo "❌Missing action input: 'dry-run'!" >&2 - exit 1 - fi - } - - setupEnvironment() { - local sourceDirectory="${{ inputs.source-directory }}" - local optional="${{ inputs.optional }}" - - if [[ -z "$sourceDirectory" ]] - then - if [[ "$optional" == "true" ]] - then - echo "💬Missing action input: 'source-directory' - can't proceed" - return 1 - else - echo "❌Missing action input: 'source-directory'!" >&2 - exit 1 - fi - elif [[ ! -d "$sourceDirectory" ]] - then - if [[ "$optional" == "true" ]] - then - echo "💬Missing website directory '$sourceDirectory' - can't proceed" - return 1 - else - echo "❌Missing website directory '$sourceDirectory'!" >&2 - exit 1 - fi - else - echo "🌐Website source directory '$sourceDirectory' found!" - cd "$sourceDirectory" - fi - } - - detectSourceStrategy() { - if [[ -f "package.json" ]] - then - strategy=nodejs - elif [[ -f "pom.xml" ]] - then - strategy=maven - else - strategy="static-files" - fi - } - - main + use aurora-github/ci-cd/input + use aurora-github/website + + var optional = (input:bool optional '${{ inputs.optional }}') + + var source-directory = (input:directory &optional=$optional &can-be-missing=$optional source-directory '${{ inputs.source-directory }}') + + website:detect-strategy-from-sources $source-directory - name: Enforce branch version if: env.strategy == 'nodejs' || env.strategy == 'maven' - uses: giancosta86/aurora-github/actions/enforce-branch-version@v10.2.0 + uses: giancosta86/aurora-github/actions/enforce-branch-version@v11.0.0 with: mode: ${{ inputs.enforce-branch-version }} project-directory: ${{ inputs.source-directory }} - name: Setup NodeJS context if: env.strategy == 'nodejs' - uses: giancosta86/aurora-github/actions/setup-nodejs-context@v10.2.0 + uses: giancosta86/aurora-github/actions/setup-nodejs-context@v11.0.0 with: project-directory: ${{ inputs.source-directory }} - name: Create the website via NodeJS if: env.strategy == 'nodejs' - shell: bash - working-directory: ${{ inputs.source-directory }} + shell: elvish {0} run: | - echo "📦Now building the website via NodeJS..." - pnpm build - echo "✅Website ready!" - - artifactDirectory=${{ inputs.source-directory }}/dist + use aurora-github/ci-cd/input + use aurora-github/website - echo "artifactDirectory=$artifactDirectory" >> $GITHUB_ENV + website:build-via-nodejs (input:string source-directory '${{ inputs.source-directory }}') - name: Create the website via Maven if: env.strategy == 'maven' - shell: bash - working-directory: ${{ inputs.source-directory }} + shell: elvish {0} run: | - echo "🪶Now building the website via Maven..." - mvn -q site - echo "✅Website ready!" + use aurora-github/ci-cd/input + use aurora-github/website - artifactDirectory=${{ inputs.source-directory }}/target/site - - echo "artifactDirectory=$artifactDirectory" >> $GITHUB_ENV + website:build-via-maven (input:string source-directory '${{ inputs.source-directory }}') - name: Setup static artifacts if: env.strategy == 'static-files' - shell: bash - run: echo "artifactDirectory=${{ inputs.source-directory }}" >> $GITHUB_ENV + shell: elvish {0} + run: | + use aurora-github/ci-cd/input + use aurora-github/website - - if: env.strategy != 'exit' - shell: bash + website:set-artifact-directory (input:string source-directory '${{ inputs.source-directory }}') + + - name: Check artifacts + if: env.strategy != 'exit' + shell: elvish {0} run: | - main() { - checkArtifactDirectory - skipUploadingOnDryRun - } - - checkArtifactDirectory() { - echo "🔎Website artifact directory: '$artifactDirectory'" - - if [[ -d "$artifactDirectory" ]] - then - echo "✅The artifact directory for the 🌐website exists!" - else - if [[ "${{ inputs.optional }}" == "true" ]] - then - echo "💬Missing website artifact directory - can't proceed" - echo "strategy=exit" >> $GITHUB_ENV - else - echo "❌Missing website artifact directory!" >&2 - exit 1 - fi - fi - } - - skipUploadingOnDryRun() { - if [[ "${{ inputs.dry-run }}" == "true" ]] - then - echo "💭Skipping publication, as requested by dry-run." - echo "strategy=exit" >> $GITHUB_ENV - fi - } - - main + use aurora-github/ci-cd/input + use aurora-github/website + + var optional = (input:bool optional '${{ inputs.optional }}') + + website:check-artifact-directory (get-env artifactDirectory) $optional + + - name: Skip publication on dry-run + if: env.strategy != 'exit' + shell: elvish {0} + run: | + use aurora-github/ci-cd/input + use aurora-github/website + + var dry-run = (input:bool dry-run '${{ inputs.dry-run }}') + + website:skip-publication-on-dry-run $dry-run - name: Upload website artifacts if: env.strategy != 'exit' @@ -200,7 +115,9 @@ runs: - name: Print confirmation message if: env.strategy != 'exit' - shell: bash + shell: elvish {0} run: | - echo "✅Publication to GitHub Pages successful!" - echo "🌐Website: ${{ steps.publish-pages.outputs.page_url }}" + use github.com/giancosta86/aurora-elvish/console + + console:echo ✅ Website publication successful! + console:echo 🌐 Project website: ${{ steps.publish-pages.outputs.page_url }} diff --git a/actions/publish-jvm-project/README.md b/actions/publish-jvm-project/README.md index 0f09ad720..6ce0629ed 100644 --- a/actions/publish-jvm-project/README.md +++ b/actions/publish-jvm-project/README.md @@ -2,19 +2,17 @@ Publishes a project for the **Java Virtual Machine** - using **Maven** or **Gradle**. -## 🃏Example +## 🃏 Example ```yaml steps: - - uses: actions/checkout@v4 - - - uses: giancosta86/aurora-github/actions/publish-jvm-project@v10 + - uses: giancosta86/aurora-github/actions/publish-jvm-project@v11 with: auth-user: userOnTheServer auth-token: ${{ secrets.SERVER_TOKEN }} ``` -## 💡How it works +## 💡 How it works 1. Run [enforce-branch-version](../enforce-branch-version/README.md), forwarding the `enforce-branch-version` input to its `mode` input. @@ -52,7 +50,7 @@ steps: - **JVM_AUTH_TOKEN** - with the value of `auth-token` -## ☑️Requirements +## ☑️ Requirements - The `mvn` or `gradle` command must be available, depending on the descriptor within the project directory - which also implies that a suitable **Java** environment is installed; by passing `java-version` and `tool-version`, you can enforce specific required versions instead of the default ones provided by the selected GitHub Actions runner. @@ -99,7 +97,7 @@ steps: - Before the first publication, running with `dry-run` set to **true** is recommended. -## 📥Inputs +## 📥 Inputs | Name | Type | Description | Default value | | :----------------------: | :---------------------: | :-----------------------------------------------: | :-----------: | @@ -113,7 +111,7 @@ steps: | `enforce-branch-version` | `inject`,`check`,`skip` | How the branch version should be enforced | **inject** | | `project-directory` | **string** | The directory containing the project descriptor | **.** | -## 🌐Further references +## 🌐 Further references - [publish-github-pages](../publish-github-pages/README.md) diff --git a/actions/publish-jvm-project/action.yml b/actions/publish-jvm-project/action.yml index bcc24a743..0bf4e9505 100644 --- a/actions/publish-jvm-project/action.yml +++ b/actions/publish-jvm-project/action.yml @@ -37,201 +37,62 @@ inputs: runs: using: composite steps: - - name: Validate inputs - shell: bash - working-directory: ${{ inputs.project-directory }} - run: | - if [[ -z "${{ inputs.dry-run }}" ]] - then - echo "❌Missing action input: 'dry-run'!" >&2 - exit 1 - fi - - if [[ -z "${{ inputs.website-directory }}" ]] - then - echo "❌Missing action input: 'website-directory'!" >&2 - exit 1 - fi - - if [[ -z "${{ inputs.enforce-branch-version }}" ]] - then - echo "❌Missing action input: 'enforce-branch-version'!" >&2 - exit 1 - fi + - uses: giancosta86/aurora-github/actions/setup-elvish-context@v11.0.0 - name: Enforce branch version - uses: giancosta86/aurora-github/actions/enforce-branch-version@v10.2.0 + uses: giancosta86/aurora-github/actions/enforce-branch-version@v11.0.0 with: mode: ${{ inputs.enforce-branch-version }} project-directory: ${{ inputs.project-directory }} - - name: Setup Python context - shell: bash - run: | - pythonPath="${{ github.action_path }}/../../core/python" - echo "PYTHONPATH=$pythonPath" >> $GITHUB_ENV - - echo "INPUT_PROJECT_DIRECTORY=${{ inputs.project-directory }}" >> $GITHUB_ENV - - - name: Detect the build tool - shell: python + - name: Setup JVM context + shell: elvish {0} + working-directory: ${{ inputs.project-directory }} run: | - from core.jvm import get_jvm_build_tool, Inputs - - inputs = Inputs.from_env() + use aurora-github/ci-cd/input + use aurora-github/ci-cd/env + use aurora-github/jvm/context - get_jvm_build_tool(inputs).write_to_github_env() - - - name: Install Java - if: inputs.java-version != '' - uses: giancosta86/aurora-github/actions/install-via-sdkman@v10.2.0 - with: - candidate: java - version: ${{ inputs.java-version }} - - - name: Install Maven - if: env.buildTool == 'mvn' && inputs.tool-version != '' - uses: giancosta86/aurora-github/actions/install-via-sdkman@v10.2.0 - with: - candidate: maven - version: ${{ inputs.tool-version }} - - - name: Install Gradle - if: env.buildTool == 'gradle' && inputs.tool-version != '' - uses: giancosta86/aurora-github/actions/install-via-sdkman@v10.2.0 - with: - candidate: gradle - version: ${{ inputs.tool-version }} + env:map (context:setup ^ + &java-version=(input:string &optional java-version '${{ inputs.java-version }}') ^ + &tool-version=(input:string &optional tool-version '${{ inputs.tool-version }}') ^ + ) - - name: Prepare Maven settings - if: env.buildTool == 'mvn' - shell: bash + - name: Prepare settings for publication + shell: elvish {0} working-directory: ${{ inputs.project-directory }} run: | - settingsDirectory="$HOME/.m2" - settingsBasename="settings.xml" - - main() { - echo "🪶Setting up Maven settings..." - - mkdir -p "$settingsDirectory" - - if [[ -f "$settingsBasename" ]] - then - echo "✅$settingsBasename found in the project directory! Now copying it to '$settingsDirectory'..." - cp "$settingsBasename" "$settingsDirectory" - else - echo "🌟Providing a default '$settingsBasename' file for 🪶Maven..." - copyDefaultSettings - checkServerInPom - fi - - echo "✅Maven settings file ready!" - } - - copyDefaultSettings() { - cp "${{ github.action_path }}/$settingsBasename" "$settingsDirectory" - - echo "The content of the generated 🪶$settingsBasename is:" - cat "$settingsDirectory/$settingsBasename" - echo "🪶🪶🪶" - } - - checkServerInPom() { - local serverName="target-server" - - if grep -q "$serverName" $descriptor - then - echo "✅Server '$serverName' found in $descriptor!" - else - echo "💭Server '$serverName' not used in $descriptor..." - fi - } - - main - - - name: Prepare Gradle settings - if: env.buildTool == 'gradle' - shell: bash - working-directory: ${{ inputs.project-directory }} - run: | - echo "🐘Checking the (optional) use of environment variables in $descriptor" - - for envVar in "JVM_AUTH_USER" "JVM_AUTH_TOKEN" - do - if grep -q "$envVar" $descriptor - then - echo "✅'$envVar' referenced by the project descriptor!" - else - echo "💭'$envVar' environment variable not referenced in $descriptor..." - fi - done + use aurora-github/jvm/settings - echo "🐘🐘🐘" + settings:prepare-for-publication (get-env buildTool) - name: Publish the GitHub Pages website - uses: giancosta86/aurora-github/actions/publish-github-pages@v10.2.0 + uses: giancosta86/aurora-github/actions/publish-github-pages@v11.0.0 with: optional: true source-directory: ${{ inputs.project-directory }}/${{ inputs.website-directory }} dry-run: ${{ inputs.dry-run }} enforce-branch-version: ${{ inputs.enforce-branch-version }} - - name: Publish via Maven - if: env.buildTool == 'mvn' - shell: bash + - name: Publish project + shell: elvish {0} working-directory: ${{ inputs.project-directory }} run: | - if [[ "${{ inputs.dry-run }}" == "true" ]] - then - dryRunDirectory="target/dry-run" - echo "📁dry-run mode enabled - publishing to '$dryRunDirectory' local directory instead..." + use aurora-github/ci-cd/input + use aurora-github/jvm/project/publication - dryRunArg="-DaltDeploymentRepository=target-server::default::file:$dryRunDirectory" - else - dryRunArg="" - fi + var quiet-tool = (input:bool quiet-tool '${{ inputs.quiet-tool }}') - if [[ "${{ inputs.quiet-tool }}" == "true" ]] - then - quietToolArg="-q" - else - quietToolArg="" - fi + var dry-run = (input:bool dry-run '${{ inputs.dry-run }}') - echo "🪶Running Maven to publish the project..." - - mvn -B $dryRunArg $quietToolArg deploy - - echo "✅Publication via Maven successful!" + publication:publish &quiet-tool=$quiet-tool &dry-run=$dry-run (get-env buildTool) env: JVM_AUTH_USER: ${{ inputs.auth-user }} JVM_AUTH_TOKEN: ${{ inputs.auth-token }} - - name: Publish via Gradle - if: env.buildTool == 'gradle' - shell: bash - working-directory: ${{ inputs.project-directory }} + - name: Print confirmation message + shell: elvish {0} run: | - if [[ "${{ inputs.dry-run }}" == "true" ]] - then - dryRunArg="--dry-run" - else - dryRunArg="" - fi + use github.com/giancosta86/aurora-elvish/console - if [[ "${{ inputs.quiet-tool }}" == "true" ]] - then - quietToolArg="-q" - else - quietToolArg="" - fi - - echo "🐘Running Gradle to publish the project..." - - gradle --no-daemon --no-scan $dryRunArg $quietToolArg publish - - echo "✅Publication via Gradle successful!" - env: - JVM_AUTH_USER: ${{ inputs.auth-user }} - JVM_AUTH_TOKEN: ${{ inputs.auth-token }} + console:echo ✅☕ JVM publication action successful! diff --git a/actions/publish-npm-package/README.md b/actions/publish-npm-package/README.md index 3f5f7d816..1d4dbed89 100644 --- a/actions/publish-npm-package/README.md +++ b/actions/publish-npm-package/README.md @@ -2,26 +2,16 @@ Publishes a **NodeJS** package to an [npm](https://www.npmjs.com/) registry. -## 🃏Example +## 🃏 Example ```yaml steps: - - uses: actions/checkout@v4 - - - uses: giancosta86/aurora-github/actions/publish-npm-package@v10 + - uses: giancosta86/aurora-github/actions/publish-npm-package@v11 with: npm-token: ${{ secrets.NPM_TOKEN }} ``` -### Remarks - -- This action is designed for _publication_ only - not for _verification_: you should call [verify-npm-package](../verify-npm-package/README.md) for that instead. - -- Before the first publication, running with `dry-run` set to **true** during the _verification_ phase is recommended. - -- This action is automatically run by [publish-rust-wasm](../publish-rust-wasm/README.md). - -## 💡How it works +## 💡 How it works 1. Run [enforce-branch-version](../enforce-branch-version/README.md), forwarding the `enforce-branch-version` input to its `mode` input. @@ -35,7 +25,15 @@ steps: 1. Run `pnpm publish`, with the value of `npm-token` injected into the **NPM_TOKEN** environment variable - accessible, for example, from the `.npmrc` configuration file. -## ☑️Requirements +## 💬 Remarks + +- This action is designed for _publication_ only - not for _verification_: you should call [verify-npm-package](../verify-npm-package/README.md) for that instead. + +- Before the first publication, running with `dry-run` set to **true** during the _verification_ phase is recommended. + +- This action is automatically run by [publish-rust-wasm](../publish-rust-wasm/README.md). + +## ☑️ Requirements - The requirements for [setup-nodejs-context](../setup-nodejs-context/README.md). @@ -45,7 +43,7 @@ steps: - Before the first publication, running with `dry-run` set to **true** is recommended. -## 📥Inputs +## 📥 Inputs | Name | Type | Description | Default value | | :----------------------: | :---------------------: | :-----------------------------------------------: | :-----------: | @@ -55,7 +53,7 @@ steps: | `enforce-branch-version` | `inject`,`check`,`skip` | How the branch version should be enforced | **inject** | | `project-directory` | **string** | The directory containing `package.json` | **.** | -## 🌐Further references +## 🌐 Further references - [setup-nodejs-context](../setup-nodejs-context/README.md) diff --git a/actions/publish-npm-package/action.yml b/actions/publish-npm-package/action.yml index c36bfcad0..5e6a2fc1f 100644 --- a/actions/publish-npm-package/action.yml +++ b/actions/publish-npm-package/action.yml @@ -3,7 +3,7 @@ description: Publishes a NodeJS package to an npm registry. inputs: dry-run: - description: Run a simulated publication via --dry-run. + description: Run a simulated publication via `--dry-run`. default: false npm-token: @@ -18,67 +18,35 @@ inputs: default: inject project-directory: - description: The directory containing package.json. + description: The directory containing `package.json`. default: . runs: using: composite steps: - - name: Validate inputs - shell: bash - working-directory: ${{ inputs.project-directory }} - run: | - if [[ -z "${{ inputs.dry-run }}" ]] - then - echo "❌Missing action input: 'dry-run'!" >&2 - exit 1 - fi - - if [[ ${{ inputs.dry-run }} != 'true' && -z "${{ inputs.npm-token }}" ]] - then - echo "❌Missing action input: 'npm-token'!" >&2 - exit 1 - fi - - if [[ -z "${{ inputs.website-directory }}" ]] - then - echo "❌Missing action input: 'website-directory'!" >&2 - exit 1 - fi - - if [[ -z "${{ inputs.enforce-branch-version }}" ]] - then - echo "❌Missing action input: 'enforce-branch-version'!" >&2 - exit 1 - fi - - if [[ ! -f "package.json" ]] - then - echo "❌The package.json descriptor file does not exist!!" >&2 - exit 1 - fi + - uses: giancosta86/aurora-github/actions/setup-elvish-context@v11.0.0 - name: Enforce branch version - uses: giancosta86/aurora-github/actions/enforce-branch-version@v10.2.0 + uses: giancosta86/aurora-github/actions/enforce-branch-version@v11.0.0 with: mode: ${{ inputs.enforce-branch-version }} project-directory: ${{ inputs.project-directory }} - name: Setup NodeJS context - uses: giancosta86/aurora-github/actions/setup-nodejs-context@v10.2.0 + uses: giancosta86/aurora-github/actions/setup-nodejs-context@v11.0.0 with: project-directory: ${{ inputs.project-directory }} - name: Try to build the package artifacts - shell: bash + shell: elvish {0} working-directory: ${{ inputs.project-directory }} run: | - source "${{ github.action_path }}/../../core/bash/npmPackage.sh" + use aurora-github/nodejs/pnpm - tryToRunNpmBuildScript + pnpm:run-optional-script build - name: Publish the GitHub Pages website - uses: giancosta86/aurora-github/actions/publish-github-pages@v10.2.0 + uses: giancosta86/aurora-github/actions/publish-github-pages@v11.0.0 with: optional: true source-directory: ${{ inputs.project-directory }}/${{ inputs.website-directory }} @@ -86,47 +54,40 @@ runs: enforce-branch-version: ${{ inputs.enforce-branch-version }} - name: Display the artifact descriptor - shell: bash + shell: elvish {0} working-directory: ${{ inputs.project-directory }} run: | - echo "The content of your 📦package.json just before publication is:" - jq -C . package.json - echo "📦📦📦" + use github.com/giancosta86/aurora-elvish/console + use aurora-github/project/descriptors/json + + console:section &emoji=📦 'package.json just before publication' { + json:print-content package.json + } - name: Ensure the package manager configuration file exists - shell: bash + shell: elvish {0} working-directory: ${{ inputs.project-directory }} run: | - npmConfigPath=".npmrc" - - if [[ ! -f "$npmConfigPath" ]] - then - echo "🌟It seems you don't have a $npmConfigPath file - generating a default one..." - - echo '//registry.npmjs.org/:_authToken=${NPM_TOKEN}' > "$npmConfigPath" + use aurora-github/nodejs/pnpm - echo "🎀Your auto-generated $npmConfigPath configuration file is:" - cat "$npmConfigPath" - echo "🎀🎀🎀" - else - echo "🌟You already have a custom $npmConfigPath file - ready to publish!" - fi + pnpm:ensure-config - name: Publish to the registry - shell: bash + shell: elvish {0} working-directory: ${{ inputs.project-directory }} run: | - if [[ "${{ inputs.dry-run }}" == "true" ]] - then - dryRunArg="--dry-run" - else - dryRunArg="" - fi - - pnpm publish --no-git-checks --access public $dryRunArg + use aurora-github/ci-cd/input + use aurora-github/nodejs/project + + var dry-run = (input:bool dry-run '${{ inputs.dry-run }}') + + project:publish $dry-run env: NPM_TOKEN: ${{ inputs.npm-token }} - name: Print confirmation message - shell: bash - run: echo "✅Npm package published successfully!" + shell: elvish {0} + run: | + use github.com/giancosta86/aurora-elvish/console + + console:echo ✅📦 Npm package publication action successful! diff --git a/actions/publish-python-package/README.md b/actions/publish-python-package/README.md index 96220c4f1..999f92685 100644 --- a/actions/publish-python-package/README.md +++ b/actions/publish-python-package/README.md @@ -2,13 +2,11 @@ Publishes a **Python** package using [PDM](https://pdm-project.org). -## 🃏Example +## 🃏 Example ```yaml steps: - - uses: actions/checkout@v4 - - - uses: giancosta86/aurora-github/actions/publish-python-package@v10 + - uses: giancosta86/aurora-github/actions/publish-python-package@v11 with: index-user: __token__ index-secret: ${{ secrets.PYPI_TOKEN }} @@ -16,7 +14,7 @@ steps: **Please, note**: this action is designed for _publication_ only - not for _verification_: you may want to use [verify-python-package](../verify-python-package/README.md) for that. -## 💡How it works +## 💡 How it works 1. Run [enforce-branch-version](../enforce-branch-version/README.md), forwarding the `enforce-branch-version` input to its `mode` input. @@ -26,7 +24,7 @@ steps: 1. Run `pdm publish`, passing the `index-` inputs as environment variables; if `dry-run` is enabled, just perform a `pdm build`, skipping actual deployment. -## ☑️Requirements +## ☑️ Requirements - `pipx` is mandatory when PDM has to be installed. @@ -34,7 +32,7 @@ steps: - Before the first publication, running with `dry-run` set to **true** is recommended. -## 📥Inputs +## 📥 Inputs | Name | Type | Description | Default value | | :----------------------: | :---------------------: | :-----------------------------------------------: | :-----------: | @@ -47,7 +45,7 @@ steps: | `enforce-branch-version` | `inject`,`check`,`skip` | How the branch version should be enforced | **inject** | | `project-directory` | **string** | The directory containing `pyproject.toml` | **.** | -## 🌐Further references +## 🌐 Further references - [publish-github-pages](../publish-github-pages/README.md) diff --git a/actions/publish-python-package/action.yml b/actions/publish-python-package/action.yml index d610e3498..92c4557ad 100644 --- a/actions/publish-python-package/action.yml +++ b/actions/publish-python-package/action.yml @@ -27,50 +27,33 @@ inputs: default: inject project-directory: - description: The directory containing pyproject.toml. + description: The directory containing `pyproject.toml`. default: . runs: using: composite steps: - - name: Validate inputs - shell: bash - working-directory: ${{ inputs.project-directory }} - run: | - if [[ -z "${{ inputs.dry-run }}" ]] - then - echo "❌Missing action input: 'dry-run'!" >&2 - exit 1 - fi - - if [[ -z "${{ inputs.website-directory }}" ]] - then - echo "❌Missing action input: 'website-directory'!" >&2 - exit 1 - fi - - if [[ -z "${{ inputs.enforce-branch-version }}" ]] - then - echo "❌Missing action input: 'enforce-branch-version'!" >&2 - exit 1 - fi + - uses: giancosta86/aurora-github/actions/setup-elvish-context@v11.0.0 - name: Enforce branch version - uses: giancosta86/aurora-github/actions/enforce-branch-version@v10.2.0 + uses: giancosta86/aurora-github/actions/enforce-branch-version@v11.0.0 with: mode: ${{ inputs.enforce-branch-version }} project-directory: ${{ inputs.project-directory }} - - name: Ensure pdm - shell: bash + - name: Setup Python context + shell: elvish {0} working-directory: ${{ inputs.project-directory }} run: | - source "${{ github.action_path }}/../../core/bash/pdm.sh" + use aurora-github/ci-cd/input + use aurora-github/python/context - ensurePdm + var pdm-version = (input:string &optional pdm-version '${{ inputs.pdm-version }}') + + context:setup &pdm-version=$pdm-version - name: Publish the GitHub Pages website - uses: giancosta86/aurora-github/actions/publish-github-pages@v10.2.0 + uses: giancosta86/aurora-github/actions/publish-github-pages@v11.0.0 with: optional: true source-directory: ${{ inputs.project-directory }}/${{ inputs.website-directory }} @@ -78,22 +61,23 @@ runs: enforce-branch-version: ${{ inputs.enforce-branch-version }} - name: Publish the package - shell: bash + shell: elvish {0} working-directory: ${{ inputs.project-directory }} run: | - if [[ "${{ inputs.dry-run }}" == "true" ]] - then - echo "💭dry-run is enabled: just building the 🐍Python project..." - pdm build - else - echo "📤Publishing the 🐍Python project..." - pdm publish $dryRunArg - fi + use aurora-github/ci-cd/input + use aurora-github/python/project + + var dry-run = (input:bool dry-run '${{ inputs.dry-run }}') + + project:publish $dry-run env: PDM_PUBLISH_REPO: ${{ inputs.index-url }} PDM_PUBLISH_USERNAME: ${{ inputs.index-user }} PDM_PUBLISH_PASSWORD: ${{ inputs.index-secret }} - name: Print confirmation message - shell: bash - run: echo "✅The 🐍Python project was published successfully!" + shell: elvish {0} + run: | + use github.com/giancosta86/aurora-elvish/console + + console:echo ✅🐍 Python publication action successful! diff --git a/actions/publish-rust-crate/README.md b/actions/publish-rust-crate/README.md index d3fa07a3b..cd1478008 100644 --- a/actions/publish-rust-crate/README.md +++ b/actions/publish-rust-crate/README.md @@ -2,38 +2,42 @@ Publishes a **Rust** crate - by default, to [crates.io](https://crates.io/) - with all of its features enabled. -## 🃏Example +## 🃏 Example ```yaml steps: - - uses: actions/checkout@v4 - - - uses: giancosta86/aurora-github/actions/publish-rust-crate@v10 + - uses: giancosta86/aurora-github/actions/publish-rust-crate@v11 with: cargo-token: ${{ secrets.CARGO_TOKEN }} ``` **Please, note**: this action is designed for _publication_ only - not for _verification_: you may want to use [verify-rust-crate](../verify-rust-crate/README.md) for that. -## 💡How it works +## 💡 How it works 1. Run [enforce-branch-version](../enforce-branch-version/README.md), forwarding the `enforce-branch-version` input to its `mode` input. -1. Prepare the descriptor - for example, enabling documentation for all the features +1. Run [setup-rust-context](../setup-rust-context/README.md) to setup a Rust toolchain. + +1. If the `document-all-features` input is **true**, enable documentation for all the features - but only if the `[package.metadata.docs.rs]` header is not already in the descriptor. For details, please consult [this link](https://docs.rs/about/metadata). + +1. Run [publish-github-pages](../publish-github-pages/README.md) with the `optional` flag enabled. -1. Run [publish-github-pages](../publish-github-pages/README.md) with the `optional` flag enabled +1. Display **Cargo.toml** just before publication. -1. Run `cargo publish`, with the `--all-features` flag +1. Run `cargo publish`, with the `--all-features` flag. -## ☑️Requirements +## ☑️ Requirements - `cargo-token` is _not_ mandatory when `dry-run` is enabled. +- `rust-toolchain.toml` must be present in `project-directory` - as described in [setup-rust-context](../setup-rust-context/README.md). + - The requirements for [publish-github-pages](../publish-github-pages/README.md) if `website-directory` references an existing directory. - Before the first publication, running with `dry-run` set to **true** is recommended. -## 📥Inputs +## 📥 Inputs | Name | Type | Description | Default value | | :----------------------: | :---------------------: | :---------------------------------------------------------------: | :-----------: | @@ -44,12 +48,14 @@ steps: | `enforce-branch-version` | `inject`,`check`,`skip` | How the branch version should be enforced | **inject** | | `project-directory` | **string** | The directory containing `Cargo.toml` | **.** | -## 🌐Further references +## 🌐 Further references - [publish-github-pages](../publish-github-pages/README.md) - [enforce-branch-version](../enforce-branch-version/README.md) +- [setup-rust-context](../setup-rust-context/README.md) + - [verify-rust-crate](../verify-rust-crate/README.md) - [aurora-github](../../README.md) diff --git a/actions/publish-rust-crate/action.yml b/actions/publish-rust-crate/action.yml index 72931cca9..f92754131 100644 --- a/actions/publish-rust-crate/action.yml +++ b/actions/publish-rust-crate/action.yml @@ -3,7 +3,7 @@ description: Publishes a Rust crate - by default, to crates.io - with all of its inputs: dry-run: - description: Run a simulated publication via --dry-run. + description: Run a simulated publication via `--dry-run`. default: false cargo-token: @@ -22,103 +22,69 @@ inputs: default: inject project-directory: - description: The directory containing Cargo.toml. + description: The directory containing `Cargo.toml`. default: . runs: using: composite steps: - - name: Validate inputs - shell: bash - working-directory: ${{ inputs.project-directory }} - run: | - if [[ -z "${{ inputs.dry-run }}" ]] - then - echo "❌Missing action input: 'dry-run'!" >&2 - exit 1 - fi - - if [[ ${{ inputs.dry-run }} != 'true' && -z "${{ inputs.cargo-token }}" ]] - then - echo "❌Missing action input: 'cargo-token'!" >&2 - exit 1 - fi - - if [[ -z "${{ inputs.document-all-features }}" ]] - then - echo "❌Missing action input: 'document-all-features'!" >&2 - exit 1 - fi - - if [[ -z "${{ inputs.website-directory }}" ]] - then - echo "❌Missing action input: 'website-directory'!" >&2 - exit 1 - fi - - if [[ -z "${{ inputs.enforce-branch-version }}" ]] - then - echo "❌Missing action input: 'enforce-branch-version'!" >&2 - exit 1 - fi + - uses: giancosta86/aurora-github/actions/setup-elvish-context@v11.0.0 - name: Enforce branch version - uses: giancosta86/aurora-github/actions/enforce-branch-version@v10.2.0 + uses: giancosta86/aurora-github/actions/enforce-branch-version@v11.0.0 with: mode: ${{ inputs.enforce-branch-version }} project-directory: ${{ inputs.project-directory }} - - shell: bash + - name: Setup Rust context + uses: giancosta86/aurora-github/actions/setup-rust-context@v11.0.0 + with: + project-directory: ${{ inputs.project-directory }} + + - name: Document all features + if: inputs.document-all-features == 'true' + shell: elvish {0} working-directory: ${{ inputs.project-directory }} run: | - prepareDescriptor() { - if [[ "${{ inputs.document-all-features }}" == "true" ]] - then - enableRustdocForAllFeatures - fi + use aurora-github/rust/project - displayDescriptor - } - - enableRustdocForAllFeatures() { - cat << EOF >> Cargo.toml - - [package.metadata.docs.rs] - all-features = true - EOF - } - - displayDescriptor() { - echo "The content of your 🦀Cargo.toml just before publication is:" - cat Cargo.toml - echo "🦀🦀🦀" - } - - prepareDescriptor + project:document-all-features - name: Publish the GitHub Pages website - uses: giancosta86/aurora-github/actions/publish-github-pages@v10.2.0 + uses: giancosta86/aurora-github/actions/publish-github-pages@v11.0.0 with: optional: true source-directory: ${{ inputs.project-directory }}/${{ inputs.website-directory }} dry-run: ${{ inputs.dry-run }} enforce-branch-version: ${{ inputs.enforce-branch-version }} + - name: Display project descriptor + shell: elvish {0} + working-directory: ${{ inputs.project-directory }} + run: | + use github.com/giancosta86/aurora-elvish/console + use aurora-github/project/descriptors/toml + + console:section &emoji=🦀 'Cargo.toml just before publication' { + toml:print-content Cargo.toml + } + - name: Publish the crate - shell: bash + shell: elvish {0} working-directory: ${{ inputs.project-directory }} run: | - if [[ "${{ inputs.dry-run }}" == "true" ]] - then - dryRunArg="--dry-run" - else - dryRunArg="" - fi - - cargo publish --all-features --allow-dirty $dryRunArg + use aurora-github/ci-cd/input + use aurora-github/rust/crate + + var dry-run = (input:bool dry-run '${{ inputs.dry-run }}') + + crate:publish $dry-run env: CARGO_REGISTRY_TOKEN: ${{ inputs.cargo-token }} - name: Print confirmation message - shell: bash - run: echo "✅The 🦀Rust crate was published successfully!" + shell: elvish {0} + run: | + use github.com/giancosta86/aurora-elvish/console + + console:echo ✅🦀 Rust crate publication action successful! diff --git a/actions/publish-rust-wasm/README.md b/actions/publish-rust-wasm/README.md index 8a1ecc5f0..1998a2e2b 100644 --- a/actions/publish-rust-wasm/README.md +++ b/actions/publish-rust-wasm/README.md @@ -2,13 +2,11 @@ Publishes a **Rust** web assembly to an [npm](https://www.npmjs.com/) registry. -## 🃏Example +## 🃏 Example ```yaml steps: - - uses: actions/checkout@v4 - - - uses: giancosta86/aurora-github/actions/publish-rust-wasm@v10 + - uses: giancosta86/aurora-github/actions/publish-rust-wasm@v11 with: npm-token: ${{ secrets.NPM_TOKEN }} wasm-pack-version: 0.13.1 @@ -17,7 +15,7 @@ steps: **Please, note**: this action is designed for _publication_ only - not for verification: you might want to use [verify-rust-wasm](../verify-rust-wasm/README.md) for that. -## 💡How it works +## 💡 How it works 1. Invoke the [install-wasm-pack](../install-wasm-pack/README.md) action, passing all the matching inputs, to install the `wasm-pack` command. @@ -27,7 +25,7 @@ steps: 1. Call [publish-npm-package](../publish-npm-package/README.md) on the **pkg** directory - passing all the matching inputs - to publish the npm package. -## ☑️Requirements +## ☑️ Requirements - the `nodejs-version` input is required for the build process; optionally, you can set the `pnpm-version` input as well, in order to request a specific pnpm version. @@ -39,7 +37,7 @@ steps: - Before the first publication, running with `dry-run` set to **true** is recommended. -## 📥Inputs +## 📥 Inputs | Name | Type | Description | Default value | | :----------------------: | :---------------------: | :--------------------------------------------------------: | :-----------: | @@ -54,7 +52,7 @@ steps: | `enforce-branch-version` | `inject`,`check`,`skip` | How the branch version should be enforced | **inject** | | `project-directory` | **string** | The directory containing `Cargo.toml` | **.** | -## 🌐Further references +## 🌐 Further references - [generate-wasm-target](../generate-wasm-target/README.md) diff --git a/actions/publish-rust-wasm/action.yml b/actions/publish-rust-wasm/action.yml index 63bf8f713..ebe2a5108 100644 --- a/actions/publish-rust-wasm/action.yml +++ b/actions/publish-rust-wasm/action.yml @@ -3,7 +3,7 @@ description: Publishes a Rust web assembly to an npm registry. inputs: dry-run: - description: Run a simulated publication via --dry-run. + description: Run a simulated publication via `--dry-run`. default: false npm-token: @@ -13,16 +13,16 @@ inputs: description: The wasm-pack version to install. npm-scope: - description: The npm package scope or "". + description: The npm package scope or ``. nodejs-version: - description: The "engines / node" version within package.json. + description: The `engines -> node` version within `package.json`. pnpm-version: - description: The "packageManager" reference to pnpm within package.json. + description: The `packageManager` reference to pnpm within `package.json`. wasm-target: - description: The target of the 'wasm-pack build' command. + description: The target of the `wasm-pack build` command. default: web website-directory: @@ -34,71 +34,21 @@ inputs: default: inject project-directory: - description: The directory containing Cargo.toml. + description: The directory containing `Cargo.toml`. default: . runs: using: composite steps: - - name: Validate inputs - shell: bash - working-directory: ${{ inputs.project-directory }} - run: | - if [[ -z "${{ inputs.dry-run }}" ]] - then - echo "❌Missing action input: 'dry-run'!" >&2 - exit 1 - fi - - if [[ ${{ inputs.dry-run }} != 'true' && -z "${{ inputs.npm-token }}" ]] - then - echo "❌Missing action input: 'npm-token'!" >&2 - exit 1 - fi - - if [[ -z "${{ inputs.wasm-pack-version }}" ]] - then - echo "❌Missing action input: 'wasm-pack-version'!" >&2 - exit 1 - fi - - if [[ -z "${{ inputs.npm-scope }}" ]] - then - echo "❌Missing action input: 'npm-scope'!" >&2 - exit 1 - fi - - if [[ -z "${{ inputs.nodejs-version }}" ]] - then - echo "❌Missing action input: 'nodejs-version'!" >&2 - exit 1 - fi - - if [[ -z "${{ inputs.wasm-target }}" ]] - then - echo "❌Missing action input: 'wasm-target'!" >&2 - exit 1 - fi - - if [[ -z "${{ inputs.website-directory }}" ]] - then - echo "❌Missing action input: 'website-directory'!" >&2 - exit 1 - fi - - if [[ -z "${{ inputs.enforce-branch-version }}" ]] - then - echo "❌Missing action input: 'enforce-branch-version'!" >&2 - exit 1 - fi + - uses: giancosta86/aurora-github/actions/setup-elvish-context@v11.0.0 - name: Install wasm-pack - uses: giancosta86/aurora-github/actions/install-wasm-pack@v10.2.0 + uses: giancosta86/aurora-github/actions/install-wasm-pack@v11.0.0 with: wasm-pack-version: ${{ inputs.wasm-pack-version }} - name: Generate the NodeJS package source files - uses: giancosta86/aurora-github/actions/generate-wasm-target@v10.2.0 + uses: giancosta86/aurora-github/actions/generate-wasm-target@v11.0.0 with: target: ${{ inputs.wasm-target }} npm-scope: ${{ inputs.npm-scope }} @@ -109,22 +59,15 @@ runs: project-directory: ${{ inputs.project-directory }} - name: Try to copy .npmrc from the project directory - shell: bash + shell: elvish {0} working-directory: ${{ inputs.project-directory }} run: | - if [[ -f ".npmrc" ]] - then - echo "🎉.npmrc configuration file found! Copying it to the package directory..." - - cp .npmrc pkg/ + use aurora-github/rust/wasm - echo "✅.npmrc file copied!" - else - echo "💭No .npmrc configuration file found in the project directory..." - fi + wasm:copy-npmrc-from-project-directory - name: Publish the GitHub Pages website - uses: giancosta86/aurora-github/actions/publish-github-pages@v10.2.0 + uses: giancosta86/aurora-github/actions/publish-github-pages@v11.0.0 with: optional: true source-directory: ${{ inputs.project-directory }}/${{ inputs.website-directory }} @@ -132,9 +75,16 @@ runs: enforce-branch-version: ${{ inputs.enforce-branch-version }} - name: Publish NodeJS package - uses: giancosta86/aurora-github/actions/publish-npm-package@v10.2.0 + uses: giancosta86/aurora-github/actions/publish-npm-package@v11.0.0 with: dry-run: ${{ inputs.dry-run }} npm-token: ${{ inputs.npm-token }} enforce-branch-version: ${{ inputs.enforce-branch-version }} project-directory: ${{ inputs.project-directory }}/pkg + + - name: Print confirmation message + shell: elvish {0} + run: | + use github.com/giancosta86/aurora-elvish/console + + console:echo ✅🦀🌐 Rust web assembly publication action successful! diff --git a/actions/run-custom-tests/README.md b/actions/run-custom-tests/README.md index 56d567ac5..302b759cc 100644 --- a/actions/run-custom-tests/README.md +++ b/actions/run-custom-tests/README.md @@ -1,70 +1,82 @@ # run-custom-tests -Executes arbitrary tests within a given directory; it runs a **shell** script by default, but can also run _pnpm_ (for **NodeJS**) or _cargo_ (for **Rust**). +Executes arbitrary tests within a given directory; it runs a shell script by default, but can also run _pnpm_ (for **NodeJS**) or _cargo_ (for **Rust**). -## 🃏Example +## 🃏 Example ```yaml steps: - - uses: giancosta86/aurora-github/actions/run-custom-tests@v10 + - uses: giancosta86/aurora-github/actions/run-custom-tests@v11 with: root-directory: client-tests ``` -### Remarks +## 💡 How it works -- You should **not** call this action for unit tests when using [verify-rust-crate](../verify-rust-crate/README.md) or [verify-npm-package](../verify-npm-package/README.md) - they are automatically run by the workflow itself. +1. If `root-directory` does not exist: -- This action is already called by [verify-rust-wasm](../verify-rust-wasm/README.md) to optionally run the tests in the **client-tests** directory. + 1. If `optional` is **true**, exit the action successfully. -- This action is already called by [verify-npm-package](../verify-npm-package/README.md) to optionally run the tests in the **tests** directory. + 1. Otherwise, crash the workflow. -## 💡How it works +1. Use `root-directory` as the current directory. -1. If `root-directory` does not exist: +1. Select the first feasible course of action: - - if `optional` is **true**, exit the action with no error + 1. If `script-file` is specified **and** can be run by forwarding it to [run-shell-script](../run-shell-script/README.md), invoke the action accordingly, passing the (optional) `script-shell`. - - otherwise, crash the workflow + 1. If **verify** (**.elv**, **.sh**, ...) exists in `working-directory` **and** can be run via [run-shell-script](../run-shell-script/README.md), invoke the action accordingly, passing the (optional) `script-shell`. -1. Detect the test type and act accordingly: + 1. If one or more files having `.test.elv` extension exist within the root directory tree, run them using [velvet](https://github.com/giancosta86/velvet) - - If a file named like `script-file` exists in the root directory, run it using `script-shell`; consequently, there is no need to mark the file as _executable_ + 1. If a file named **package.json** exists in the root directory: - - Otherwise, if a file named **package.json** exists in the root directory: + 1. Invoke [setup-nodejs-context](../setup-nodejs-context/README.md). - 1. run [setup-nodejs-context](../setup-nodejs-context/README.md) + 1. Run the **verify** script in the **scripts** section of **package.json**. - 1. run the **verify** script in the **scripts** section of **package.json** + 1. If a file named **Cargo.toml** exists in the root directory: - - Otherwise, if a file named **Cargo.toml** exists in the root directory: + 1. Invoke [setup-rust-context](../setup-rust-context/README.md), without enforcing the existence of the toolchain file. - 1. if the **rust-toolchain.toml** file exists, run [check-rust-versions](../check-rust-versions/README.md) to enforce a specific Rust toolkit + 1. Run `cargo test`: - 1. run `cargo test` with the `--all-features` flag + 1. with no features enabled - - Otherwise: + 1. with all the features enabled - - if `optional` is **true**, exit the action with no error + 1. Otherwise: - - otherwise, crash the workflow + 1. If `optional` is **true**, exit the action successfully. -## ☑️Requirements + 1. Otherwise, crash the workflow. -## 📥Inputs +## 💬 Remarks -| Name | Type | Description | Default value | -| :--------------: | :---------: | :-------------------------------------------: | :-----------: | -| `optional` | **boolean** | Exit with no error if the tests cannot be run | **false** | -| `script-file` | **string** | Relative path to the script file | **verify.sh** | -| `script-shell` | **string** | The shell used to run `script-file` | **bash** | -| `root-directory` | **string** | The directory containing the tests | | +- You should **not** call this action for unit tests when using [verify-rust-crate](../verify-rust-crate/README.md) or [verify-npm-package](../verify-npm-package/README.md) - they are automatically run by the workflow itself. -## 🌐Further references +- This action is already called by [verify-rust-wasm](../verify-rust-wasm/README.md) to optionally run the tests in the **client-tests** directory. + +- This action is already called by [verify-npm-package](../verify-npm-package/README.md) to optionally run the tests in the **tests** directory. + +## 📥 Inputs + +| Name | Type | Description | Default value | +| :--------------: | :---------: | :------------------------------------------: | :-----------: | +| `optional` | **boolean** | Exit successfully if the tests cannot be run | **false** | +| `script-file` | **string** | Relative path to the script file | | +| `script-shell` | **string** | The shell used to run `script-file` | | +| `root-directory` | **string** | The directory containing the tests | | + +## 🌐 Further references + +- [velvet](https://github.com/giancosta86/velvet) + +- [run-shell-script](../run-shell-script/README.md) - [setup-nodejs-context](../setup-nodejs-context/README.md) -- [check-rust-versions](../check-rust-versions/README.md) +- [setup-rust-context](../setup-rust-context/README.md) - [verify-rust-crate](../verify-rust-crate/README.md) @@ -72,4 +84,6 @@ steps: - [verify-rust-wasm](../verify-rust-wasm/README.md) +- [aurora-elvish](https://github.com/giancosta86/aurora-elvish) + - [aurora-github](../../README.md) diff --git a/actions/run-custom-tests/action.yml b/actions/run-custom-tests/action.yml index 0f7a6ea4c..7f1d18c68 100644 --- a/actions/run-custom-tests/action.yml +++ b/actions/run-custom-tests/action.yml @@ -1,18 +1,16 @@ name: Run custom tests -description: Executes arbitrary tests within a given directory; it runs a shell script by default, but can also run pnpm (for NodeJS) or cargo (for Rust). +description: Executes arbitrary tests within a given directory; it runs a shell script by default, but can also run `pnpm` (for NodeJS) or `cargo` (for Rust). inputs: optional: - description: Exit with no error if the tests cannot be run. + description: Exit successfully if the tests cannot be run. default: false script-file: description: Relative path to the script file. - default: verify.sh script-shell: description: The shell used to run script-file. - default: bash root-directory: description: The directory containing the tests. @@ -20,128 +18,75 @@ inputs: runs: using: composite steps: - - name: Set up strategy - shell: bash + - uses: giancosta86/aurora-github/actions/setup-elvish-context@v11.0.0 + + - name: Detect the test strategy + shell: elvish {0} run: | - main() { - validateInputs - detectTestStrategy - } - - validateInputs() { - if [[ -z "${{ inputs.optional }}" ]] - then - echo "❌Missing action input: 'optional'!" >&2 - exit 1 - fi - - if [[ -d "${{ inputs.root-directory }}" ]] - then - cd "${{ inputs.root-directory }}" - else - if [[ "${{ inputs.optional }}" == "true" ]] - then - echo "💭Skipping optional tests in missing directory: '${{ inputs.root-directory }}'" - echo "strategy=exit" >> $GITHUB_ENV - exit 0 - else - echo "❌Cannot run custom tests in missing directory: '${{ inputs.root-directory }}'" >&2 - exit 1 - fi - fi - } - - detectTestStrategy() { - echo "🔬Detecting custom test strategy in directory '${{ inputs.root-directory }}'..." - - local scriptFile="${{ inputs.script-file }}" - - if [[ -n "$scriptFile" && -f "$scriptFile" ]] - then - echo "🐚Custom test script '$scriptFile' found!" - local strategy="script" - - if [[ -z "${{ inputs.script-shell }}" ]] - then - echo "❌Missing action input: 'script-shell'!" >&2 - exit 1 - fi - elif [[ -f "package.json" ]] - then - echo "📦package.json file found!" - local strategy="nodejs" - elif [[ -f "Cargo.toml" ]] - then - echo "🦀Cargo.toml file found!" - local strategy="rust" - else - if [[ "${{ inputs.optional }}" == "true" ]] - then - echo "💭No supported strategy detected for the optional custom tests" - local strategy="exit" - else - echo "❌Cannot run custom tests: no supported test strategy could be detected!" >&2 - exit 1 - fi - fi - - echo "🔎Test strategy: '$strategy'" - - echo "strategy=$strategy" >> $GITHUB_ENV - } - - main - - - name: Run script + use aurora-github/ci-cd/input + use aurora-github/custom-tests + + custom-tests:detect-strategy [ + &optional=(input:bool optional '${{ inputs.optional }}') + + &script-file=(input:string &optional script-file '${{ inputs.script-file }}') + + &root-directory=(input:directory &optional &can-be-missing root-directory '${{ inputs.root-directory }}') + ] + + - name: Run test script if: env.strategy == 'script' - shell: bash + uses: giancosta86/aurora-github/actions/run-shell-script@v11.0.0 + with: + optional: false + script-file: ${{ env.scriptPath }} + shell: ${{ inputs.script-shell }} + working-directory: ${{ inputs.root-directory }} + + - name: Run tests via Velvet + if: env.strategy == 'velvet' + shell: elvish {0} working-directory: ${{ inputs.root-directory }} run: | - echo "🐚Now running the custom script '${{ inputs.script-file }}' using '${{ inputs.script-shell }}'..." + use github.com/giancosta86/velvet/main velvet - "${{ inputs.script-shell }}" "${{ inputs.script-file }}" + velvet:velvet &must-pass - name: Setup NodeJS context if: env.strategy == 'nodejs' - uses: giancosta86/aurora-github/actions/setup-nodejs-context@v10.2.0 + uses: giancosta86/aurora-github/actions/setup-nodejs-context@v11.0.0 with: project-directory: ${{ inputs.root-directory }} - name: Run the 'verify' script from package.json if: env.strategy == 'nodejs' - shell: bash + shell: elvish {0} working-directory: ${{ inputs.root-directory }} run: | - echo "📦Now running the 'verify' script from package.json..." - pnpm verify + use aurora-github/nodejs/project - - name: Check for the Rust toolchain file + project:verify + + - name: Setup Rust context if: env.strategy == 'rust' - shell: bash - working-directory: ${{ inputs.root-directory }} - run: | - if [[ -f "rust-toolchain.toml" ]] - then - echo "checkRustVersions=true" >> $GITHUB_ENV - else - echo "checkRustVersions=false" >> $GITHUB_ENV - fi - - - name: Check Rust versions - if: env.strategy == 'rust' && env.checkRustVersions == 'true' - uses: giancosta86/aurora-github/actions/check-rust-versions@v10.2.0 + uses: giancosta86/aurora-github/actions/setup-rust-context@v11.0.0 with: + check-toolchain-file: false project-directory: ${{ inputs.root-directory }} - - name: Run tests via Cargo + - name: Run the tests via Cargo if: env.strategy == 'rust' - shell: bash + shell: elvish {0} working-directory: ${{ inputs.root-directory }} run: | - echo "🦀Running Rust tests with all the features enabled..." - cargo test --all-features + use aurora-github/rust/project + + project:run-tests - name: Print confirmation message if: env.strategy != 'exit' - shell: bash - run: echo "✅Custom tests in directory '${{ inputs.root-directory }}' run successfully!" + shell: elvish {0} + run: | + use github.com/giancosta86/aurora-elvish/console + + console:echo ✅ Custom tests in directory "'"${{ inputs.root-directory }}"'" run successfully! diff --git a/actions/run-shell-script/README.md b/actions/run-shell-script/README.md new file mode 100644 index 000000000..f9c835837 --- /dev/null +++ b/actions/run-shell-script/README.md @@ -0,0 +1,52 @@ +# run-shell-script + +Runs a shell script, supporting different shells. + +## 🃏 Example + +```yaml +steps: + - uses: giancosta86/aurora-github/actions/run-shell-script@v11 + with: + script-file: process-data #Can detect both the extension and the shell automatically + working-directory: src +``` + +## 💡 How it works + +1. Look for the given `script-file` within `working-directory`; if it does not exist, try adding the following extensions, in this order: + + 1. **.elv** + + 1. **.sh** + + If no script file can still be found, exit the process - with an error, unless `optional` is set to **true**. + +1. If `shell` is specified, it will be invoked to run the script; otherwise, detect it from the extension of the actual script file: + + | Extension | Default shell | + | :-------: | :-----------: | + | **.elv** | `elvish` | + | **.sh** | `bash` | + + If no shell can still be detected, exit the process - with an error, unless `optional` is set to **true**. + +1. Within `working-directory`, run: + + ``` + + ``` + +## 📥 Inputs + +| Name | Type | Description | Default value | +| :-----------------: | :----------------------: | :---------------------------------------------------------: | :-----------: | +| `optional` | **boolean** | Exit successfully if no script can be run | **false** | +| `script-file` | **string** | Relative path - in `working-directory` - to the script file | | +| `shell` | **string** | The shell used to run the script | | +| `args` | **comma-separated list** | Arguments to be passed to the script | | +| `working-directory` | **string** | The working directory | **.** | + +## 🌐 Further references + +- [aurora-github](../../README.md) diff --git a/actions/run-shell-script/action.yml b/actions/run-shell-script/action.yml new file mode 100644 index 000000000..406d0a2d9 --- /dev/null +++ b/actions/run-shell-script/action.yml @@ -0,0 +1,43 @@ +name: Run shell script +description: Runs a shell script, supporting different shells. + +inputs: + optional: + description: Exit successfully if the script cannot be run. + default: false + + script-file: + description: Relative path - in the working directory - to the script file. + + shell: + description: The shell used to run the script. + + args: + description: Comma-separated list of arguments passed to the script. + + working-directory: + description: The working directory. + default: . + +runs: + using: composite + steps: + - uses: giancosta86/aurora-github/actions/setup-elvish-context@v11.0.0 + + - name: Run the script + shell: elvish {0} + run: | + use aurora-github/ci-cd/input + use aurora-github/script + + var optional = (input:bool optional '${{ inputs.optional }}') + + var script-file = (input:string script-file '${{ inputs.script-file }}') + + var shell = (input:string &optional shell '${{ inputs.shell }}') + + var args = (input:list '${{ inputs.args }}') + + var working-directory = (input:directory &optional &can-be-missing working-directory '${{ inputs.working-directory }}') + + script:run &working-directory=$working-directory &optional=$optional &shell=$shell $script-file $@args diff --git a/actions/setup-elvish-context/README.md b/actions/setup-elvish-context/README.md index e77a60da3..cb0c47862 100644 --- a/actions/setup-elvish-context/README.md +++ b/actions/setup-elvish-context/README.md @@ -1,17 +1,15 @@ # setup-elvish-context -Installs an **Elvish** version and optional startup packages, caching everything between multiple jobs of the same workflow execution. +Installs the **Elvish** shell, caching it between multiple jobs of the same workflow execution. -## 🃏Example +## 🃏 Example ```yaml steps: - - uses: actions/checkout@v4 - - - uses: giancosta86/aurora-github/actions/setup-elvish-context@v10 + - uses: giancosta86/aurora-github/actions/setup-elvish-context@v11 ``` -## 💡How it works +## 💡 How it works 1. If the `elvish` command is already available in the system and the `skip-if-existing` input is set to **true** (the default), the action will do just nothing @@ -19,39 +17,31 @@ steps: - Otherwise, install the **Elvish** shell, making the `elvish` command available along the system **PATH** -1. If at least one package was specified in the `packages` input (which **MUST** be either empty or a comma/space-separated list): - - - If the exact set of packages was already requested by a previous execution of this action during the current workflow, use the cached version - - - Otherwise, install them via `epm:install`, then cache the entire `$epm:managed-dir` directory - -### Notes - -1. The cache spans over the lifetime of a specific **workflow execution** - so every new workflow run will not see the previously cached entries. +## 💬 Remarks -1. The `aurora-github` package - contained in the [lib](../../lib/) directory - will also be available to any Elvish shell retrieved via this action; however, such library is to be considered **unstable** even between patch versions, so it should be used in custom script steps _only_ when your workflow references this action from a _specific release_ of aurora-github. +- The cache spans over the lifetime of a specific **workflow execution** - so every new workflow run will not see the previously cached entries. -## ☑️Requirements +- The following packages will also be available: -The requested Elvish version **must** include an `epm` module having a `$managed-dir` variable. + - `aurora-github` - contained in the [core](../../core/) directory - however, such library is to be considered **unstable** even between patch versions, so it should be used in custom script steps _only_ when your workflow references this action from a _specific release_ of aurora-github. -Also, if the `packages` input is non-empty, `epm` must provide the following functions: + - [aurora-elvish](https://github.com/giancosta86/aurora-elvish) - at branch **v1** -- `install` +- You need this action only to run your custom Elvish scripts - because it is automatically called by almost every action in aurora-github. -- `installed` +## ☑️ Requirements -All the above features must follow the protocol described in the documentation for Elvish v0.21. +The requested Elvish version **must** include an `epm` module having a `$managed-dir` variable - for example, Elvish v0.21. -## 📥Inputs +## 📥 Inputs -| Name | Type | Description | Default value | -| :----------------: | :-----------------------------------------: | :---------------------------------------------------: | :-----------: | -| `version` | **string** | The Elvish version to download and cache | **0.21.0** | -| `packages` | **string** - empty or space/comma-separated | Packages to install and cache with Elvish | | -| `skip-if-existing` | **boolean** | If the `elvish` command is available, just do nothing | **true** | +| Name | Type | Description | Default value | +| :----------------: | :---------: | :---------------------------------------------------: | :-----------: | +| `version` | **string** | The Elvish version to download and cache | **0.21.0** | +| `skip-if-existing` | **boolean** | If the `elvish` command is available, just do nothing | **true** | +| `quiet` | **boolean** | Only print warnings and errors | **true** | -## 🌐Further references +## 🌐 Further references - [Elvish](https://elv.sh/) diff --git a/actions/setup-elvish-context/action.yml b/actions/setup-elvish-context/action.yml index 3ba00b6fa..21b987d0d 100644 --- a/actions/setup-elvish-context/action.yml +++ b/actions/setup-elvish-context/action.yml @@ -1,162 +1,109 @@ name: Setup an Elvish context -description: Installs an Elvish version and optional startup packages, caching everything between multiple jobs of the same workflow execution. +description: Installs the Elvish shell, caching it between multiple jobs of the same workflow execution. inputs: version: description: The requested Elvish version. default: 0.21.0 - packages: - description: Startup packages - empty or space/comma-separated - to install via epm. - default: "" - skip-if-existing: - description: If the 'elvish' command is available, just do nothing. + description: If the `elvish` command is available, just do nothing. + default: true + + quiet: + description: Only print warnings and errors. default: true runs: using: composite steps: - - name: Validate inputs + - name: Initialize the action shell: bash run: | - if [[ -z "${{ inputs.version }}" ]] - then - echo "❌Missing action input: 'version'!" >&2 - exit 1 - fi + source "${{ github.action_path }}/bootstrap.sh" - if [[ -z "${{ inputs.skip-if-existing }}" ]] - then - echo "❌Missing action input: 'skip-if-existing'!" >&2 - exit 1 - fi + requireInput version '${{ inputs.version }}' + requireInput skip-if-existing '${{ inputs.skip-if-existing }}' + requireInput quiet '${{ inputs.quiet }}' - - name: Detect if the action should be skipped - shell: bash - run: | - skip=false + tracingEnabled="$(not '${{ inputs.quiet }}')" + setTracing $tracingEnabled - if type elvish + if shouldInstallCommand elvish '${{ inputs.skip-if-existing }}' then - echo "💬Elvish is already installed on the system!" - - if [[ "${{ inputs.skip-if-existing }}" == "true" ]] - then - echo "🌟Skipping the setup, as requested!" - skip=true - else - echo "📥Still proceeding with the setup, as requested!" - fi + elvishCacheKey="${{ github.workflow }}-${{ github.run_number }}-elvish-shell-v${{ inputs.version }}" + trace "🔎Elvish cache key: '$elvishCacheKey'" + + writeEnv elvish-cache-key "$elvishCacheKey" + writeEnv elvish-command-path /usr/local/bin/elvish + writeEnv skip-binary false else - echo "💭Elvish shell not found on the system..." + writeEnv skip-binary true fi - echo "skip=$skip" >> $GITHUB_ENV - - - name: Setup environment variables - if: env.skip != 'true' - shell: bash - run: | - elvishCacheKey="${{ github.workflow }}-${{ github.run_number }}-elvish-shell-v${{ inputs.version }}" - echo "🔎Elvish cache key: '$elvishCacheKey'" - - echo "elvish-cache-key=$elvishCacheKey" >> $GITHUB_ENV - - name: Restore cached Elvish binary id: restore-cached-elvish - if: env.skip != 'true' + if: env.skip-binary != 'true' uses: actions/cache/restore@v4 with: - path: /usr/local/bin/elvish key: ${{ env.elvish-cache-key }} + path: ${{ env.elvish-command-path }} - - name: Confirm cache hit for Elvish - if: env.skip != 'true' && steps.restore-cached-elvish.outputs.cache-hit == 'true' + - name: Confirm cache hit for Elvish binary + if: env.skip-binary != 'true' && inputs.quiet != 'true' && steps.restore-cached-elvish.outputs.cache-hit == 'true' shell: elvish {0} - run: echo 🚀Elvish ${{ inputs.version }} loaded from cache! + run: echo 🚀 Elvish ${{ inputs.version }} loaded from cache! > &2 - name: Install Elvish - if: env.skip != 'true' && steps.restore-cached-elvish.outputs.cache-hit != 'true' + if: env.skip-binary != 'true' && steps.restore-cached-elvish.outputs.cache-hit != 'true' uses: elves/setup-elvish@v1 with: elvish-version: ${{ inputs.version }} - name: Confirm installation for Elvish - if: env.skip != 'true' && steps.restore-cached-elvish.outputs.cache-hit != 'true' + if: env.skip-binary != 'true' && inputs.quiet != 'true' && steps.restore-cached-elvish.outputs.cache-hit != 'true' shell: elvish {0} - run: echo 🚀Elvish ${{ inputs.version }} installed! + run: echo 🚀 Elvish ${{ inputs.version }} installed! > &2 - name: Cache Elvish binary - if: env.skip != 'true' && steps.restore-cached-elvish.outputs.cache-hit != 'true' + if: env.skip-binary != 'true' && steps.restore-cached-elvish.outputs.cache-hit != 'true' uses: actions/cache/save@v4 with: - path: /usr/local/bin/elvish + path: ${{ env.elvish-command-path }} key: ${{ env.elvish-cache-key }} - - name: Copy the aurora-github package for Elvish - if: env.skip != 'true' + - name: Link the aurora-github core as an Elvish package shell: elvish {0} run: | use epm use os + use path - echo "📥Now installing the 🔮aurora-github package for Elvish..." os:mkdir-all $epm:managed-dir - var aurora-github-package-directory = ${{ github.action_path }}/../../lib + var aurora-github-core-directory = (path:join '${{ github.action_path }}' .. .. core) - cp -r $aurora-github-package-directory $epm:managed-dir/aurora-github + var link-path = (path:join $epm:managed-dir aurora-github) - echo "✅aurora-github package installed!" + if (not (os:exists $link-path)) { + os:symlink $aurora-github-core-directory $link-path + } - - name: Compute package-related environment variables - if: env.skip != 'true' && inputs.packages != '' + - name: Print core confirmation message + if: inputs.quiet != 'true' shell: elvish {0} run: | - use aurora-github/startup-libs - - startup-libs:setup-env-vars [ - &workflow=${{ github.workflow }} - &run-number=${{ github.run_number }} - &packages='${{ inputs.packages }}' - ] + echo 🔮 Now booting aurora-github for Elvish! - - name: Restore cached startup packages - if: env.skip != 'true' && inputs.packages != '' - id: restore-cached-packages - uses: actions/cache/restore@v4 + - name: Setup aurora-elvish + uses: giancosta86/aurora-github/actions/setup-elvish-package@v11.0.0 with: - path: ${{ env.epm-dir }} - key: ${{ env.epm-cache-key }} + package: github.com/giancosta86/aurora-elvish + git-ref: v1 + quiet: ${{ inputs.quiet }} - - name: Confirm cache hit for Elvish - if: env.skip != 'true' && inputs.packages != '' && steps.restore-cached-packages.outputs.cache-hit == 'true' - shell: elvish {0} - run: echo 🚀Startup packages for Elvish loaded from cache! - - - name: Install startup packages - if: env.skip != 'true' && inputs.packages != '' && steps.restore-cached-packages.outputs.cache-hit != 'true' + - name: Print final confirmation message + if: inputs.quiet != 'true' shell: elvish {0} run: | - use aurora-github/startup-libs - startup-libs:install $E:comma-separated-packages - - - name: Cache Elvish packages - if: env.skip != 'true' && inputs.packages != '' && steps.restore-cached-packages.outputs.cache-hit != 'true' - uses: actions/cache/save@v4 - with: - path: ${{ env.epm-dir }} - key: ${{ env.epm-cache-key }} - - - name: Print startup packages - if: env.skip != 'true' && inputs.packages != '' - shell: elvish {0} - run: | - use aurora-github/startup-libs - startup-libs:list - - - name: Print confirmation message - if: env.skip != 'true' - shell: elvish {0} - run: echo ✅Elvish context ready! + echo ✅ Elvish context ready! diff --git a/actions/setup-elvish-context/bootstrap.sh b/actions/setup-elvish-context/bootstrap.sh new file mode 100644 index 000000000..43fcca45e --- /dev/null +++ b/actions/setup-elvish-context/bootstrap.sh @@ -0,0 +1,71 @@ +set -e +set -u +set -o pipefail + +tracingVarName='AURORA_GITHUB_TRACING_ENABLED' + +requireInput() { + local name="$1" + local value="$2" + + if [[ -z "$value" ]] + then + echo "❌ Missing action input: '$name'!" >&2 + exit 1 + fi +} + +writeEnv() { + local name="$1" + local value="$2" + + echo "$name=$value" >> $GITHUB_ENV +} + +not() { + local value="$1" + + if [[ "$value" == 'true' ]] + then + echo false + else + echo true + fi +} + +setTracing() { + local enabled="$1" + + export "$tracingVarName=$enabled" + + writeEnv $tracingVarName "$enabled" +} + +trace() { + if [[ "${!tracingVarName:-}" == "true" ]] + then + echo "$@" + fi +} + +shouldInstallCommand() { + local command="$1" + local skipIfExisting="$2" + + if type "$command" > /dev/null 2>&1 + then + trace "🌟The '$command' command is already installed on the system!" + + if [[ "$skipIfExisting" == "true" ]] + then + trace "💫Skipping the setup, as requested!" + return 1 + else + trace "📥Still proceeding with the setup, as requested!" + return 0 + fi + fi + + trace "💭The '$command' command is not available - now installing it..." + return 0 +} diff --git a/actions/setup-elvish-package/action.yml b/actions/setup-elvish-package/action.yml new file mode 100644 index 000000000..8d6635b2d --- /dev/null +++ b/actions/setup-elvish-package/action.yml @@ -0,0 +1,117 @@ +name: Setup Elvish package +description: Ensures a package for the Elvish shell is installed, possibly at a specific Git reference. + +inputs: + package: + description: The name of the library, passed to epm:install. + + git-ref: + description: The optional Git reference (branch, tag, ...) to checkout. + + quiet: + description: Displays more detailed messages. + default: true + +runs: + using: composite + steps: + - name: Validate inputs + shell: elvish {0} + run: | + if (== 0 (count '${{ inputs.package }}')) { + fail 'Missing input: package' + } + + if (== 0 (count '${{ inputs.quiet }}')) { + fail 'Missing input: quiet' + } + + if (not (has-value [true false] '${{ inputs.quiet }}')) { + fail 'Invalid boolean input for ''quiet'': '''${{ inputs.quiet }}"'" + } + + - name: Set environment variables + shell: elvish {0} + run: | + use epm + use os + + var package-cache-key = '${{ github.workflow }}-${{ github.run_number }}-elvish-package-${{ inputs.package }}' + + var package-path = (epm:metadata '${{ inputs.package }}')[dst] + + var package-installed = ( + if (os:is-dir $package-path) { + put 'true' + } else { + put 'false' + } + ) + + echo elvish-package-cache-key=$package-cache-key >> (get-env GITHUB_ENV) + + echo elvish-package-path=$package-path >> (get-env GITHUB_ENV) + + echo elvish-package-installed=$package-installed >> (get-env GITHUB_ENV) + + - name: Declare the package is already installed + if: env.elvish-package-installed == 'true' && inputs.quiet != 'true' + shell: elvish {0} + run: echo 🌟📚Elvish package '${{ inputs.package }}' is already installed! > &2 + + - name: Restore cached package + if: env.elvish-package-installed != 'true' + id: restore-cached-package + uses: actions/cache/restore@v4 + with: + key: ${{ env.elvish-package-cache-key }} + path: ${{ env.elvish-package-path }} + + - name: Confirm cache hit for Elvish package + if: env.elvish-package-installed != 'true' && steps.restore-cached-package.outputs.cache-hit == 'true' && inputs.quiet != 'true' + shell: elvish {0} + run: echo 📤📚 Elvish package '${{ inputs.package }}' restored from cache! > &2 + + - name: Install package via epm + if: env.elvish-package-installed != 'true' && steps.restore-cached-package.outputs.cache-hit != 'true' + shell: elvish {0} + run: | + use epm + + epm:install '${{ inputs.package }}' + + - name: Cache Elvish package + if: env.elvish-package-installed != 'true' && steps.restore-cached-package.outputs.cache-hit != 'true' + uses: actions/cache/save@v4 + with: + path: ${{ env.elvish-package-path }} + key: ${{ env.elvish-package-cache-key }} + + - name: Ensure the requested Git reference + if: inputs.git-ref != '' + shell: elvish {0} + run: | + use os + + var quiet = (==s '${{ inputs.quiet }}' true) + + if (not $quiet) { + echo 🧭Switching Elvish package '${{ inputs.package }}' to Git reference: '${{ inputs.git-ref }}' + } + + cd (get-env elvish-package-path) + + { + git clean -df + + git checkout '${{ inputs.git-ref }}' + } > $os:dev-null 2> $os:dev-null + + if (not $quiet) { + echo ✅ Switched to Git reference '${{ inputs.git-ref }}' + } + + - name: Display final confirmation message + if: inputs.quiet != 'true' + shell: elvish {0} + run: echo 🚀📚 Elvish package '${{ inputs.package }}' ready! > &2 diff --git a/actions/setup-nodejs-context/README.md b/actions/setup-nodejs-context/README.md index 1f3ad5e74..5165e9fd1 100644 --- a/actions/setup-nodejs-context/README.md +++ b/actions/setup-nodejs-context/README.md @@ -2,34 +2,36 @@ Conditionally installs **NodeJS** along with **pnpm**, as well as the dependencies listed in **package.json**. -## 🃏Example +## 🃏 Example ```yaml steps: - - uses: actions/checkout@v4 - - - uses: giancosta86/aurora-github/actions/setup-nodejs-context@v10 + - uses: giancosta86/aurora-github/actions/setup-nodejs-context@v11 ``` **Please, note**: this action is automatically run by [verify-npm-package](../verify-npm-package/README.md) and [publish-npm-package](../publish-npm-package/README.md). -## 💡How it works +## 💡 How it works -1. If **package.json** - which must exist - declares the following field: +1. Determine whether a specific NodeJS toolchain must be installed; this happens in one of the following cases - considered in this order: - ```json - { - "engines": { - "node": "..." - } - } - ``` + 1. If the **.nvmrc** file exists in the project directory - containing the requested NodeJS version, as expected by `nvm` - an entire NodeJS toolchain will be set up; in particular: + 1. If **package.json** declares the following field: - 1. The requested **NodeJS** version - or a compatible one, if a range is passed - will be installed via [actions/setup-node](https://github.com/actions/setup-node) + ```json + { + "engines": { + "node": "..." + } + } + ``` + + **PLEASE, NOTE**: if you are using Bash as your development shell, you may want to install the [nvmcd](https://github.com/giancosta86/aurora-bash/tree/main/scripts/nvmcd) command from the [aurora-bash](https://github.com/giancosta86/aurora-bash) project. - **PLEASE, NOTE**: if you are using Bash as your development shell, you may want to install the [nvmcd](https://github.com/giancosta86/aurora-bash/tree/main/scripts/nvmcd) command from the [aurora-bash](https://github.com/giancosta86/aurora-bash) project. +1. If the NodeJS toolchain is to be set up: + + 1. The requested **NodeJS** version - or a compatible one, if a range is passed - will be installed via [actions/setup-node](https://github.com/actions/setup-node) 1. **pnpm** will be downloaded via [pnpm/action-setup](https://github.com/pnpm/action-setup). @@ -47,13 +49,15 @@ steps: - otherwise, the **latest** version will be installed +1. Set the `FORCE_COLOR` environment variable according to the value of the `pnpm-colors` input. + 1. No matter whether the toolchain was installed, retrieve the dependencies - as follows: - 🧊 if **pnpm-lock.yaml** exists, it is considered _frozen_ via the `--frozen-lockfile` flag - 🌞 otherwise, `--no-frozen-lockfile` is passed explicitly -## ☑️Requirements +## ☑️ Requirements - The **package.json** descriptor must exist in `project-directory`. @@ -61,13 +65,14 @@ steps: - If the **pnpm-lock.yaml** file exists, it must be up-to-date - because it's considered _frozen_. -## 📥Inputs +## 📥 Inputs -| Name | Type | Description | Default value | -| :-----------------: | :--------: | :-------------------------------------: | :-----------: | -| `project-directory` | **string** | The directory containing `package.json` | **.** | +| Name | Type | Description | Default value | +| :-----------------: | :---------: | :-------------------------------------: | :-----------: | +| `pnpm-colors` | **boolean** | Enable colors for pnpm | **true** | +| `project-directory` | **string** | The directory containing `package.json` | **.** | -## 🌐Further references +## 🌐 Further references - [nvmcd](https://github.com/giancosta86/aurora-bash/tree/main/scripts/nvmcd) from [aurora-bash](https://github.com/giancosta86/aurora-bash) diff --git a/actions/setup-nodejs-context/action.yml b/actions/setup-nodejs-context/action.yml index 315db488d..561d697c4 100644 --- a/actions/setup-nodejs-context/action.yml +++ b/actions/setup-nodejs-context/action.yml @@ -1,126 +1,100 @@ name: Setup a NodeJS context -description: Conditionally installs NodeJS along with pnpm, as well as the dependencies listed in package.json. +description: Conditionally installs NodeJS along with `pnpm`, as well as the dependencies listed in package.json. inputs: + pnpm-colors: + description: Enable colors for `pnpm` + default: true + project-directory: - description: The directory containing package.json. + description: The directory containing `package.json`. default: . runs: using: composite steps: - - name: Verify package.json - shell: bash + - uses: giancosta86/aurora-github/actions/setup-elvish-context@v11.0.0 + + - name: Check preconditions + shell: elvish {0} working-directory: ${{ inputs.project-directory }} run: | - echo "💻Setting up NodeJS context in '${{ inputs.project-directory }}'..." + use aurora-github/nodejs/context - if [[ ! -f "package.json" ]] - then - echo "❌The package.json descriptor is missing!" >&2 - exit 1 - fi + context:check-preconditions - name: Detect toolchain constraints - id: detect-toolchain-constraints - shell: bash + id: detect-nodejs-constraints + shell: elvish {0} working-directory: ${{ inputs.project-directory }} run: | - requestedNodeVersion="$(jq -r '.engines.node // ""' package.json)" - - if [[ -n "$requestedNodeVersion" ]] - then - echo "🔎NodeJS version requested in package.json: '$requestedNodeVersion'" - installToolchain=true - else - echo "💭No requested NodeJS version in package.json..." - installToolchain=false - fi + use aurora-github/ci-cd/output + use aurora-github/nodejs/context - echo "echo 🔎Install NodeJS toolchain? $installToolchain" - - echo "install-toolchain=$installToolchain" >> $GITHUB_OUTPUT - - echo "requested-node-version=$requestedNodeVersion" >> $GITHUB_OUTPUT + output:map (context:detect-nodejs-constraints) - name: Install NodeJS - if: steps.detect-toolchain-constraints.outputs.install-toolchain == 'true' + if: steps.detect-nodejs-constraints.outputs.install-toolchain == 'true' uses: actions/setup-node@v4 with: - node-version: ${{ steps.detect-toolchain-constraints.outputs.requested-node-version }} + node-version: ${{ steps.detect-nodejs-constraints.outputs.requested-node-version }} - name: Print NodeJS version - shell: bash + shell: elvish {0} working-directory: ${{ inputs.project-directory }} run: | - echo "🎡NodeJS version: '$(node --version)'" + use github.com/giancosta86/aurora-elvish/console + + console:inspect &emoji=🎡 'NodeJS version' (node --version) - name: Detect the requested pnpm version - if: steps.detect-toolchain-constraints.outputs.install-toolchain == 'true' - id: detect-pnpm-version - shell: bash + if: steps.detect-nodejs-constraints.outputs.install-toolchain == 'true' + id: detect-pnpm-constraints + shell: elvish {0} working-directory: ${{ inputs.project-directory }} run: | - packageManagerReference="$(jq -r '.packageManager // ""' package.json)" - - echo "📦Package manager reference: '$packageManagerReference'" - - if [[ -n "$packageManagerReference" ]] - then - requestedPackageManager="$(echo "$packageManagerReference" | cut -d '@' -f 1)" - - if [[ "$requestedPackageManager" != "pnpm" ]] - then - echo "❌The package manager must be pnpm!" >&2 - exit 1 - fi - - requestedPnpmVersion="$(echo "$packageManagerReference" | cut -d '@' -f 2)" - - echo "🔎Requested pnpm version: '$requestedPnpmVersion'" - - pnpmVersion="$requestedPnpmVersion" - else - echo "🌟Defaulting to the latest pnpm version!" - pnpmVersion="latest" - fi + use aurora-github/ci-cd/output + use aurora-github/nodejs/context - echo "🔬pnpm version to install: '$pnpmVersion'" - - echo "requested-pnpm-version=$pnpmVersion" >> $GITHUB_OUTPUT + output:map (context:detect-pnpm-constraints) - name: Install pnpm - if: steps.detect-toolchain-constraints.outputs.install-toolchain == 'true' + if: steps.detect-nodejs-constraints.outputs.install-toolchain == 'true' uses: pnpm/action-setup@v4 with: - version: ${{ steps.detect-pnpm-version.outputs.requested-pnpm-version }} + version: ${{ steps.detect-pnpm-constraints.outputs.requested-pnpm-version }} - - name: Print pnpm version - shell: bash + - name: Setup colors for pnpm + shell: elvish {0} working-directory: ${{ inputs.project-directory }} run: | - echo "📦pnpm version: $(pnpm --version)" + use aurora-github/ci-cd/input + use aurora-github/nodejs/context - - name: Install the dependencies - shell: bash + var pnpm-colors = (input:bool pnpm-colors '${{ inputs.pnpm-colors }}') + + context:set-pnpm-colors $pnpm-colors + + - name: Print pnpm version + shell: elvish {0} working-directory: ${{ inputs.project-directory }} run: | - lockFile="pnpm-lock.yaml" + use github.com/giancosta86/aurora-elvish/console - if [[ -f "$lockFile" ]] - then - echo "🧊Installing dependencies with frozen lockfile, as '$lockFile' is present..." - lockFileArg="--frozen-lockfile" - else - echo "🌞Installing dependencies without frozen lockfile, as '$lockFile' is missing..." - lockFileArg="--no-frozen-lockfile" - fi + console:inspect &emoji=📦 'pnpm version' (pnpm --version) - pnpm install $lockFileArg + - name: Install the dependencies + shell: elvish {0} + working-directory: ${{ inputs.project-directory }} + run: | + use aurora-github/nodejs/context - echo "✅Dependencies installed!" + context:install-dependencies - name: Print confirmation message - shell: bash + shell: elvish {0} working-directory: ${{ inputs.project-directory }} - run: echo "✅NodeJS context in '${{ inputs.project-directory }}' ready!" + run: | + use github.com/giancosta86/aurora-elvish/console + + console:echo ✅📦 NodeJS context in "'"${{ inputs.project-directory }}"'" ready! diff --git a/actions/setup-rust-context/README.md b/actions/setup-rust-context/README.md new file mode 100644 index 000000000..f1a01e3f3 --- /dev/null +++ b/actions/setup-rust-context/README.md @@ -0,0 +1,55 @@ +# setup-rust-context + +Installs and configures a **Rust** toolchain. + +## 🃏 Example + +```yaml +steps: + - uses: giancosta86/aurora-github/actions/setup-rust-context@v11 +``` + +**Please, note**: this action is automatically run by [verify-rust-crate](../verify-rust-crate/README.md), [publish-rust-crate](../publish-rust-crate/README.md) and [run-custom-tests](../run-custom-tests/README.md). + +## 💡 How it works + +1. Set the `CARGO_TERM_COLOR` environment variable according to the value of the `cargo-colors` input. + +1. If the `check-toolchain-file` input is **true**, verify that the toolchain file (discussed above) exists. + +1. Ensure the required components (**rustfmt**, **clippy**) are installed. + +1. Display the versions of the executables in the current Rust toolchain. + +## ☑️ Requirements + +- The **Cargo.toml** descriptor must exist in `project-directory`. + +- Some version of the `cargo` and `rustup` executables must already be available in the path. + +- if the `check-toolchain-file` input is **true**, the [toolchain file](https://rust-lang.github.io/rustup/overrides.html#the-toolchain-file) file must exist within `project-directory`. + + It should include at least the required toolchain version, for example: + + ```toml + [toolchain] + channel = "1.80.0" + ``` + +## 📥 Inputs + +| Name | Type | Description | Default value | +| :--------------------: | :---------: | :-----------------------------------------: | :-----------: | +| `cargo-colors` | **boolean** | Enable colors for Cargo | **true** | +| `check-toolchain-file` | **boolean** | Verify the existence of the toolchain file | **true** | +| `project-directory` | **string** | The directory containing the toolchain file | **.** | + +## 🌐 Further references + +- [verify-rust-crate](../verify-rust-crate/README.md) + +- [publish-rust-crate](../publish-rust-crate/README.md) + +- [run-custom-tests](../run-custom-tests/README.md) + +- [aurora-github](../../README.md) diff --git a/actions/setup-rust-context/action.yml b/actions/setup-rust-context/action.yml new file mode 100644 index 000000000..0ad06cfe1 --- /dev/null +++ b/actions/setup-rust-context/action.yml @@ -0,0 +1,31 @@ +name: Setup Rust context +description: Installs and configures a Rust toolchain. + +inputs: + cargo-colors: + description: Enable colors for `cargo` + default: true + + check-toolchain-file: + description: Verify the existence of the toolchain file. + default: true + + project-directory: + description: The directory containing the toolchain file. + default: . + +runs: + using: composite + steps: + - uses: giancosta86/aurora-github/actions/setup-elvish-context@v11.0.0 + + - shell: elvish {0} + working-directory: ${{ inputs.project-directory }} + run: | + use aurora-github/ci-cd/input + use aurora-github/rust/context + + var cargo-colors = (input:bool cargo-colors '${{ inputs.cargo-colors }}') + var check-toolchain-file = (input:bool check-toolchain-file '${{ inputs.check-toolchain-file }}') + + context:setup &cargo-colors=$cargo-colors &check-toolchain-file=$check-toolchain-file diff --git a/actions/tag-and-release/README.md b/actions/tag-and-release/README.md index c1f35787d..4a6bc8939 100644 --- a/actions/tag-and-release/README.md +++ b/actions/tag-and-release/README.md @@ -2,11 +2,11 @@ Merges a pull request, creates a **Git** tag and publishes a **GitHub** release, from a Git branch named according to [semantic versioning](https://semver.org/). -## 🃏Example +## 🃏 Example ```yaml steps: - - uses: giancosta86/aurora-github/actions/tag-and-release@v10 + - uses: giancosta86/aurora-github/actions/tag-and-release@v11 ``` It is essential to remember that this action must be called: @@ -24,7 +24,21 @@ The only exception is when `dry-run` is set to **true**. More generally, this action should be _the very last step_ in a manually-triggered workflow performing _artifact publication_ - so that the pull request gets closed and the related resources released once all the other steps are successful. -## ☑️Requirements +## 💡 How it works + +1. If the pull request associated with the current branch is open (as it should), merge it - using the selected `git-strategy` for merging/rebasing the code and deleting the branch + +1. Create a new tag - for example, `vX.Y.Z` - containing the semantic version inferred from the branch name. + +1. Generate the release notes - based on the Git commit list + +1. If `notes-file-processor` is not an empty string, it will be interpreted as the `script-file` input of [run-shell-script](../run-shell-script/README.md) + +1. Create or draft a GitHub release. + +1. Optionally, _create or move_ the tag of the major version related to the current version - for example, `vX`. + +## ☑️ Requirements - Unless the `dry-run` input is set to **true**, this action can only be called: @@ -48,44 +62,28 @@ More generally, this action should be _the very last step_ in a manually-trigger - The requirements discussed for [detect-branch-version](../detect-branch-version/README.md) also apply. -## 💡How it works +## 📥 Inputs -1. If the pull request associated with the current branch is open (as it should), merge it - using the selected `git-strategy` for merging/rebasing the code and deleting the branch +| Name | Type | Description | Default value | +| :--------------------: | :-------------------------: | :-------------------------------------------------------: | :-----------: | +| `git-strategy` | `merge`,`rebase`,`squash` | How to apply the pull request to the Git repository | **squash** | +| `draft-release` | `true`, `false`, `on-major` | Draft the release - do not publish it | **on-major** | +| `notes-file-processor` | **string** | Shell script editing the generated release notes | | +| `set-major-tag` | **boolean** | Create/move the `vX` tag to this commit (X=major version) | **false** | +| `dry-run` | **boolean** | Run the action without performing commands | **false** | -1. Create a new tag - for example, `vX.Y.Z` - containing the semantic version inferred from the branch name. +- The `draft-release` input, when set to **on-major**, will become **true** only if the semantic version detected from the current branch has the form `X.0.0` - otherwise, it will fallback to **false**. -1. Generate the release notes - based on the Git commit list - -1. If `notes-file-processor` is not an empty string, it will be interpreted as the filename - relative to `project-directory` - of a **Bash** script that: - - - must take in input (via `$1`) the path of the temporary file containing the generated release notes - - - can arbitrarily alter the content of such file - and even call other interpreters - - - does not need the `#!` prelude, nor the _executable flag_ - -1. Create or draft a GitHub release. - -1. Optionally, _create or move_ the tag of the major version related to the current version - for example, `vX`. - -## 📥Inputs - -| Name | Type | Description | Default value | -| :--------------------: | :-----------------------: | :-------------------------------------------------------: | :-----------: | -| `git-strategy` | `merge`,`rebase`,`squash` | How to apply the pull request to the Git repository | **rebase** | -| `draft-release` | **boolean** | Draft the release - do not publish it | **false** | -| `notes-file-processor` | **string** | Bash script editing the generated release notes | | -| `set-major-tag` | **boolean** | Create/move the `vX` tag to this commit (X=major version) | **false** | -| `dry-run` | **boolean** | Run the action without performing commands | **false** | - -## 📤Outputs +## 📤 Outputs | Name | Type | Description | Example | | :-----------: | :--------: | :--------------------------------------: | :--------: | | `release-tag` | **string** | The Git tag associated with the release | **v7.4.9** | | `major-tag` | **string** | The Git tag of the major version, if set | **v7** | -## 🌐Further references +## 🌐 Further references + +- [run-shell-script](../run-shell-script/README.md) - [semver](https://semver.org/) diff --git a/actions/tag-and-release/action.yml b/actions/tag-and-release/action.yml index 426621e08..a6f60daf7 100644 --- a/actions/tag-and-release/action.yml +++ b/actions/tag-and-release/action.yml @@ -3,14 +3,14 @@ description: Merges a pull request, creates a Git tag and publishes a GitHub rel inputs: draft-release: - description: Draft the release - do not publish it. - default: false + description: Draft the release - do not publish it. Can be `true`, `false` or `on-major`. + default: on-major notes-file-processor: - description: Bash script editing the generated release notes. + description: Shell script editing the generated release notes. set-major-tag: - description: Create/move the 'vX' tag to this commit (X=major version). + description: Create/move the `vX` tag to this commit (X=major version). default: false dry-run: @@ -19,401 +19,41 @@ inputs: git-strategy: description: How to apply the pull request to the Git repository. Can be `merge`, `rebase` or `squash`. - default: rebase + default: squash outputs: release-tag: description: The Git tag associated with the release. - value: ${{ steps.create-release.outputs.release-tag }} + value: ${{ steps.action-body.outputs.tag }} major-tag: description: The Git tag of the major version, if set. - value: ${{ steps.set-major-tag.outputs.major-tag }} + value: ${{ steps.action-body.outputs.major-tag }} runs: using: composite steps: - - name: Validate inputs - shell: bash - run: | - if [[ -z "${{ inputs.draft-release }}" ]] - then - echo "❌Missing action input: 'draft-release'!" >&2 - exit 1 - fi - - if [[ -z "${{ inputs.set-major-tag }}" ]] - then - echo "❌Missing action input: 'set-major-tag'!" >&2 - exit 1 - fi - - if [[ -z "${{ inputs.dry-run }}" ]] - then - echo "❌Missing action input: 'dry-run'!" >&2 - exit 1 - fi - - case "${{ inputs.git-strategy }}" in - merge | rebase | squash) - ;; - - *) - echo "❌Invalid value for input: 'git-strategy': '${{ inputs.git-strategy }}'!" >&2 - exit 1 - esac - - - name: Display inputs - shell: bash - run: | - echo "📥dry-run: ${{ inputs.dry-run }}" - echo "📥draft-release: ${{ inputs.draft-release }}" - echo "📥set-major-tag: ${{ inputs.set-major-tag }}" - echo "📥notes-file-processor: ${{ inputs.notes-file-processor }}" - echo "📥git-strategy: ${{ inputs.git-strategy }}" - - - name: Detect branch and version - id: detect-branch-version - uses: giancosta86/aurora-github/actions/detect-branch-version@v10.2.0 - - - name: Verify versions - shell: bash - run: | - version="${{ steps.detect-branch-version.outputs.version }}" - - if [[ -n "$version" ]] - then - echo "🔎Detected version: '$version'" - else - echo "❌The current version could not be detected from the Git branch ('$branch')!" >&2 - exit 1 - fi - - setMajorTag="${{ inputs.set-major-tag }}" - - if [[ "$setMajorTag" == "true" ]] - then - major="${{ steps.detect-branch-version.outputs.major }}" - - if [[ -n "$major" ]] - then - echo "🔎Detected major version: '$major'" - else - echo "❌The major version could not be detected!" >&2 - exit 1 - fi - fi - - - name: Detect if a pull request was the trigger - shell: bash - run: | - echo "🧭GITHUB_REF IS: '$GITHUB_REF'" - - if [[ "$GITHUB_REF" =~ ^refs/pull/ ]] - then - inPullRequestWorkflow=true - - if [[ "${{ inputs.dry-run }}" != "true" ]] - then - echo "❌This action can be run from a workflow triggered by a pull-request only when dry-run is enabled" - exit 1 - fi - else - inPullRequestWorkflow=false - fi - - echo "inPullRequestWorkflow=$inPullRequestWorkflow" >> $GITHUB_ENV - - - name: Retrieve pull request information - shell: bash - run: | - branch="${{ steps.detect-branch-version.outputs.branch }}" - - echo "😺Retrieving Git pull request info for branch: '$branch'..." - - pullRequestJson="$(gh pr view $branch --json title,number,baseRefOid,headRefOid --jq '{title: .title, number: .number, baseSha: .baseRefOid, headSha: .headRefOid}')" - - echo "✅Pull request JSON data retrieved!" - - title=$(echo "$pullRequestJson" | jq -r .title) - number=$(echo "$pullRequestJson" | jq -r .number) - baseSha=$(echo "$pullRequestJson" | jq -r .baseSha) - headSha=$(echo "$pullRequestJson" | jq -r .headSha) - - echo "pullRequestTitle=$title" >> $GITHUB_ENV - echo "pullRequestNumber=$number" >> $GITHUB_ENV - echo "pullRequestBaseSha=$baseSha" >> $GITHUB_ENV - echo "pullRequestHeadSha=$headSha" >> $GITHUB_ENV - env: - GH_TOKEN: ${{ github.token }} - - - name: Print pull request information - shell: bash - run: | - echo "🧭In pull request workflow? $inPullRequestWorkflow" - echo "🔁Pull request title: '$pullRequestTitle'" - echo "🔁Pull request number: '$pullRequestNumber'" - echo "🔁Pull request base SHA: '$pullRequestBaseSha'" - echo "🔁Pull request head SHA: '$pullRequestHeadSha'" - - - name: Reset any Git local change - shell: bash - run: | - echo "⏱️Discarding local changes to the Git repository..." - git reset --hard HEAD - echo "✅Git repository successfully reset" - - - name: Fetch Git log - shell: bash - run: | - main() { - if [[ "$inPullRequestWorkflow" == "true" ]] - then - echo "📥Fetching Git log within a pull request workflow..." - fetchLogWithinPullRequestWorkflow - else - echo "📥Fetching Git log not within a pull request workflow..." - fetchLogNotWithinPullRequestWorkflow - fi - - echo "✅Git log ready!" - } - - function fetchLogWithinPullRequestWorkflow() { - git fetch origin "$pullRequestBaseSha" "$pullRequestHeadSha" - } - - function fetchLogNotWithinPullRequestWorkflow() { - fetchGitSha "$pullRequestHeadSha" - - fetchGitSha "$pullRequestBaseSha" - } - - function fetchGitSha() { - local requiredSha="$1" - - local branch="${{ steps.detect-branch-version.outputs.branch }}" - local depthDelta=25 - - echo "🧭Ensuring Git SHA '$requiredSha' is available..." - - while ! git cat-file commit "$requiredSha" > /dev/null 2>&1 - do - echo "📥Fetching $depthDelta more commits..." - git fetch --deepen="$depthDelta" origin "$branch" - depthDelta=$((depthDelta * 2)) - done - - echo "✅Git SHA '$requiredSha' ready!" - } - - main - - - name: Fetch Git tags - shell: bash - run: | - echo "📥Retrieving Git tags..." - gitErrorLog="$(mktemp)" - if git fetch --tags > /dev/null 2> "$gitErrorLog" - then - echo "✅Git tags retrieved!" - else - echo "❌Cannot retrieve the Git tags, because of these errors:" >&2 - cat "$gitErrorLog" >&2 - echo "❌❌❌" >&2 - exit 1 - fi + - uses: giancosta86/aurora-github/actions/setup-elvish-context@v11.0.0 - - name: Merge the pull request - shell: bash + - id: action-body + shell: elvish {0} run: | - branch="${{ steps.detect-branch-version.outputs.branch }}" + use aurora-github/ci-cd/input + use aurora-github/ci-cd/output + use aurora-github/tag-and-release - echo "🔀Now merging the PR for branch '$branch', via the '${{ inputs.git-strategy }}' Git strategy..." + var inputs = [ + &draft-release=(input:enum draft-release '${{ inputs.draft-release }}' [true false on-major]) - if [[ "${{ inputs.dry-run }}" != "true" ]] - then - gitStrategyArg="--${{ inputs.git-strategy }}" - gh pr merge "$branch" $gitStrategyArg --delete-branch - else - echo "💭Just simulating pull request merging, in dry-run mode..." - fi - env: - GH_TOKEN: ${{ github.token }} - - - name: Create the Git tag - id: create-git-tag - shell: bash - run: | - version="${{ steps.detect-branch-version.outputs.version }}" - - tag="v${version}" - echo "📌Creating and pushing Git tag '$tag'..." - - if [[ "${{ inputs.dry-run }}" != "true" ]] - then - git tag "$tag" - git push origin "$tag" - echo "📌Tag created and pushed!" - else - echo "💭Just simulating Git tag creation, in dry-run mode..." - fi - - echo "tag=$tag" >> $GITHUB_OUTPUT - - - name: Publish or draft release - id: create-release - shell: bash - run: | - tag="${{ steps.create-git-tag.outputs.tag }}" - echo "📌Release tag: '$tag'..." - - baseSha="$pullRequestBaseSha" - echo "🏰Base SHA: '$baseSha'" - - headSha="$pullRequestHeadSha" - echo "👤Head SHA: '$headSha'" - - function createRelease() { - local repoBasename="$(basename "$GITHUB_REPOSITORY")" - echo "🧭Repository basename: '$repoBasename'" - - local version="${{ steps.detect-branch-version.outputs.version }}" - echo "🔎Version: '$version'" - - local releaseTitle="$repoBasename $version" - echo "🔎Release title: '$releaseTitle'" - - local draftOnly="${{ inputs.draft-release }}" - echo "🔎Draft only? $draftOnly" - - local releaseNotesFile="$(mktemp)" - generateReleaseNotes "$releaseNotesFile" - - local notesFileProcessor=${{ inputs.notes-file-processor }} - if [[ -n "$notesFileProcessor" ]] - then - echo "🖋Release notes file processor found: '$notesFileProcessor'" - - bash "$notesFileProcessor" "$releaseNotesFile" - - echo "🎀Processed release notes:" - cat "$releaseNotesFile" - echo "🎀🎀🎀" - else - echo "💭No release notes file processor..." - fi - - if [[ "$draftOnly" == "true" ]] - then - echo "📝Drafting release '$releaseTitle'..." - - if [[ "${{ inputs.dry-run }}" != "true" ]] - then - gh release create "$tag" --title "$releaseTitle" --latest --notes-file "$releaseNotesFile" --draft - - echo "📝Release drafted!" - else - echo "💭Just simulating draft release creation, in dry-run mode..." - fi - else - echo "🌟Publishing release '$releaseTitle'..." - - if [[ "${{ inputs.dry-run }}" != "true" ]] - then - gh release create "$tag" --title "$releaseTitle" --latest --notes-file "$releaseNotesFile" - - echo "🌟Release published!" - else - echo "💭Just simulating release creation, in dry-run mode..." - fi - fi - } + ¬es-file-processor=(input:string &optional notes-file-processor '${{ inputs.notes-file-processor }}') - function generateReleaseNotes() { - local outputFile="$1" + &set-major-tag=(input:bool set-major-tag '${{ inputs.set-major-tag }}') - writeCommitList "$outputFile" + &dry-run=(input:bool dry-run '${{ inputs.dry-run }}') - echo "---" >> "$outputFile" + &git-strategy=(input:enum git-strategy '${{ inputs.git-strategy }}' [merge rebase squash]) + ] - writePullRequestData "$outputFile" - - echo >> "$outputFile" - - writeChangeLog "$outputFile" - - echo "📝Release notes generated!" - cat "$outputFile" - echo "📝📝📝" - } - - function writeCommitList() { - local outputFile="$1" - - printGitLogsAsMarkdown "§+-+§" >> "$outputFile" - } - - function printGitLogsAsMarkdown() { - local marker="$1" - - git log --no-merges --reverse --pretty=format:"$marker* %B" "$baseSha".."$headSha" | sed " - s/^/ / - s/^ $marker// - " - } - - function writePullRequestData() { - local outputFile="$1" - - echo -e "**Pull request**: $pullRequestTitle (#$pullRequestNumber):" >> "$outputFile" - } - - function writeChangeLog() { - local outputFile="$1" - - local mostSpecificBaseTag="$(git tag --points-at "$baseSha" | awk '{ print length, $0 }' | sort -nr | cut -d' ' -f2- | head -n 1)" - - if [[ -n "$mostSpecificBaseTag" ]] - then - echo "📌Tag '$mostSpecificBaseTag' found for the '$baseSha' base SHA" - local baseReference="$mostSpecificBaseTag" - else - echo "💭No tags associated with the '$baseSha' base SHA - using it directly" - local baseReference="$baseSha" - fi - - echo "🧭Base reference: '$baseReference'" - echo "📌Release tag: '$tag'" - - echo "**Full changelog**: https://github.com/$GITHUB_REPOSITORY/compare/$baseReference..$tag" >> "$outputFile" - } - - createRelease - - echo "release-tag=$tag" >> $GITHUB_OUTPUT + output:map (tag-and-release:run-action $inputs | only-values) env: GH_TOKEN: ${{ github.token }} - - - name: Create or move major version tag - if: inputs.set-major-tag == 'true' - id: set-major-tag - shell: bash - run: | - major="${{ steps.detect-branch-version.outputs.major }}" - - majorTag="v${major}" - - echo "🪩Setting major version tag '$majorTag'..." - - if [[ "${{ inputs.dry-run }}" != "true" ]] - then - git tag -f "$majorTag" - git push origin "$majorTag" --force - - echo "🪩Major version tag set!" - else - echo "💭Just simulating major version tag creation, in dry-run mode..." - fi - - echo "major-tag=$majorTag" >> $GITHUB_OUTPUT diff --git a/actions/upload-release-assets/README.md b/actions/upload-release-assets/README.md index 25f926748..ccf90f844 100644 --- a/actions/upload-release-assets/README.md +++ b/actions/upload-release-assets/README.md @@ -2,37 +2,37 @@ Uploads one or more asset files to a **GitHub** release. -## 🃏Example +## 🃏 Example ```yaml steps: - - uses: giancosta86/aurora-github/actions/upload-release-assets@v10 + - uses: giancosta86/aurora-github/actions/upload-release-assets@v11 with: release-tag: v3.0.2 files: logo.png data.zip source-directory: dist ``` -## 💡How it works +## 💡 How it works This action calls the [gh release upload](https://cli.github.com/manual/gh_release_upload) command to upload the given files. -## ☑️Requirements +## ☑️ Requirements - The `release-tag` input must be the tag of an existing release - which could be, for example, the `release-tag` output of the [tag-and-release](../tag-and-release/README.md) action. -- The `files` input must be passed just like a string of relative file paths on the Bash command line. +- The `files` input must be comma-separated -## 📥Inputs +## 📥 Inputs -| Name | Type | Description | Default value | -| :----------------: | :---------: | :---------------------------------------------: | :-----------: | -| `release-tag` | **string** | The tag of the target release | | -| `files` | **string** | The relative paths of the asset files to upload | | -| `overwrite` | **boolean** | Overwrite existing assets in the release | **true** | -| `source-directory` | **string** | Directory containing the files | **.** | +| Name | Type | Description | Default value | +| :----------------: | :-------------------------: | :-----------------------------------------: | :-----------: | +| `release-tag` | **string** | The tag of the target release | | +| `files` | **string**, comma-separated | Relative paths of the asset files to upload | | +| `overwrite` | **boolean** | Overwrite existing assets in the release | **true** | +| `source-directory` | **string** | Directory containing the files | **.** | -## 🌐Further references +## 🌐 Further references - [tag-and-release](../tag-and-release/README.md) diff --git a/actions/upload-release-assets/action.yml b/actions/upload-release-assets/action.yml index 836201d4e..c78f26508 100644 --- a/actions/upload-release-assets/action.yml +++ b/actions/upload-release-assets/action.yml @@ -6,7 +6,7 @@ inputs: description: The tag of the target release. files: - description: The relative paths of the asset files to upload. + description: Comma-separated relative paths of the asset files to upload. overwrite: description: Overwrite existing assets in the release. @@ -19,45 +19,20 @@ inputs: runs: using: composite steps: - - shell: bash + - uses: giancosta86/aurora-github/actions/setup-elvish-context@v11.0.0 + + - shell: elvish {0} working-directory: ${{ inputs.source-directory }} run: | - main() { - validateInputs - publishReleaseAssets - } - - validateInputs() { - if [[ -z "${{ inputs.release-tag }}" ]] - then - echo "❌Missing action input: 'release-tag'!" >&2 - exit 1 - fi - - if [[ -z "${{ inputs.files }}" ]] - then - echo "❌Missing action input: 'files'!" >&2 - exit 1 - fi - - if [[ -z "${{ inputs.overwrite }}" ]] - then - echo "❌Missing action input: 'overwrite'!" >&2 - exit 1 - fi - } - - publishReleaseAssets() { - if [[ "${{ inputs.overwrite }}" == "true" ]] - then - local clobberArg="--clobber" - else - local clobberArg="" - fi - - gh release upload $clobberArg "${{ inputs.release-tag }}" ${{ inputs.files }} - } - - main + use aurora-github/ci-cd/input + use aurora-github/ci-cd/release-assets + + release-assets:publish [ + &release-tag=(input:string release-tag '${{ inputs.release-tag }}') + + &files=(input:list '${{ inputs.files }}') + + &overwrite=(input:bool overwrite '${{ inputs.overwrite }}') + ] env: GH_TOKEN: ${{ github.token }} diff --git a/actions/verify-elvish-package/README.md b/actions/verify-elvish-package/README.md new file mode 100644 index 000000000..ef9733217 --- /dev/null +++ b/actions/verify-elvish-package/README.md @@ -0,0 +1,42 @@ +# verify-elvish-package + +Verifies the source files of an **Elvish** library. + +## 🃏 Example + +```yaml +steps: + - uses: giancosta86/aurora-github/actions/verify-elvish-package@v11 +``` + +## 💡 How it works + +1. Run [check-project-license](../check-project-license/README.md) to verify the **LICENSE** file. + +1. Ensure that the library _metadata_ are declared. + +1. Execute [run-custom-tests](../run-custom-tests/README.md). + +1. Find [critical TODOs](../find-critical-todos/README.md) in the source code - which crash the workflow by default. + +## ☑️ Requirements + +- `metadata.xml` must be present in `project-directory` - as described in [epm:metadata](https://elv.sh/ref/epm.html#epm:metadata) + +## 📥 Inputs + +| Name | Type | Description | Default value | +| :-----------------------: | :---------: | :--------------------------------------------: | :-----------------------: | +| `crash-on-critical-todos` | **boolean** | Crash the workflow if critical TODOs are found | **true** | +| `source-file-regex` | **string** | PCRE pattern describing the source files | view [source](action.yml) | +| `project-directory` | **string** | The directory containing `Cargo.toml` | **.** | + +## 🌐 Further references + +- [check-project-license](../check-project-license/README.md) + +- [run-custom-tests](../run-custom-tests/README.md) + +- [find-critical-todos](../find-critical-todos/README.md) + +- [aurora-github](../../README.md) diff --git a/actions/verify-elvish-package/action.yml b/actions/verify-elvish-package/action.yml new file mode 100644 index 000000000..4ac0b1282 --- /dev/null +++ b/actions/verify-elvish-package/action.yml @@ -0,0 +1,50 @@ +name: Verify Elvish library +description: Verifies the source files of an Elvish library. + +inputs: + crash-on-critical-todos: + description: Crash the workflow if critical TODOs are found. + default: true + + source-file-regex: + description: PCRE pattern describing the source files. + default: '\.elv$' + + project-directory: + description: The directory containing `metadata.json`. + default: . + +runs: + using: composite + steps: + - uses: giancosta86/aurora-github/actions/setup-elvish-context@v11.0.0 + + - name: Check the project license + uses: giancosta86/aurora-github/actions/check-project-license@v11.0.0 + + - name: Check the metadata + shell: elvish {0} + working-directory: ${{ inputs.project-directory }} + run: | + use aurora-github/elvish-library + + elvish-library:check-metadata + + - uses: giancosta86/aurora-github/actions/run-custom-tests@v11.0.0 + with: + root-directory: ${{ inputs.project-directory }} + + - name: Check for critical TODOs + uses: giancosta86/aurora-github/actions/find-critical-todos@v11.0.0 + with: + source-file-regex: ${{ inputs.source-file-regex }} + crash-on-found: ${{ inputs.crash-on-critical-todos }} + display-lines: true + root-directory: ${{ inputs.project-directory }} + + - name: Print confirmation message + shell: elvish {0} + run: | + use github.com/giancosta86/aurora-elvish/console + + console:echo ✅🔮 Elvish library verified! diff --git a/actions/verify-jvm-project/README.md b/actions/verify-jvm-project/README.md index 99d73d3d4..eaefc3db5 100644 --- a/actions/verify-jvm-project/README.md +++ b/actions/verify-jvm-project/README.md @@ -2,16 +2,14 @@ Verifies the source files of a project for the **Java Virtual Machine** - using **Maven** or **Gradle**. -## 🃏Example +## 🃏 Example ```yaml steps: - - uses: actions/checkout@v4 - - - uses: giancosta86/aurora-github/actions/verify-jvm-project@v10 + - uses: giancosta86/aurora-github/actions/verify-jvm-project@v11 ``` -## 💡How it works +## 💡 How it works 1. Run [check-project-license](../check-project-license/README.md) to verify the **LICENSE** file. @@ -37,11 +35,11 @@ steps: 1. Find [critical TODOs](../find-critical-todos/README.md) in the source code - which crash the workflow by default. -## ☑️Requirements +## ☑️ Requirements - The `mvn` or `gradle` command must be available, depending on the descriptor within the project directory - which also implies that a suitable **Java** environment is installed; by passing `java-version` and `tool-version`, you can enforce specific required versions instead of the default ones provided by the selected GitHub Actions runner. -## 📥Inputs +## 📥 Inputs | Name | Type | Description | Default value | | :-----------------------: | :---------------------: | :---------------------------------------------: | :-----------------------: | @@ -53,7 +51,7 @@ steps: | `enforce-branch-version` | `inject`,`check`,`skip` | How the branch version should be enforced | **inject** | | `project-directory` | **string** | The directory containing the project descriptor | **.** | -## 🌐Further references +## 🌐 Further references - [check-project-license](../check-project-license/README.md) diff --git a/actions/verify-jvm-project/action.yml b/actions/verify-jvm-project/action.yml index 1d9c41470..9d343fab6 100644 --- a/actions/verify-jvm-project/action.yml +++ b/actions/verify-jvm-project/action.yml @@ -18,7 +18,7 @@ inputs: source-file-regex: description: PCRE pattern describing the source files. - default: '^\.\/src\/.+\.(java|kt|scala|groovy)$' + default: '^src\/.+\.(java|kt|scala|groovy)$' enforce-branch-version: description: How the branch version should be enforced. @@ -31,119 +31,43 @@ inputs: runs: using: composite steps: - - name: Validate inputs - shell: bash - working-directory: ${{ inputs.project-directory }} - run: | - if [[ -z "${{ inputs.quiet-tool }}" ]] - then - echo "❌Missing action input: 'quiet-tool'!" >&2 - exit 1 - fi - - if [[ -z "${{ inputs.crash-on-critical-todos }}" ]] - then - echo "❌Missing action input: 'crash-on-critical-todos'!" >&2 - exit 1 - fi - - if [[ -z "${{ inputs.source-file-regex }}" ]] - then - echo "❌Missing action input: 'source-file-regex'!" >&2 - exit 1 - fi - - if [[ -z "${{ inputs.enforce-branch-version }}" ]] - then - echo "❌Missing action input: 'enforce-branch-version'!" >&2 - exit 1 - fi + - uses: giancosta86/aurora-github/actions/setup-elvish-context@v11.0.0 - name: Check the project license - uses: giancosta86/aurora-github/actions/check-project-license@v10.2.0 - - - name: Setup Python context - shell: bash - run: | - pythonPath="${{ github.action_path }}/../../core/python" - echo "PYTHONPATH=$pythonPath" >> $GITHUB_ENV - - echo "INPUT_PROJECT_DIRECTORY=${{ inputs.project-directory }}" >> $GITHUB_ENV - - - name: Detect the build tool - shell: python - run: | - from core.jvm import get_jvm_build_tool, Inputs - - inputs = Inputs.from_env() - - get_jvm_build_tool(inputs).write_to_github_env() + uses: giancosta86/aurora-github/actions/check-project-license@v11.0.0 - name: Enforce branch version - uses: giancosta86/aurora-github/actions/enforce-branch-version@v10.2.0 + uses: giancosta86/aurora-github/actions/enforce-branch-version@v11.0.0 with: mode: ${{ inputs.enforce-branch-version }} project-directory: ${{ inputs.project-directory }} - - name: Install Java - if: inputs.java-version != '' - uses: giancosta86/aurora-github/actions/install-via-sdkman@v10.2.0 - with: - candidate: java - version: ${{ inputs.java-version }} - - - name: Install Maven - if: env.buildTool == 'mvn' && inputs.tool-version != '' - uses: giancosta86/aurora-github/actions/install-via-sdkman@v10.2.0 - with: - candidate: maven - version: ${{ inputs.tool-version }} - - - name: Install Gradle - if: env.buildTool == 'gradle' && inputs.tool-version != '' - uses: giancosta86/aurora-github/actions/install-via-sdkman@v10.2.0 - with: - candidate: gradle - version: ${{ inputs.tool-version }} - - - name: Run Maven - if: env.buildTool == 'mvn' - shell: bash + - name: Setup JVM context + shell: elvish {0} working-directory: ${{ inputs.project-directory }} run: | - if [[ "${{ inputs.quiet-tool }}" == "true" ]] - then - quietToolArg="-q" - else - quietToolArg="" - fi + use aurora-github/ci-cd/input + use aurora-github/ci-cd/env + use aurora-github/jvm/context - echo "🪶Running Maven to verify the project..." + env:map (context:setup ^ + &java-version=(input:string &optional java-version '${{ inputs.java-version }}') ^ + &tool-version=(input:string &optional tool-version '${{ inputs.tool-version }}') ^ + ) - mvn -B $quietToolArg verify - - echo "✅Verification successful!" - - - name: Run Gradle - if: env.buildTool == 'gradle' - shell: bash + - name: Verify project + shell: elvish {0} working-directory: ${{ inputs.project-directory }} run: | - if [[ "${{ inputs.quiet-tool }}" == "true" ]] - then - quietToolArg="-q" - else - quietToolArg="" - fi - - echo "🐘Running Gradle to verify the project..." + use aurora-github/ci-cd/input + use aurora-github/jvm/project/verification - gradle --no-daemon --no-scan $quietToolArg build + var quiet-tool = (input:bool quiet-tool '${{ inputs.quiet-tool }}') - echo "✅Verification successful!" + verification:verify &quiet-tool=$quiet-tool (get-env buildTool) - name: Check for critical TODOs - uses: giancosta86/aurora-github/actions/find-critical-todos@v10.2.0 + uses: giancosta86/aurora-github/actions/find-critical-todos@v11.0.0 with: source-file-regex: ${{ inputs.source-file-regex }} crash-on-found: ${{ inputs.crash-on-critical-todos }} @@ -151,5 +75,8 @@ runs: root-directory: ${{ inputs.project-directory }} - name: Print confirmation message - shell: bash - run: echo "✅JVM project verified!" + shell: elvish {0} + run: | + use github.com/giancosta86/aurora-elvish/console + + console:echo ✅☕ JVM project verified! diff --git a/actions/verify-npm-package/README.md b/actions/verify-npm-package/README.md index a86c7992e..f7c1d6946 100644 --- a/actions/verify-npm-package/README.md +++ b/actions/verify-npm-package/README.md @@ -4,13 +4,11 @@ Verifies the source files of a **NodeJS** package - by running its `verify` scri It is worth noting this action can support any technology - as long as you comply with the requirements described below. -## 🃏Example +## 🃏 Example ```yaml steps: - - uses: actions/checkout@v4 - - - uses: giancosta86/aurora-github/actions/verify-npm-package@v10 + - uses: giancosta86/aurora-github/actions/verify-npm-package@v11 ``` **IMPORTANT**: please, remember to declare your verification process in the `verify` script within `package.json`! For example: @@ -23,7 +21,7 @@ steps: } ``` -## 💡How it works +## 💡 How it works 1. Run [check-project-license](../check-project-license/README.md) to verify the **LICENSE** file. @@ -39,19 +37,19 @@ steps: 1. If a **tests** directory exists within `project-directory`, execute [run-custom-tests](../run-custom-tests/README.md) on it, with the `optional` flag enabled. - 💡The rationale for this step is a parallelism with Rust's **tests** directory - dedicated to verify the crate under test from a _client_ perspective; however, in `verify-npm-package` you have even more fine-grained control over the test process: for example, you can automatically launch _a Bash script_ to test the system, while still relying on the **tests** directory to host utility modules imported by different tests in the **src** directory tree. + 💡The rationale for this step is a parallelism with Rust's **tests** directory - dedicated to verify the crate under test from a _client_ perspective; however, in `verify-npm-package` you have even more fine-grained control over the test process: for example, you can automatically launch _a shell script_ to test the system, while still relying on the **tests** directory to host utility modules imported by different tests in the **src** directory tree. - **Please, note**: should you need to execute a shell script for testing, a `verify.sh` script, run by Bash, is required; for further details, please refer to [run-custom-tests](../run-custom-tests/README.md). + **Please, note**: should you need to execute a shell script for testing, a `verify.elv` / `verify.sh` script, run by Elvish or Bash, is required; for further details, please refer to [run-custom-tests](../run-custom-tests/README.md). 1. Find [critical TODOs](../find-critical-todos/README.md) in the source code - which crash the workflow by default. -## ☑️Requirements +## ☑️ Requirements - The entire verification process for the package must be triggered by the `verify` script in `package.json` (see the example). - The requirements for [setup-nodejs-context](../setup-nodejs-context/README.md). -## 📥Inputs +## 📥 Inputs | Name | Type | Description | Default value | | :-----------------------: | :---------------------: | :-----------------------------------------------------: | :-----------------------: | @@ -61,7 +59,7 @@ steps: | `check-subpath-exports` | **boolean** | Run `check-subpath-exports` after the **verify** script | **true** | | `project-directory` | **string** | The directory containing `package.json` | **.** | -## 🌐Further references +## 🌐 Further references - [check-project-license](../check-project-license/README.md) diff --git a/actions/verify-npm-package/action.yml b/actions/verify-npm-package/action.yml index 5fb56afdd..c58563450 100644 --- a/actions/verify-npm-package/action.yml +++ b/actions/verify-npm-package/action.yml @@ -1,5 +1,5 @@ name: Verify npm package -description: Verifies the source files of a NodeJS package - by running its 'verify' script within the 'scripts' section of 'package.json'. +description: Verifies the source files of a NodeJS package - by running its `verify` script within the `scripts` section of `package.json`. inputs: crash-on-critical-todos: @@ -8,101 +8,70 @@ inputs: source-file-regex: description: PCRE pattern describing the source files. - default: '^\.\/(src|(tests(?!\/node_modules\/)))\/.+\.(c|m)?(j|t)sx?$' + default: '^(src|(tests(?!\/node_modules\/)))\/.+\.(c|m)?(j|t)sx?$' enforce-branch-version: description: How the branch version should be enforced. default: inject check-subpath-exports: - description: Run check-subpath-exports after the "verify" package script. + description: Run check-subpath-exports after the `verify` package script. default: true project-directory: - description: The directory containing package.json. + description: The directory containing `package.json`. default: . runs: using: composite steps: - - name: Validate inputs - shell: bash - working-directory: ${{ inputs.project-directory }} - run: | - if [[ -z "${{ inputs.crash-on-critical-todos }}" ]] - then - echo "❌Missing action input: 'crash-on-critical-todos'!" >&2 - exit 1 - fi - - if [[ -z "${{ inputs.source-file-regex }}" ]] - then - echo "❌Missing action input: 'source-file-regex'!" >&2 - exit 1 - fi - - if [[ -z "${{ inputs.enforce-branch-version }}" ]] - then - echo "❌Missing action input: 'enforce-branch-version'!" >&2 - exit 1 - fi - - if [[ -z "${{ inputs.check-subpath-exports }}" ]] - then - echo "❌Missing action input: 'check-subpath-exports'!" >&2 - exit 1 - fi - - if [[ ! -f "package.json" ]] - then - echo "❌The package.json descriptor file does not exist!!" >&2 - exit 1 - fi + - uses: giancosta86/aurora-github/actions/setup-elvish-context@v11.0.0 - name: Check the project license - uses: giancosta86/aurora-github/actions/check-project-license@v10.2.0 + uses: giancosta86/aurora-github/actions/check-project-license@v11.0.0 - name: Enforce branch version - uses: giancosta86/aurora-github/actions/enforce-branch-version@v10.2.0 + uses: giancosta86/aurora-github/actions/enforce-branch-version@v11.0.0 with: mode: ${{ inputs.enforce-branch-version }} project-directory: ${{ inputs.project-directory }} - name: Setup NodeJS context - uses: giancosta86/aurora-github/actions/setup-nodejs-context@v10.2.0 + uses: giancosta86/aurora-github/actions/setup-nodejs-context@v11.0.0 with: project-directory: ${{ inputs.project-directory }} - name: Run the 'verify' script from package.json - shell: bash + shell: elvish {0} working-directory: ${{ inputs.project-directory }} run: | - echo "🔎Now running the 'verify' package.json script..." - pnpm verify - echo "✅'verify' script successful!" + use github.com/giancosta86/aurora-elvish/console + use aurora-github/nodejs/project + + project:verify - name: Try to build the package artifacts - shell: bash + shell: elvish {0} working-directory: ${{ inputs.project-directory }} run: | - source "${{ github.action_path }}/../../core/bash/npmPackage.sh" + use aurora-github/nodejs/pnpm - tryToRunNpmBuildScript + pnpm:run-optional-script build - name: Check subpath exports if: inputs.check-subpath-exports == 'true' - uses: giancosta86/aurora-github/actions/check-subpath-exports@v10.2.0 + uses: giancosta86/aurora-github/actions/check-subpath-exports@v11.0.0 with: project-directory: ${{ inputs.project-directory }} - name: Run optional custom tests from the 'tests' directory - uses: giancosta86/aurora-github/actions/run-custom-tests@v10.2.0 + uses: giancosta86/aurora-github/actions/run-custom-tests@v11.0.0 with: optional: true root-directory: ${{ inputs.project-directory }}/tests - name: Check for critical TODOs - uses: giancosta86/aurora-github/actions/find-critical-todos@v10.2.0 + uses: giancosta86/aurora-github/actions/find-critical-todos@v11.0.0 with: source-file-regex: ${{ inputs.source-file-regex }} crash-on-found: ${{ inputs.crash-on-critical-todos }} @@ -110,5 +79,8 @@ runs: root-directory: ${{ inputs.project-directory }} - name: Print confirmation message - shell: bash - run: echo "✅npm package project verified!" + shell: elvish {0} + run: | + use github.com/giancosta86/aurora-elvish/console + + console:echo ✅☕ npm package project verified! diff --git a/actions/verify-python-package/README.md b/actions/verify-python-package/README.md index 4f19a97df..ae09b2cb6 100644 --- a/actions/verify-python-package/README.md +++ b/actions/verify-python-package/README.md @@ -2,16 +2,14 @@ Verifies the source files of a **Python** package using [PDM](https://pdm-project.org). -## 🃏Example +## 🃏 Example ```yaml steps: - - uses: actions/checkout@v4 - - - uses: giancosta86/aurora-github/actions/verify-python-package@v10 + - uses: giancosta86/aurora-github/actions/verify-python-package@v11 ``` -## 💡How it works +## 💡 How it works 1. Run [check-project-license](../check-project-license/README.md) to verify the **LICENSE** file. @@ -25,13 +23,13 @@ steps: 1. Find [critical TODOs](../find-critical-todos/README.md) in the source code - which crash the workflow by default. -## ☑️Requirements +## ☑️ Requirements - `pipx` is mandatory when PDM has to be installed. - the **verify** script must be declared within **pyproject.toml**. -## 📥Inputs +## 📥 Inputs | Name | Type | Description | Default value | | :-----------------------: | :---------------------: | :--------------------------------------------: | :-----------------------: | @@ -41,7 +39,7 @@ steps: | `enforce-branch-version` | `inject`,`check`,`skip` | How the branch version should be enforced | **inject** | | `project-directory` | **string** | The directory containing **pyproject.toml** | **.** | -## 🌐Further references +## 🌐 Further references - [check-project-license](../check-project-license/README.md) diff --git a/actions/verify-python-package/action.yml b/actions/verify-python-package/action.yml index 1180b624b..fb979167c 100644 --- a/actions/verify-python-package/action.yml +++ b/actions/verify-python-package/action.yml @@ -11,76 +11,59 @@ inputs: source-file-regex: description: PCRE pattern describing the source files. - default: '^\.\/(src|tests)\/.+\.pyw?$' + default: '^(src|tests)\/.+\.pyw?$' enforce-branch-version: description: How the branch version should be enforced. default: inject project-directory: - description: The directory containing pyproject.toml. + description: The directory containing `pyproject.toml`. default: . runs: using: composite steps: - - name: Validate inputs - shell: bash - working-directory: ${{ inputs.project-directory }} - run: | - if [[ -z "${{ inputs.crash-on-critical-todos }}" ]] - then - echo "❌Missing action input: 'crash-on-critical-todos'!" >&2 - exit 1 - fi - - if [[ -z "${{ inputs.source-file-regex }}" ]] - then - echo "❌Missing action input: 'source-file-regex'!" >&2 - exit 1 - fi - - if [[ -z "${{ inputs.enforce-branch-version }}" ]] - then - echo "❌Missing action input: 'enforce-branch-version'!" >&2 - exit 1 - fi + - uses: giancosta86/aurora-github/actions/setup-elvish-context@v11.0.0 - name: Check the project license - uses: giancosta86/aurora-github/actions/check-project-license@v10.2.0 + uses: giancosta86/aurora-github/actions/check-project-license@v11.0.0 - name: Enforce branch version - uses: giancosta86/aurora-github/actions/enforce-branch-version@v10.2.0 + uses: giancosta86/aurora-github/actions/enforce-branch-version@v11.0.0 with: mode: ${{ inputs.enforce-branch-version }} project-directory: ${{ inputs.project-directory }} - - name: Ensure pdm - shell: bash + - name: Setup Python context + shell: elvish {0} working-directory: ${{ inputs.project-directory }} run: | - source "${{ github.action_path }}/../../core/bash/pdm.sh" + use aurora-github/ci-cd/input + use aurora-github/python/context - ensurePdm + var pdm-version = (input:string &optional pdm-version '${{ inputs.pdm-version }}') + + context:setup &pdm-version=$pdm-version - name: Verify the project - shell: bash + shell: elvish {0} working-directory: ${{ inputs.project-directory }} run: | - echo "🔬Verifying the project..." - pdm run verify - echo "✅Project verified!" + use aurora-github/python/project + + project:verify - name: Build the project - shell: bash + shell: elvish {0} working-directory: ${{ inputs.project-directory }} run: | - echo "📦Building the project..." - pdm build - echo "✅Project built successfully!" + use aurora-github/python/project + + project:build - name: Check for critical TODOs - uses: giancosta86/aurora-github/actions/find-critical-todos@v10.2.0 + uses: giancosta86/aurora-github/actions/find-critical-todos@v11.0.0 with: source-file-regex: ${{ inputs.source-file-regex }} crash-on-found: ${{ inputs.crash-on-critical-todos }} @@ -88,5 +71,8 @@ runs: root-directory: ${{ inputs.project-directory }} - name: Print confirmation message - shell: bash - run: echo "✅Python project verified!" + shell: elvish {0} + run: | + use github.com/giancosta86/aurora-elvish/console + + console:echo ✅🐍 Python project verified! diff --git a/actions/verify-rust-crate/README.md b/actions/verify-rust-crate/README.md index ad18ac140..81644d5cd 100644 --- a/actions/verify-rust-crate/README.md +++ b/actions/verify-rust-crate/README.md @@ -2,18 +2,16 @@ Verifies the source files of a **Rust** crate. -## 🃏Example +## 🃏 Example ```yaml steps: - - uses: actions/checkout@v4 - - - uses: giancosta86/aurora-github/actions/verify-rust-crate@v10 + - uses: giancosta86/aurora-github/actions/verify-rust-crate@v11 ``` **Please, note**: this action is automatically run by [verify-rust-wasm](../verify-rust-wasm/README.md). -## 💡How it works +## 💡 How it works 1. Run [check-project-license](../check-project-license/README.md) to verify the **LICENSE** file. @@ -35,11 +33,11 @@ steps: 1. Find [critical TODOs](../find-critical-todos/README.md) in the source code - which crash the workflow by default. -## ☑️Requirements +## ☑️ Requirements -- `rust-toolchain.toml` must be present in `project-directory` - as described in [check-rust-versions](../check-rust-versions/README.md) +- `rust-toolchain.toml` must be present in `project-directory` - as described in [setup-rust-context](../setup-rust-context/README.md) -## 📥Inputs +## 📥 Inputs | Name | Type | Description | Default value | | :-----------------------: | :---------------------: | :-----------------------------------------------: | :-----------------------: | @@ -50,7 +48,7 @@ steps: | `enforce-branch-version` | `inject`,`check`,`skip` | How the branch version should be enforced | **inject** | | `project-directory` | **string** | The directory containing `Cargo.toml` | **.** | -## 🌐Further references +## 🌐 Further references - [check-project-license](../check-project-license/README.md) @@ -62,6 +60,6 @@ steps: - [enforce-branch-version](../enforce-branch-version/README.md) -- [check-rust-versions](../check-rust-versions/README.md) +- [setup-rust-context](../setup-rust-context/README.md) - [aurora-github](../../README.md) diff --git a/actions/verify-rust-crate/action.yml b/actions/verify-rust-crate/action.yml index ca59323ed..96a5b691d 100644 --- a/actions/verify-rust-crate/action.yml +++ b/actions/verify-rust-crate/action.yml @@ -16,137 +16,64 @@ inputs: source-file-regex: description: PCRE pattern describing the source files. - default: '^\.\/(src|tests)\/.+\.rs$' + default: '^(src|tests)\/.+\.rs$' enforce-branch-version: description: How the branch version should be enforced. default: inject project-directory: - description: The directory containing Cargo.toml. + description: The directory containing `Cargo.toml`. default: . runs: using: composite steps: - - name: Validate inputs - shell: bash - working-directory: ${{ inputs.project-directory }} - run: | - if [[ -z "${{ inputs.run-clippy-checks }}" ]] - then - echo "❌Missing action input: 'run-clippy-checks'!" >&2 - exit 1 - fi - - if [[ -z "${{ inputs.check-rustdoc }}" ]] - then - echo "❌Missing action input: 'check-rustdoc'!" >&2 - exit 1 - fi - - if [[ -z "${{ inputs.crash-on-critical-todos }}" ]] - then - echo "❌Missing action input: 'crash-on-critical-todos'!" >&2 - exit 1 - fi - - if [[ -z "${{ inputs.source-file-regex }}" ]] - then - echo "❌Missing action input: 'source-file-regex'!" >&2 - exit 1 - fi - - if [[ -z "${{ inputs.enforce-branch-version }}" ]] - then - echo "❌Missing action input: 'enforce-branch-version'!" >&2 - exit 1 - fi + - uses: giancosta86/aurora-github/actions/setup-elvish-context@v11.0.0 - name: Check the project license - uses: giancosta86/aurora-github/actions/check-project-license@v10.2.0 + uses: giancosta86/aurora-github/actions/check-project-license@v11.0.0 - name: Enforce branch version - uses: giancosta86/aurora-github/actions/enforce-branch-version@v10.2.0 + uses: giancosta86/aurora-github/actions/enforce-branch-version@v11.0.0 with: mode: ${{ inputs.enforce-branch-version }} project-directory: ${{ inputs.project-directory }} - - name: Check Rust versions - uses: giancosta86/aurora-github/actions/check-rust-versions@v10.2.0 + - name: Setup Rust context + uses: giancosta86/aurora-github/actions/setup-rust-context@v11.0.0 with: project-directory: ${{ inputs.project-directory }} - name: Check style - shell: bash + shell: elvish {0} working-directory: ${{ inputs.project-directory }} run: | - checkStyle() { - checkFormat - - if [[ "${{ inputs.run-clippy-checks }}" == "true" ]] - then - runClippyChecks - fi - } + use aurora-github/ci-cd/input + use aurora-github/rust/project - checkFormat() { - echo "🎨Checking source code format..." - cargo fmt --check - echo "✅Source code format OK!" - } + var run-clippy-checks = (input:bool run-clippy-checks '${{ inputs.run-clippy-checks }}') - runClippyChecks() { - echo "📎Running clippy checks..." - cargo clippy --all-targets --all-features -- -D warnings - echo "✅Clippy checks OK!" - } + var check-rustdoc = (input:bool check-rustdoc '${{ inputs.check-rustdoc }}') - checkStyle + project:check-style &run-clippy-checks=$run-clippy-checks &check-rustdoc=$check-rustdoc - name: Extract code snippets as tests from README.md - uses: giancosta86/aurora-github/actions/extract-rust-snippets@v10.2.0 + uses: giancosta86/aurora-github/actions/extract-rust-snippets@v11.0.0 with: optional: true project-directory: ${{ inputs.project-directory }} - name: Run tests - shell: bash + shell: elvish {0} working-directory: ${{ inputs.project-directory }} run: | - runTests() { - runVanillaTests - - runAllFeaturesTests - - if [[ "${{ inputs.check-rustdoc }}" == "true" ]] - then - runDocTests - fi - } + use aurora-github/rust/project - runVanillaTests() { - echo "🔬Running tests with no features enabled..." - cargo test - echo "✅Tests with no features OK!" - } - - runAllFeaturesTests() { - echo "🔬Running tests with all the features enabled..." - cargo test --all-features - echo "✅Tests with all the features OK!" - } - - runDocTests() { - echo "📚Running doctests with all the features enabled..." - RUSTDOCFLAGS="-D warnings" cargo doc --all-features - echo "✅Doctests with all the features OK!" - } - - runTests + project:run-tests - name: Check for critical TODOs - uses: giancosta86/aurora-github/actions/find-critical-todos@v10.2.0 + uses: giancosta86/aurora-github/actions/find-critical-todos@v11.0.0 with: source-file-regex: ${{ inputs.source-file-regex }} crash-on-found: ${{ inputs.crash-on-critical-todos }} @@ -154,5 +81,8 @@ runs: root-directory: ${{ inputs.project-directory }} - name: Print confirmation message - shell: bash - run: echo "✅Rust crate project verified!" + shell: elvish {0} + run: | + use github.com/giancosta86/aurora-elvish/console + + console:echo ✅🦀 Rust crate project verified! diff --git a/actions/verify-rust-wasm/README.md b/actions/verify-rust-wasm/README.md index 7b5796e0d..9aa208ada 100644 --- a/actions/verify-rust-wasm/README.md +++ b/actions/verify-rust-wasm/README.md @@ -2,19 +2,17 @@ Verifies the source files of a **Rust** web assembly. -## 🃏Example +## 🃏 Example ```yaml steps: - - uses: actions/checkout@v4 - - - uses: giancosta86/aurora-github/actions/verify-rust-wasm@v10 + - uses: giancosta86/aurora-github/actions/verify-rust-wasm@v11 with: wasm-pack-version: 0.13.1 npm-scope: your-npm-scope ``` -## 💡How it works +## 💡 How it works 1. Invoke the [install-wasm-pack](../install-wasm-pack/README.md) action, passing all the matching inputs, to install the `wasm-pack` command. @@ -26,13 +24,13 @@ steps: 1. If the directory referenced by the `client-tests-directory` input exists, execute the [run-custom-tests](../run-custom-tests/README.md) action on it, with the `optional` flag enabled. -## ☑️Requirements +## ☑️ Requirements -- `rust-toolchain.toml` must be present in `project-directory` - as described in [check-rust-versions](../check-rust-versions/README.md) +- `rust-toolchain.toml` must be present in `project-directory` - as described in [setup-rust-context](../setup-rust-context/README.md) - Please, refer to the documentation of [run-custom-tests](../run-custom-tests/README.md) for details about setting up a suitable structure for `client-tests-directory`. -## 📥Inputs +## 📥 Inputs | Name | Type | Description | Default value | | :-----------------------: | :---------------------: | :-----------------------------------------------: | :-----------------------: | @@ -47,7 +45,7 @@ steps: | `enforce-branch-version` | `inject`,`check`,`skip` | How the branch version should be enforced | **inject** | | `project-directory` | **string** | The directory containing `Cargo.toml` | **.** | -## 🌐Further references +## 🌐 Further references - [check-project-license](../check-project-license/README.md) @@ -57,7 +55,7 @@ steps: - [parse-npm-scope](../parse-npm-scope/README.md) -- [check-rust-versions](../check-rust-versions/README.md) +- [setup-rust-context](../setup-rust-context/README.md) - [install-wasm-pack](../install-wasm-pack/README.md) diff --git a/actions/verify-rust-wasm/action.yml b/actions/verify-rust-wasm/action.yml index b335e3cb0..ced6ba5a6 100644 --- a/actions/verify-rust-wasm/action.yml +++ b/actions/verify-rust-wasm/action.yml @@ -6,14 +6,14 @@ inputs: description: The wasm-pack version to install. npm-scope: - description: The npm package scope or "". + description: The npm package scope or ``. client-tests-directory: description: Relative directory containing the client tests. default: client-tests wasm-target: - description: The target of the 'wasm-pack build' command. + description: The target of the `wasm-pack build` command. default: web run-clippy-checks: @@ -30,84 +30,28 @@ inputs: source-file-regex: description: PCRE pattern describing the source files. - default: '^\.\/((src|tests)\/.+\.rs)|(client-tests\/.+\.(c|m)?(j|t)sx?)$' + default: '^((src|tests)\/.+\.rs)|(client-tests\/.+\.(c|m)?(j|t)sx?)$' enforce-branch-version: description: How the branch version should be enforced. default: inject project-directory: - description: The directory containing Cargo.toml. + description: The directory containing `Cargo.toml`. default: . runs: using: composite steps: - - name: Validate inputs - shell: bash - working-directory: ${{ inputs.project-directory }} - run: | - if [[ -z "${{ inputs.wasm-pack-version }}" ]] - then - echo "❌Missing action input: 'wasm-pack-version'!" >&2 - exit 1 - fi - - if [[ -z "${{ inputs.npm-scope }}" ]] - then - echo "❌Missing action input: 'npm-scope'!" >&2 - exit 1 - fi - - if [[ -z "${{ inputs.client-tests-directory }}" ]] - then - echo "❌Missing action input: 'client-tests-directory'!" >&2 - exit 1 - fi - - if [[ -z "${{ inputs.wasm-target }}" ]] - then - echo "❌Missing action input: 'wasm-target'!" >&2 - exit 1 - fi - - if [[ -z "${{ inputs.run-clippy-checks }}" ]] - then - echo "❌Missing action input: 'run-clippy-checks'!" >&2 - exit 1 - fi - - if [[ -z "${{ inputs.check-rustdoc }}" ]] - then - echo "❌Missing action input: 'check-rustdoc'!" >&2 - exit 1 - fi - - if [[ -z "${{ inputs.crash-on-critical-todos }}" ]] - then - echo "❌Missing action input: 'crash-on-critical-todos'!" >&2 - exit 1 - fi - - if [[ -z "${{ inputs.source-file-regex }}" ]] - then - echo "❌Missing action input: 'source-file-regex'!" >&2 - exit 1 - fi - - if [[ -z "${{ inputs.enforce-branch-version }}" ]] - then - echo "❌Missing action input: 'enforce-branch-version'!" >&2 - exit 1 - fi + - uses: giancosta86/aurora-github/actions/setup-elvish-context@v11.0.0 - name: Install wasm-pack - uses: giancosta86/aurora-github/actions/install-wasm-pack@v10.2.0 + uses: giancosta86/aurora-github/actions/install-wasm-pack@v11.0.0 with: wasm-pack-version: ${{ inputs.wasm-pack-version }} - name: Verify Rust source files - uses: giancosta86/aurora-github/actions/verify-rust-crate@v10.2.0 + uses: giancosta86/aurora-github/actions/verify-rust-crate@v11.0.0 with: run-clippy-checks: ${{ inputs.run-clippy-checks }} check-rustdoc: ${{ inputs.check-rustdoc }} @@ -117,15 +61,15 @@ runs: project-directory: ${{ inputs.project-directory }} - name: Run headless browser tests - shell: bash + shell: elvish {0} working-directory: ${{ inputs.project-directory }} run: | - echo "🌐Running headless browser tests..." - wasm-pack test --chrome --headless --release - echo "✅Headless browser tests OK!" + use aurora-github/rust/wasm-pack + + wasm-pack:run-browser-tests - - name: Generate the NodeJS package source files - uses: giancosta86/aurora-github/actions/generate-wasm-target@v10.2.0 + - name: Generate the wasm target + uses: giancosta86/aurora-github/actions/generate-wasm-target@v11.0.0 with: target: ${{ inputs.wasm-target }} npm-scope: ${{ inputs.npm-scope }} @@ -134,11 +78,14 @@ runs: project-directory: ${{ inputs.project-directory }} - name: Run client tests - uses: giancosta86/aurora-github/actions/run-custom-tests@v10.2.0 + uses: giancosta86/aurora-github/actions/run-custom-tests@v11.0.0 with: optional: true root-directory: ${{ inputs.project-directory }}/${{ inputs.client-tests-directory }} - name: Print confirmation message - shell: bash - run: echo "✅Rust web assembly project verified!" + shell: elvish {0} + run: | + use github.com/giancosta86/aurora-elvish/console + + console:echo ✅🦀🌐 Rust web assembly project verified! diff --git a/core/action-references.elv b/core/action-references.elv new file mode 100644 index 000000000..9ffc3ed13 --- /dev/null +++ b/core/action-references.elv @@ -0,0 +1,24 @@ +use github.com/giancosta86/aurora-elvish/console +use github.com/giancosta86/aurora-elvish/map +use ./branch-version/detection +use ./ci-cd/action-references + +fn check { + var branch = (detection:detect)[branch] + + var regex = (action-references:get-regex-for-references-to-other-branches $branch) + + var grep-result = ?( + grep --color=always --perl-regexp $regex **.yml > &2 + ) + + if $grep-result { + fail "There are references to actions within '"$pwd"' residing in other branches!" + } else { + if (==s (map:drill-down &default='' $grep-result reason exit-status) 1) { + console:echo ✅ No cross-branch action references detected! + } else { + fail $grep-result + } + } +} \ No newline at end of file diff --git a/core/bash/npmPackage.sh b/core/bash/npmPackage.sh deleted file mode 100644 index 4b2d4a310..000000000 --- a/core/bash/npmPackage.sh +++ /dev/null @@ -1,9 +0,0 @@ -tryToRunNpmBuildScript() { - if jq -e '.scripts.build? != null' package.json > /dev/null - then - echo "✅'build' script found in package.json - now running it!" - pnpm build - else - echo "💭No 'build' script found in package.json - skipping the build step." - fi -} \ No newline at end of file diff --git a/core/bash/pdm.sh b/core/bash/pdm.sh deleted file mode 100644 index 347770fb5..000000000 --- a/core/bash/pdm.sh +++ /dev/null @@ -1,30 +0,0 @@ -ensurePdm() { - local requestedVersion="$1" - - installPdm() { - source "$GITHUB_ACTION_PATH/../../core/bash/pipx.sh" - - installViaPipx pdm "$requestedVersion" - } - - if which pdm - then - echo "🌟pdm is already installed!" - - if [[ -n "$requestedVersion" ]] - then - local installedVersion="$(pdm --version)" - - echo "🔎Installed pdm version: '$installedVersion'" - - if echo "$installedVersion" | grep -Pq "\b$requestedVersion\b" - then - echo "✅The requested pdm version is already installed!" - else - installPdm - fi - fi - else - installPdm - fi -} \ No newline at end of file diff --git a/core/bash/pipx.sh b/core/bash/pipx.sh deleted file mode 100644 index aa449f45c..000000000 --- a/core/bash/pipx.sh +++ /dev/null @@ -1,25 +0,0 @@ -installViaPipx() { - local package="$1" - local requestedVersion="$2" - - echo "📥Installing $package via pipx..." - - if [[ -n "$requestedVersion" ]] - then - echo "🔎Requested version: $requestedVersion" - else - echo "🔎Latest version requested" - fi - - if [[ -n "$requestedVersion" ]] - then - versionArg="==$requestedVersion" - else - versionArg="" - fi - - pipx install ${package}${versionArg} - - echo "✅$package installed!" -} - diff --git a/core/branch-version/detection.elv b/core/branch-version/detection.elv new file mode 100644 index 000000000..968bd420c --- /dev/null +++ b/core/branch-version/detection.elv @@ -0,0 +1,39 @@ +use path +use re +use github.com/giancosta86/aurora-elvish/console +use github.com/giancosta86/aurora-elvish/semver +use github.com/giancosta86/aurora-elvish/seq +use ../ci-cd/git-refs + +fn detect { + var actual-ref = (git-refs:get-actual) + + if (seq:is-empty $actual-ref) { + fail 'Cannot detect the actual Git ref!' + } + + console:inspect &emoji=🌳 'Actual Git ref' $actual-ref + + var branch = (path:base $actual-ref) + console:inspect &emoji=🌲 'Current Git branch' $branch + + var semantic-version = (semver:parse $branch) + + var version = (semver:to-string $semantic-version) + console:inspect &emoji=🦋 'Detected version' $version + + var escaped-version = (re:quote $version) + console:inspect &emoji=🧵 'Escaped version' $escaped-version + + var major = $semantic-version[major] + console:inspect &emoji=🪩 'Major version' $major + + put [ + &full-branch=$actual-ref + &branch=$branch + &version=$version + &escaped-version=$escaped-version + &major=$major + &semantic-version=$semantic-version + ] +} diff --git a/core/branch-version/enforcement.elv b/core/branch-version/enforcement.elv new file mode 100644 index 000000000..2ef782be6 --- /dev/null +++ b/core/branch-version/enforcement.elv @@ -0,0 +1,72 @@ +use str +use github.com/giancosta86/aurora-elvish/console +use github.com/giancosta86/aurora-elvish/edit +use github.com/giancosta86/aurora-elvish/map +use ../project +use ./detection + +fn -inject { |project| + console:echo 🧬 Injecting branch version into project: ($project[to-string]) + + var branch-version = (detection:detect)[version] + + edit:file $project[descriptor-path] { |text| + str:replace '0.0.0' $branch-version $text + } + + console:echo ✅ Version injected! + + $project[print-descriptor] +} + +fn -check { |project| + console:echo 🔎 Checking branch version for project: ($project[to-string]) + + $project[print-descriptor] + + var branch-version = (detection:detect)[version] + console:inspect &emoji=🌲 'Branch version' $branch-version + + var project-version = ($project[read-version]) + + if $project-version { + console:inspect &emoji=🏷 'Project version' $project-version + + if (==s $project-version $branch-version) { + console:echo ✅ The project version matches the branch version! + } else { + fail 'The project version and the branch version do not match!' + } + } else { + console:echo 💭 The project version cannot be detected... + console:echo 🔎 Ensuring the branch version is mentioned in the descriptor... + + var descriptor-content = (slurp < $project[descriptor-path]) + + if (str:contains $descriptor-content $branch-version) { + console:echo ✅ Branch version found in the descriptor! + } else { + fail 'The branch version cannot be found in the artifact descriptor!' + } + } +} + +var -strategies = [ + &inject=$-inject~ + + &check=$-check~ + + &skip={ |_| + console:echo 💭 Skipping branch version enforcement, as requested... + } +] + +fn enforce { |&descriptor-name=$nil mode| + var strategy = (map:get-value $-strategies $mode &default={ + fail "Invalid mode: '"$mode"'" + }) + + var project = (project:detect &descriptor-name=$descriptor-name) + + $strategy $project +} diff --git a/core/ci-cd/action-references.elv b/core/ci-cd/action-references.elv new file mode 100644 index 000000000..21bceb944 --- /dev/null +++ b/core/ci-cd/action-references.elv @@ -0,0 +1,9 @@ +use github.com/giancosta86/aurora-elvish/console +use github.com/giancosta86/aurora-elvish/seq +use ./repository + +fn get-regex-for-references-to-other-branches { |current-branch| + var full-repository-name = (repository:get-full-name) + + put 'uses:\s*'$full-repository-name'[^@]+@(?!'$current-branch')' +} \ No newline at end of file diff --git a/core/ci-cd/env.elv b/core/ci-cd/env.elv new file mode 100644 index 000000000..a0111d4e6 --- /dev/null +++ b/core/ci-cd/env.elv @@ -0,0 +1,9 @@ +use ./io + +fn write { |key value| + io:write (get-env GITHUB_ENV) $key $value +} + +fn map { |source-map| + io:map (get-env GITHUB_ENV) $source-map +} \ No newline at end of file diff --git a/core/ci-cd/git-refs.elv b/core/ci-cd/git-refs.elv new file mode 100644 index 000000000..4a315faf8 --- /dev/null +++ b/core/ci-cd/git-refs.elv @@ -0,0 +1,9 @@ +use github.com/giancosta86/aurora-elvish/lang +use github.com/giancosta86/aurora-elvish/seq + +fn get-actual { + var head-ref = (get-env GITHUB_HEAD_REF) + var ref = (get-env GITHUB_REF) + + lang:ternary (seq:is-non-empty $head-ref) $head-ref $ref +} diff --git a/core/ci-cd/input.elv b/core/ci-cd/input.elv new file mode 100644 index 000000000..3b61ebb96 --- /dev/null +++ b/core/ci-cd/input.elv @@ -0,0 +1,85 @@ +use os +use path +use str +use github.com/giancosta86/aurora-elvish/console +use github.com/giancosta86/aurora-elvish/seq + +fn string { |&optional=$false name value| + var trimmed-value = (str:trim-space $value) + + if (seq:is-empty $trimmed-value) { + if $optional { + put $nil + return + } else { + fail 'Missing input: '''$name'''!' + } + } + + put $trimmed-value +} + +fn -parse-string { |&optional=$false name value parser| + var source-string = (string &optional=$optional $name $value) + if (not $source-string) { + put $nil + return + } + + $parser $source-string +} + +fn bool { |&optional=$false name value| + -parse-string &optional=$optional $name $value { |source-string| + if (==s $source-string true) { + put $true + } elif (==s $source-string false) { + put $false + } else { + fail 'Invalid boolean value for the '''$name''' input: '''$source-string'''!' + } + } +} + +fn enum { |&optional=$false name value admissible-list| + -parse-string &optional=$optional $name $value { |source-string| + if (not (has-value $admissible-list $source-string)) { + fail 'Invalid enum value for the '''$name''' input: '''$source-string'''!' + } + + put $source-string + } +} + +fn -file-system-input { |&optional=$false &can-be-missing=$false type-description name value path-checker| + -parse-string &optional=$optional $name $value { |source-string| + var clean-path = (path:clean $source-string) + + if ($path-checker $clean-path) { + put $clean-path + } else { + if $can-be-missing { + console:inspect &emoji=💭 'Missing '$type-description' for input '''$name''' at path' $clean-path + put $nil + } else { + fail 'Inexistent '$type-description' for input '''$name''' at path: '''$clean-path'''!' + } + } + } +} + +fn directory { |&optional=$false &can-be-missing=$false name value| + -file-system-input &optional=$optional &can-be-missing=$can-be-missing directory $name $value $os:is-dir~ +} + +fn file { |&optional=$false &can-be-missing=$false name value| + -file-system-input &optional=$optional &can-be-missing=$can-be-missing file $name $value $os:is-regular~ +} + +fn list { |source| + put [( + str:split , $source | + each $str:trim-space~ | + keep-if $seq:is-non-empty~ + )] +} \ No newline at end of file diff --git a/core/ci-cd/io.elv b/core/ci-cd/io.elv new file mode 100644 index 000000000..d9291e605 --- /dev/null +++ b/core/ci-cd/io.elv @@ -0,0 +1,32 @@ +use github.com/giancosta86/aurora-elvish/console +use github.com/giancosta86/aurora-elvish/map +use github.com/giancosta86/aurora-elvish/seq + +var -constant-mappings = [ + &$nil='' + &$true='true' + &$false='false' +] + +var -supported-value-kinds = [string number] + +fn -format-value { |value| + var mapped-value = (map:get-value $-constant-mappings $value) + + coalesce $mapped-value $value +} + +fn write { |target-channel key value| + echo $key'='(-format-value $value) >> $target-channel +} + +fn map { |target-channel source-map| + map:entries $source-map | + seq:spread { |key value| + var value-kind = (kind-of $value) + + if (has-value $-supported-value-kinds $value-kind) { + write $target-channel $key $value + } + } +} \ No newline at end of file diff --git a/core/ci-cd/output.elv b/core/ci-cd/output.elv new file mode 100644 index 000000000..fedcb1b85 --- /dev/null +++ b/core/ci-cd/output.elv @@ -0,0 +1,9 @@ +use ./io + +fn write { |key value| + io:write (get-env GITHUB_OUTPUT) $key $value +} + +fn map { |source-map| + io:map (get-env GITHUB_OUTPUT) $source-map +} \ No newline at end of file diff --git a/core/ci-cd/pull-request.elv b/core/ci-cd/pull-request.elv new file mode 100644 index 000000000..ff5ff1e5b --- /dev/null +++ b/core/ci-cd/pull-request.elv @@ -0,0 +1,33 @@ +use str +use github.com/giancosta86/aurora-elvish/console +use github.com/giancosta86/aurora-elvish/lang + +fn triggers-current-workflow { + var github-ref = (get-env GITHUB_REF) + console:inspect &emoji=🧭 'GITHUB_REF' $github-ref + + lang:ternary (str:has-prefix $github-ref 'refs/pull/') $true $false +} + +fn fetch-info { |branch| + console:inspect &emoji=😺 'Retrieving Git pull request info for branch' $branch + + var raw-data = (gh pr view $branch --json title,number,baseRefOid,headRefOid | from-json) + + put [ + &branch=$branch + &title=$raw-data[title] + &number=$raw-data[number] + &base-sha=$raw-data[baseRefOid] + &head-sha=$raw-data[headRefOid] + ] +} + +fn merge { |branch git-strategy| + console:inspect &emoji=🔀 'Now merging the PR for branch' $branch + console:inspect &emoji=💡 'Git strategy' $git-strategy + + var git-stategy-arg = '--'$git-strategy + + gh pr merge $branch $git-stategy-arg --delete-branch +} \ No newline at end of file diff --git a/core/ci-cd/release-assets.elv b/core/ci-cd/release-assets.elv new file mode 100644 index 000000000..2473f1fc9 --- /dev/null +++ b/core/ci-cd/release-assets.elv @@ -0,0 +1,19 @@ +use github.com/giancosta86/aurora-elvish/console +use github.com/giancosta86/aurora-elvish/lang +use github.com/giancosta86/aurora-elvish/seq + +fn publish { |inputs| + console:inspect-inputs $inputs + + var release-tag = $inputs[release-tag] + var files = $inputs[files] + var overwrite = $inputs[overwrite] + + if (seq:is-empty $files) { + fail 'No files declared!' + } + + var clobber-arg = (lang:ternary $overwrite [--clobber] []) + + gh release upload $@clobber-arg $release-tag $@files +} diff --git a/core/ci-cd/repository.elv b/core/ci-cd/repository.elv new file mode 100644 index 000000000..bf56656b1 --- /dev/null +++ b/core/ci-cd/repository.elv @@ -0,0 +1,7 @@ +fn get-full-name { + get-env GITHUB_REPOSITORY +} + +fn get-changelog { |base-reference tag| + put 'https://github.com/'(get-full-name)'/compare/'$base-reference'..'$tag +} \ No newline at end of file diff --git a/core/ci-cd/required-jobs.elv b/core/ci-cd/required-jobs.elv new file mode 100644 index 000000000..7eec0cf4e --- /dev/null +++ b/core/ci-cd/required-jobs.elv @@ -0,0 +1,42 @@ +use github.com/giancosta86/aurora-elvish/console +use github.com/giancosta86/aurora-elvish/map + +var -result-descriptions = [ + &success='✅ (OK)' + &failure='❌ (FAILURE)' + &skipped='😴 (SKIPPED)' +] + +var -unknown-result-description = '❓ (UNKNOWN)' + +fn check { |needs-as-json| + var failure = $false + + var required-jobs = (echo $needs-as-json | from-json) + + console:section &emoji=🤹 'JOB SUMMARY' { + keys $required-jobs | + order | + each { |job-id| + var raw-job = $required-jobs[$job-id] + + var job-result = $raw-job[result] + + if (!=s $job-result success) { + set failure = $true + } + + var result-description = ( + map:get-value $-result-descriptions $job-result &default=$-unknown-result-description + ) + + console:echo '* '$job-id': '$result-description + } + } + + if $failure { + fail 'All the required jobs must be successful!' + } + + console:echo ✅ All the required jobs are OK! +} diff --git a/core/critical-todos.elv b/core/critical-todos.elv new file mode 100644 index 000000000..7cd6c347b --- /dev/null +++ b/core/critical-todos.elv @@ -0,0 +1,47 @@ +use github.com/giancosta86/aurora-elvish/console +use github.com/giancosta86/aurora-elvish/lang + +var -todo-text = (printf '%s%s' TODO !) + +fn find { |inputs| + console:inspect-inputs $inputs + + var verbose = $inputs[verbose] + var display-lines = $inputs[display-lines] + var source-file-regex = $inputs[source-file-regex] + var crash-on-found = $inputs[crash-on-found] + + console:inspect &emoji=📁 'Current directory' $pwd + + var quiet-grep-arg = (lang:ternary $display-lines '' '-q') + + var found = $false + + put **[type:regular] | + keep-if { |path| + eq $ok ?(echo $path | grep --perl-regexp --quiet $source-file-regex) + } | + each { |path| + if $verbose { + console:echo 🔎 Looking for critical TODOs in path: $path... + } + + var found-in-file = ?(grep --color=always --with-filename --line-number $@quiet-grep-arg $-todo-text $path > &2) + + if $found-in-file { + set found = $true + } + } + + if $found { + if $crash-on-found { + fail 'Critical TODOs found!' + } else { + console:echo 🤯 Critical TODOs found! + put $true + } + } else { + console:echo ✅ No critical TODOs found! + put $false + } +} diff --git a/core/custom-tests.elv b/core/custom-tests.elv new file mode 100644 index 000000000..1b1002983 --- /dev/null +++ b/core/custom-tests.elv @@ -0,0 +1,93 @@ +use os +use github.com/giancosta86/aurora-elvish/console +use github.com/giancosta86/velvet/main velvet +use ./ci-cd/env +use ./script + + +fn -set-strategy { |strategy| + console:inspect &emoji=💡 'Current test strategy' $strategy + env:write strategy $strategy +} + +fn -set-script-strategy { |script-path| + -set-strategy script + + console:inspect &emoji=📃 'Test script to run' $script-path + + env:write scriptPath $script-path +} + +fn -enforce-exit-strategy { + -set-strategy exit +} + +fn detect-strategy { |inputs| + console:inspect-inputs $inputs + + var optional = $inputs[optional] + var script-file = $inputs[script-file] + var root-directory = $inputs[root-directory] + + console:echo 🔬 Looking for a custom test strategy... + + if (not $root-directory) { + if $optional { + console:echo 💭 Skipping optional tests in missing root directory... + -enforce-exit-strategy + return + } else { + fail "Cannot run custom tests in missing root directory: '"$root-directory"'!" + } + } + + console:echo 🔁📁 Test root directory "'"$root-directory"'" found! + tmp pwd = $root-directory + + var target-script-file = (coalesce $script-file verify) + + var actual-script-path = (script:get-actual-path $target-script-file) + + if $actual-script-path { + console:echo 🐚 Shell script strategy requested! + -set-script-strategy $actual-script-path + return + } else { + if $script-file { + var error-message = "Cannot find the '"$script-file"' script file" + + if $optional { + console:echo 💭 $error-message... + -enforce-exit-strategy + return + } else { + fail $error-message + } + } + } + + if (velvet:has-test-scripts) { + console:echo 📋 aurora-elvish .test.elv files found! + -set-strategy velvet + return + } + + if (os:is-regular package.json) { + console:echo 📦 package.json file found! + -set-strategy nodejs + return + } + + if (os:is-regular Cargo.toml) { + console:echo 🦀 Cargo.toml file found! + -set-strategy rust + return + } + + if $optional { + console:echo 💭 No supported strategy detected for the optional custom tests... + -enforce-exit-strategy + } else { + fail 'Cannot run mandatory custom tests: no supported test strategy could be detected!' + } +} diff --git a/core/elvish-library.elv b/core/elvish-library.elv new file mode 100644 index 000000000..3da35abd4 --- /dev/null +++ b/core/elvish-library.elv @@ -0,0 +1,28 @@ +use os +use github.com/giancosta86/aurora-elvish/console +use github.com/giancosta86/aurora-elvish/string + +var -metadata-file = metadata.json + +var -required-fields = [ + description + maintainers + homepage + dependencies +] + +fn check-metadata { + if (not (os:is-regular $-metadata-file)) { + fail 'Missing library metadata file: '$-metadata-file + } + + var metadata = (from-json < $-metadata-file) + + all $-required-fields | each { |field| + if (not (has-key $metadata $field)) { + fail 'Missing required field in '$-metadata-file': '$field + } + } + + console:echo ✅ Library metadata OK! +} \ No newline at end of file diff --git a/core/git.elv b/core/git.elv new file mode 100644 index 000000000..6d1d3deda --- /dev/null +++ b/core/git.elv @@ -0,0 +1,53 @@ +use math +use github.com/giancosta86/aurora-elvish/command +use github.com/giancosta86/aurora-elvish/console +use github.com/giancosta86/aurora-elvish/lang + +fn hard-reset { + console:echo ⏱️ Discarding local changes to the Git repository... + + command:silence-until-error { + git reset --hard HEAD + } + + console:echo ✅ Git repository successfully reset +} + +fn fetch-branched-sha { |&depth-delta=25 &delta-factor=1.5 branch required-sha| + console:inspect &emoji=🧭 'Iteratively trying to fetch Git SHA' $required-sha + + while (not ?(command:silence { git cat-file commit $required-sha })) { + console:echo 📥 Fetching $depth-delta more commits... + + command:silence-until-error { + git fetch --deepen=$depth-delta origin $branch + } + + set depth-delta = (* $depth-delta $delta-factor | math:ceil (all) | exact-num (all)) + } + + console:inspect &emoji=✅ 'Git SHA ready' $required-sha +} + +fn fetch-tags { + console:echo 📥 Retrieving Git tags... + + command:silence-until-error { + git fetch --tags + } + + console:echo ✅ Git tags retrieved! +} + +fn create-and-push-tag { |&force=$false tag| + console:inspect &emoji=📌 'Creating and pushing Git tag' $tag + + var force-arg = (lang:ternary $force [--force] []) + + command:silence-until-error { + git tag $@force-arg $tag + git push origin $tag $@force-arg + } + + console:echo 📌 Tag created and pushed! +} \ No newline at end of file diff --git a/core/highlighting.elv b/core/highlighting.elv new file mode 100644 index 000000000..3c52e260e --- /dev/null +++ b/core/highlighting.elv @@ -0,0 +1,19 @@ +fn -run-or-cat { |@command-line| + var command = $command-line[0] + + if (has-external $command) { + var args = $command-line[1..] + + (external $command) $@args + } else { + cat + } +} + +fn highlight { |format| + if (==s $format json) { + -run-or-cat jq -C + } else { + -run-or-cat pygmentize -l $format + } +} \ No newline at end of file diff --git a/core/jvm/context.elv b/core/jvm/context.elv new file mode 100644 index 000000000..ff0f91e1f --- /dev/null +++ b/core/jvm/context.elv @@ -0,0 +1,36 @@ +use github.com/giancosta86/aurora-elvish/console +use ./project +use ./sdkman + +var -build-tool-sdks = [ + &mvn=maven + &gradle=gradle +] + +fn setup { |&java-version=$nil &tool-version=$nil| + console:inspect-inputs [ + &java-version=$java-version + &tool-version=$tool-version + ] + + console:echo ☕💻 Setting up JVM context in "'"$pwd"'"... + + var project = (project:detect-for-jvm) + var build-tool = $project[build-tool] + + if $java-version { + sdkman:install-sdk java $java-version + } + + if $tool-version { + var build-tool-sdk = $-build-tool-sdks[build-tool] + + sdkman:install $build-tool-sdk $tool-version + } + + put [ + &buildTool=$build-tool + ] + + console:echo ✅☕ JVM context in "'"$pwd"'" ready! +} \ No newline at end of file diff --git a/core/jvm/gradle.elv b/core/jvm/gradle.elv new file mode 100644 index 000000000..b522fa926 --- /dev/null +++ b/core/jvm/gradle.elv @@ -0,0 +1,24 @@ +use github.com/giancosta86/aurora-elvish/console +use github.com/giancosta86/aurora-elvish/lang + +fn run { |&quiet=$true @rest| + var quiet-arg = (lang:ternary $quiet [-q] []) + + gradle --no-daemon --no-scan $@quiet-arg $@rest +} + +fn verify-project { |&quiet=$true| + console:echo 🐘 Running Gradle to verify the project... + + run &quiet=$quiet build + + console:echo ✅ Gradle verification OK! +} + +fn publish-project { |&quiet=$true &dry-run=$true| + console:echo 🐘 Running Gradle to publish the project... + + var dry-run-arg = (lang:ternary $dry-run [--dry-run] []) + + run &quiet=$quiet $@dry-run-arg publish +} \ No newline at end of file diff --git a/core/jvm/gradle/descriptor.elv b/core/jvm/gradle/descriptor.elv new file mode 100644 index 000000000..12ca83217 --- /dev/null +++ b/core/jvm/gradle/descriptor.elv @@ -0,0 +1,17 @@ +use os + +var -supported-descriptors = [ + build.gradle.kts + build.gradle +] + +fn get-name { + for descriptor $-supported-descriptors { + if (os:is-regular $descriptor) { + put $descriptor + return + } + } + + fail 'No supported Gradle descriptor found in '''$pwd'''!' +} \ No newline at end of file diff --git a/core/jvm/gradle/settings.elv b/core/jvm/gradle/settings.elv new file mode 100644 index 000000000..ba7dc27cd --- /dev/null +++ b/core/jvm/gradle/settings.elv @@ -0,0 +1,23 @@ +use str +use github.com/giancosta86/aurora-elvish/console +use ./descriptor + +fn prepare-for-publication { + console:echo 🐘 Preparing Gradle settings for publication... + + var descriptor-name = (descriptor:get-name) + + var descriptor-content = (slurp < $descriptor-name) + + console:section &emoji=🐘 'Checking the optional use of environment variables in the descriptor' { + for env-var [JVM_AUTH_USER JVM_AUTH_TOKEN] { + if (str:contains $descriptor-content $env-var) { + console:inspect &emoji=✅ 'Referenced' $env-var + } else { + console:inspect &emoji=💭 'Not mentioned' $env-var + } + } + } + + console:echo ✅ Gradle settings now ready! +} \ No newline at end of file diff --git a/core/jvm/maven.elv b/core/jvm/maven.elv new file mode 100644 index 000000000..90a79bcb9 --- /dev/null +++ b/core/jvm/maven.elv @@ -0,0 +1,30 @@ +use github.com/giancosta86/aurora-elvish/console +use github.com/giancosta86/aurora-elvish/lang + +fn run { |&quiet=$true @rest| + var quiet-arg = (lang:ternary $quiet [-q] []) + + mvn -B $@quiet-arg $@rest +} + +fn verify-project { |&quiet=$true| + console:echo 🪶 Running Maven to verify the project... + run &quiet=$quiet verify + console:echo ✅ Maven verification OK! +} + +fn publish-project { |&quiet=$true &dry-run=$true| + var dry-run-arg + + if $dry-run { + var dry-run-directory = target/dry-run + + console:inspect &emoji=📁 'dry-run mode enabled - publishing to local directory' $dry-run-directory + + set dry-run-arg = [-DaltDeploymentRepository=target-server::default::file:$dry-run-directory] + } else { + set dry-run-arg = [] + } + + run &quiet=$quiet $@dry-run-arg deploy +} \ No newline at end of file diff --git a/core/jvm/maven/settings.elv b/core/jvm/maven/settings.elv new file mode 100644 index 000000000..5e992ab05 --- /dev/null +++ b/core/jvm/maven/settings.elv @@ -0,0 +1,58 @@ +use os +use path +use str +use github.com/giancosta86/aurora-elvish/console +use github.com/giancosta86/aurora-elvish/fs +use github.com/giancosta86/aurora-elvish/resources +use ../../highlighting + +var -resources = (resources:for-script (src)) + +var -user-settings-path = ~/.m2/settings.xml + +var -user-settings-filename = (path:base $-user-settings-path) + +fn -copy-default-settings { + console:echo 🌟 Providing a default settings file for 🪶 Maven... + + var default-settings-path = ($-resources[get-path] $-user-settings-filename) + + fs:copy $default-settings-path $-user-settings-path + + console:section &emoji=🪶 'Content of the per-user Maven settings file' { + cat $-user-settings-path | highlighting:highlight xml + } +} + +fn -check-server-in-pom { + var server-name = target-server + + if (slurp < pom.xml | str:contains (all) $server-name) { + console:echo ✅ Server "'"$server-name"'" found in pom.xml! + } else { + console:echo 💭 Server "'"$server-name"'" not mentioned in pom.xml... + } +} + +fn prepare-for-publication { + console:echo 🪶 Preparing Maven settings for publication... + + if (os:is-regular $-user-settings-path) { + console:inspect &emoji=🌟 'Maven settings file found at' $-user-settings-path + return + } + + os:mkdir-all (path:dir $-user-settings-path) + + if (os:is-regular $-user-settings-filename) { + console:echo 📃 Maven settings file found in the current directory! Now copying it... + + fs:copy $-user-settings-filename $-user-settings-path + } else { + -copy-default-settings + + -check-server-in-pom + } + + console:echo ✅ Maven settings now ready! +} diff --git a/actions/publish-jvm-project/settings.xml b/core/jvm/maven/settings.xml similarity index 100% rename from actions/publish-jvm-project/settings.xml rename to core/jvm/maven/settings.xml diff --git a/core/jvm/project.elv b/core/jvm/project.elv new file mode 100644 index 000000000..49e86957b --- /dev/null +++ b/core/jvm/project.elv @@ -0,0 +1,18 @@ +use github.com/giancosta86/aurora-elvish/console +use ../project + +var -supported-build-tools = [mvn gradle] + +fn detect-for-jvm { + var project = (project:detect) + + var build-tool = $project[build-tool] + + console:inspect &emoji=⚒ 'Project build tool' $build-tool + + if (not (has-value $-supported-build-tools $build-tool)) { + fail 'Unsupported build tool for a JVM project: '$build-tool + } + + put $project +} \ No newline at end of file diff --git a/core/jvm/project/publication.elv b/core/jvm/project/publication.elv new file mode 100644 index 000000000..1c823e3c6 --- /dev/null +++ b/core/jvm/project/publication.elv @@ -0,0 +1,20 @@ +var -project-publishers = [ + &mvn={ |inputs| + use ../maven + maven:publish-project &quiet=$inputs[quiet-tool] &dry-run=$inputs[dry-run] + } + + &gradle={ |inputs| + use ../gradle + gradle:publish-project &quiet=$inputs[quiet-tool] &dry-run=$inputs[dry-run] + } +] + +fn publish { |&quiet-tool=$true &dry-run=$true build-tool| + var publisher = $-project-publishers[$build-tool] + + $publisher [ + &quiet-tool=$quiet-tool + &dry-run=$dry-run + ] +} \ No newline at end of file diff --git a/core/jvm/project/verification.elv b/core/jvm/project/verification.elv new file mode 100644 index 000000000..338f02d97 --- /dev/null +++ b/core/jvm/project/verification.elv @@ -0,0 +1,17 @@ +var -project-verifiers = [ + &mvn={ |quiet-tool| + use ../maven + maven:verify-project &quiet=$quiet-tool + } + + &gradle={ |quiet-tool| + use ../gradle + gradle:verify-project &quiet=$quiet-tool + } +] + +fn verify { |&quiet-tool=$true build-tool| + var verifier = $-project-verifiers[$build-tool] + + $verifier $quiet-tool +} \ No newline at end of file diff --git a/core/jvm/sdkman.elv b/core/jvm/sdkman.elv new file mode 100644 index 000000000..828e77aee --- /dev/null +++ b/core/jvm/sdkman.elv @@ -0,0 +1,40 @@ +use os +use github.com/giancosta86/aurora-elvish/console +use ../ci-cd/env + +var -sdkman-home = ~/.sdkman +var -sdkman-script = $-sdkman-home/bin/sdkman-init.sh + +fn -ensure-installed { + if (os:is-dir $-sdkman-home) { + console:echo 🎉 It seems that SDKMAN was previously installed! + return + } + + console:echo 📥 Installing SDKMAN... + + curl -s 'https://get.sdkman.io' | bash + + console:echo ✅ SDKMAN installed! +} + +fn install-sdk { |candidate version| + -ensure-installed + + console:echo 📥 Installing $candidate'('$version')...' + + bash -c "source '"$-sdkman-script"'; sdk install '"$candidate"' '"$version"'" + + var sdk-bin = $-sdkman-home/candidates/$candidate/$version/bin + + if (not (os:is-dir $sdk-bin)) { + fail 'Inexistent sdk ''bin'' directory: '$sdk-bin + } + + var updated-path = $sdk-bin':'(get-env PATH) + + set-env PATH $updated-path + env:write PATH $updated-path + + console:echo ✅ $candidate'('$version')' installed! +} diff --git a/core/jvm/settings.elv b/core/jvm/settings.elv new file mode 100644 index 000000000..5f54ae749 --- /dev/null +++ b/core/jvm/settings.elv @@ -0,0 +1,17 @@ +var -publication-preparers = [ + &mvn={ + use ./maven/settings + settings:prepare-for-publication + } + + &gradle={ + use ./gradle/settings + settings:prepare-for-publication + } +] + +fn prepare-for-publication { |build-tool| + var preparer = $-publication-preparers[$build-tool] + + $preparer +} \ No newline at end of file diff --git a/core/license-file.elv b/core/license-file.elv new file mode 100644 index 000000000..e7cd9f1c3 --- /dev/null +++ b/core/license-file.elv @@ -0,0 +1,24 @@ +use github.com/giancosta86/aurora-elvish/console +use github.com/giancosta86/aurora-elvish/seq + +fn -check-includes-current-year { |license-file| + var current-year = (date +%Y) + + if (seq:is-empty $current-year) { + fail 'Cannot detect the current year!' + } + + console:inspect &emoji=🗓 'Current year' $current-year + + console:echo 🔎🗓 Searching the license file for the current year... + + if ?(grep --color=always $current-year $license-file > &2) { + console:echo ✅ Current year found in the license file! + } else { + fail 'Cannot find the current year in the license file!' + } +} + +fn check { |license-file| + -check-includes-current-year $license-file +} diff --git a/core/nodejs/context.elv b/core/nodejs/context.elv new file mode 100644 index 000000000..465b5cee9 --- /dev/null +++ b/core/nodejs/context.elv @@ -0,0 +1,93 @@ +use os +use str +use github.com/giancosta86/aurora-elvish/console +use github.com/giancosta86/aurora-elvish/lang +use github.com/giancosta86/aurora-elvish/nvm/node-version +use github.com/giancosta86/aurora-elvish/seq +use ../ci-cd/env + +fn check-preconditions { + console:echo 📦💻 Setting up NodeJS context in "'"$pwd"'"... + + if (not (os:is-regular package.json)) { + fail 'The package.json descriptor is missing!' + } +} + +fn detect-nodejs-constraints { + var requested-node-version = (node-version:detect-in-pwd) + + var install-toolchain + + if $requested-node-version { + console:inspect 'Requested NodeJS version' $requested-node-version + set install-toolchain = true + } else { + console:echo 💭 No requested NodeJS version... + set install-toolchain = false + } + + console:inspect 'Install NodeJS toolchain' $install-toolchain + + put [ + &install-toolchain=$install-toolchain + &requested-node-version=$requested-node-version + ] +} + +fn detect-pnpm-constraints { + var package-manager-reference = (jq -r '.packageManager // ""' package.json) + + console:inspect &emoji=📦 'Package manager reference' $package-manager-reference + + var requested-pnpm-version + + if (seq:is-non-empty $package-manager-reference) { + var requested-package-manager requested-package-manager-version = ( + echo $package-manager-reference | str:split @ (all) + ) + + if (!=s $requested-package-manager pnpm) { + fail 'The package manager must be pnpm!' + } + + set requested-pnpm-version = $requested-package-manager-version + + console:inspect 'Requested pnpm version' $requested-pnpm-version + } else { + console:echo 🌟 Defaulting to the latest pnpm version! + set requested-pnpm-version = latest + } + + console:inspect &emoji=🔬 'pnpm version to install' $requested-pnpm-version + + put [ + &requested-pnpm-version=$requested-pnpm-version + ] +} + +fn set-pnpm-colors { |enabled| + var key = FORCE_COLOR + var value = (lang:ternary $enabled 1 0) + + set-env $key $value + env:write $key $value +} + +fn install-dependencies { + var lockfile = pnpm-lock.yaml + + var lockfile-arg + + if (os:is-regular $lockfile) { + console:echo 🧊 Installing dependencies with frozen lockfile, as "'"$lockfile"'" is present... + set lockfile-arg = --frozen-lockfile + } else { + console:echo 🌞 Installing dependencies without frozen lockfile, as "'"$lockfile"'" is missing... + set lockfile-arg = --no-frozen-lockfile + } + + pnpm install $lockfile-arg + + console:echo ✅ Dependencies installed! +} diff --git a/core/nodejs/pnpm.elv b/core/nodejs/pnpm.elv new file mode 100644 index 000000000..bf5b7883b --- /dev/null +++ b/core/nodejs/pnpm.elv @@ -0,0 +1,47 @@ +use os +use str +use github.com/giancosta86/aurora-elvish/console +use github.com/giancosta86/aurora-elvish/map +use ../highlighting + +fn parse-scope { |declared-scope| + if (==s $declared-scope '') { + console:echo 🫚 Root npm scope detected! + put $nil + } else { + var actual-scope = (str:trim-prefix $declared-scope @) + console:inspect &emoji=☂ 'Custom npm scope detected' $actual-scope + put $actual-scope + } +} + +fn run-optional-script { |script| + var package-json = (from-json < package.json) + + var scripts = (coalesce (map:get-value $package-json scripts) [&]) + + if (has-key $scripts $script) { + console:echo 🛠 Optional "'"$script"'" script found in package.json - now running it! + + pnpm $script + } else { + console:echo 💭 Optional "'"$script"'" script not found in package.json... + } +} + +fn ensure-config { + var config-path = .npmrc + + if (os:is-regular $config-path) { + console:echo 🌟You already have a custom $config-path file! + return + } + + console:echo 🧞 It seems you do not have a $config-path file - generating a default one... + + echo '//registry.npmjs.org/:_authToken=${NPM_TOKEN}' > $config-path + + console:section &emoji=🎀 'Your auto-generated '$config-path' configuration file' { + cat $config-path | highlighting:highlight ini + } +} \ No newline at end of file diff --git a/core/nodejs/project.elv b/core/nodejs/project.elv new file mode 100644 index 000000000..6bce49797 --- /dev/null +++ b/core/nodejs/project.elv @@ -0,0 +1,16 @@ +use github.com/giancosta86/aurora-elvish/console +use github.com/giancosta86/aurora-elvish/lang + +fn verify { + console:echo 📦 Now running the 'verify' script from package.json... + + pnpm verify + + console:echo ✅Verification script OK! +} + +fn publish { |dry-run| + var dry-run-arg = (lang:ternary $dry-run [--dry-run] []) + + pnpm publish --no-git-checks --access public $@dry-run-arg +} diff --git a/core/nodejs/subpath-exports.elv b/core/nodejs/subpath-exports.elv new file mode 100644 index 000000000..1fc0abef7 --- /dev/null +++ b/core/nodejs/subpath-exports.elv @@ -0,0 +1,6 @@ +use ./subpath-exports/check +use ./subpath-exports/inject + +var check~ = $check:check~ + +var inject~ = $inject:inject~ diff --git a/core/nodejs/subpath-exports/check.elv b/core/nodejs/subpath-exports/check.elv new file mode 100644 index 000000000..5753a12cc --- /dev/null +++ b/core/nodejs/subpath-exports/check.elv @@ -0,0 +1,60 @@ +use os +use github.com/giancosta86/aurora-elvish/console +use github.com/giancosta86/aurora-elvish/lang +use github.com/giancosta86/aurora-elvish/map + +var -check-json-value~ + +fn -check-json-object { |path-in-json json-object| + keys $json-object | order | each { |key| + -check-json-value $path-in-json'->'$key $json-object[$key] + } +} + +fn -check-file-pattern { |path-in-json file-pattern| + console:print 🔎 $path-in-json'->'$file-pattern...' ' + + var matches = (find . -wholename $file-pattern | wc -l) + + if (== $matches 0) { + console:echo ❌ + fail 'No file matching subpath pattern: '$file-pattern + } else { + console:echo ✅ + } +} + +set -check-json-value~ = { |path-in-json json-value| + var checker = ( + lang:ternary (==s (kind-of $json-value) map) $-check-json-object~ $-check-file-pattern~ + ) + + $checker $path-in-json $json-value +} + +fn check { + if (not (os:is-regular package.json)) { + fail 'The package.json descriptor file does not exist!' + } + + var exports = ( + from-json < package.json | + map:get-value (all) exports + ) + + if (not $exports) { + console:echo 💭 No exports declared in package.json... + return + } + + if (== (count $exports) 0) { + console:echo 💭 Exports are an empty object... + return + } + + console:echo 🔎 Now inspecting subpath exports... + + -check-json-value exports $exports + + console:echo ✅ Export subpaths are OK! +} \ No newline at end of file diff --git a/core/nodejs/subpath-exports/inject.elv b/core/nodejs/subpath-exports/inject.elv new file mode 100644 index 000000000..f06053ee5 --- /dev/null +++ b/core/nodejs/subpath-exports/inject.elv @@ -0,0 +1,92 @@ +use os +use path +use str +use github.com/giancosta86/aurora-elvish/console +use github.com/giancosta86/aurora-elvish/edit + +var -index-names = [index.ts index.js] + +fn -print-exports { |context-description| + console:section &emoji=📦 'package.json exports '$context-description { + jq -C .exports package.json + } +} + +fn -write-export { |relative-index-directory| + if (not ( + or (==s $relative-index-directory '') (str:has-prefix $relative-index-directory '/') + )) { + fail 'The relative index directory must be empty or have a leading /' + } + + var export-key = '.'$relative-index-directory + + var dist-index-directory = './dist'$relative-index-directory + + console:echo "🔑 Export '"$export-key"' provided by dist directory: '"$dist-index-directory"'" + + edit:json package.json ' + .exports += { + "'$export-key'": { + types: "'$dist-index-directory'/index.d.ts", + import: "'$dist-index-directory'/index.js" + } + }' + + console:echo ✅ Export $export-key injected! +} + +fn -inject-root-index { |source-directory| + put $source-directory/{$@-index-names} | each { |potential-root-index| + console:inspect 'Looking for potential root index' $potential-root-index + + if (os:is-regular $potential-root-index) { + console:inspect &emoji=✅ 'Root index file found' $potential-root-index + + -write-export '' + + put $true + return + } + } + + console:echo 💭 No root index file found... + put $false +} + +fn -inject-subdirectory-indexes { |source-directory| + console:echo 🔽 Looking for potential subdirectory indexes... + + put $source-directory/*[type:regular][nomatch-ok]/{$@-index-names} | + each { |index-path| + console:inspect &emoji=💡 'Index file found in subdirectory, at path' $index-path + + var export-name = (str:trim-prefix (path:dir $index-path) $source-directory/) + + -write-export '/'$export-name + } +} + +fn -do-inject { |source-directory mode| + var root-index-injected = (-inject-root-index $source-directory) + + if (and $root-index-injected (==s $mode prefer-index)) { + console:echo 🐹 In this mode, since the root index has been found, no more subpath exports will be injected + return + } + + -inject-subdirectory-indexes $source-directory +} + +fn inject { | inputs | + console:inspect-inputs $inputs + + var mode = $inputs[mode] + var source-directory = $inputs[source-directory] + + -print-exports 'before the injection' + + -do-inject $source-directory $mode + + -print-exports 'after the injection' +} \ No newline at end of file diff --git a/core/project.elv b/core/project.elv new file mode 100644 index 000000000..d979c09cd --- /dev/null +++ b/core/project.elv @@ -0,0 +1,5 @@ +use ./project/loader + +fn detect { |&descriptor-name=$nil| + loader:load &descriptor-name=$descriptor-name +} diff --git a/core/project/base.elv b/core/project/base.elv new file mode 100644 index 000000000..7f8d2070b --- /dev/null +++ b/core/project/base.elv @@ -0,0 +1,38 @@ +use path +use github.com/giancosta86/aurora-elvish/console +use github.com/giancosta86/aurora-elvish/map +use ./descriptors/plain-text + +fn load-project { |inputs| + var descriptor-namespace = $inputs[descriptor-namespace] + var descriptor-name = $inputs[descriptor-name] + var technology = $inputs[technology] + var build-tool = $inputs[build-tool] + var emoji = $inputs[emoji] + + var descriptor-path = (path:join $pwd $descriptor-name) + + put [ + &directory=$pwd + + &descriptor-path=$descriptor-path + + &descriptor-name=$descriptor-name + + &technology=$technology + + &build-tool=$build-tool + + &emoji=$emoji + + &read-version={ $descriptor-namespace[read-version~] $descriptor-path } + + &print-descriptor={ + console:section &emoji=$emoji 'Project descriptor ('$descriptor-name')' { + $descriptor-namespace[print-content~] $descriptor-path + } + } + + &to-string={ put $emoji' '$technology' ('$descriptor-name')' } + ] +} diff --git a/core/project/descriptors/gradle.elv b/core/project/descriptors/gradle.elv new file mode 100644 index 000000000..4c58e3db8 --- /dev/null +++ b/core/project/descriptors/gradle.elv @@ -0,0 +1,14 @@ +use path +use github.com/giancosta86/aurora-elvish/lang +use ../../highlighting +use ./toml + +var read-version~ = $toml:read-version~ + +fn print-content { |descriptor-path| + var extension = (path:ext $descriptor-path) + + var highlighting-format = (lang:ternary (==s $extension .kts) kotlin groovy) + + cat $descriptor-path | highlighting:highlight $highlighting-format +} \ No newline at end of file diff --git a/core/project/descriptors/json.elv b/core/project/descriptors/json.elv new file mode 100644 index 000000000..7802a5385 --- /dev/null +++ b/core/project/descriptors/json.elv @@ -0,0 +1,9 @@ +use ../../highlighting + +fn read-version { |descriptor-path| + put (from-json < $descriptor-path)[version] +} + +fn print-content { |descriptor-path| + cat $descriptor-path | highlighting:highlight json +} \ No newline at end of file diff --git a/core/project/descriptors/plain-text.elv b/core/project/descriptors/plain-text.elv new file mode 100644 index 000000000..46a6ede25 --- /dev/null +++ b/core/project/descriptors/plain-text.elv @@ -0,0 +1,7 @@ +fn read-version { |descriptor-path| + put $nil +} + +fn print-content { |descriptor-path| + cat $descriptor-path +} \ No newline at end of file diff --git a/core/project/descriptors/toml.elv b/core/project/descriptors/toml.elv new file mode 100644 index 000000000..b61995672 --- /dev/null +++ b/core/project/descriptors/toml.elv @@ -0,0 +1,18 @@ +use re +use ../../highlighting + +fn read-version { |descriptor-path| + cat $descriptor-path | from-lines | each { |line| + re:find '^\s*version\s*=\s*["''](.*)["'']\s*$' $line | + each { |match| + put $match[groups][1][text] + return + } + } + + put $nil +} + +fn print-content { |descriptor-path| + cat $descriptor-path | highlighting:highlight toml +} \ No newline at end of file diff --git a/core/project/descriptors/xml-version.py b/core/project/descriptors/xml-version.py new file mode 100644 index 000000000..9837ec877 --- /dev/null +++ b/core/project/descriptors/xml-version.py @@ -0,0 +1,19 @@ +import sys +import xml.etree.ElementTree as ET + +descriptor_path = sys.argv[1] + +tree = ET.parse(descriptor_path) + +root = tree.getroot() + +namespaces = {"mvn": root.tag.split("}")[0].strip("{}")} + +version_tag = root.find(".//mvn:version", namespaces) + +if version_tag is None: + raise Exception("Cannot find the tag!") + +version = version_tag.text + +print(version) \ No newline at end of file diff --git a/core/project/descriptors/xml.elv b/core/project/descriptors/xml.elv new file mode 100644 index 000000000..df6ce0fd1 --- /dev/null +++ b/core/project/descriptors/xml.elv @@ -0,0 +1,15 @@ +use str +use github.com/giancosta86/aurora-elvish/resources +use ../../highlighting + +var -resources = (resources:for-script (src)) + +fn read-version { |descriptor-path| + var python-script-path = ($-resources[get-path] xml-version.py) + + python3 $python-script-path $descriptor-path +} + +fn print-content { |descriptor-path| + cat $descriptor-path | highlighting:highlight xml +} \ No newline at end of file diff --git a/core/project/gradle.elv b/core/project/gradle.elv new file mode 100644 index 000000000..5b1197534 --- /dev/null +++ b/core/project/gradle.elv @@ -0,0 +1,16 @@ +use ./base +use ./descriptors/gradle + +fn load-project { |descriptor-name| + base:load-project [ + &descriptor-namespace=$gradle: + + &descriptor-name=$descriptor-name + + &technology=Gradle + + &build-tool=gradle + + &emoji=🐘 + ] +} diff --git a/core/project/loader.elv b/core/project/loader.elv new file mode 100644 index 000000000..fbe9070f1 --- /dev/null +++ b/core/project/loader.elv @@ -0,0 +1,79 @@ +use os +use github.com/giancosta86/aurora-elvish/console +use github.com/giancosta86/aurora-elvish/lang +use github.com/giancosta86/aurora-elvish/map + +var -loader-retrievers = [ + &package.json={ + use ./nodejs + put $nodejs:load-project~ + } + + &Cargo.toml={ + use ./rust + put $rust:load-project~ + } + + &pom.xml={ + use ./maven + put $maven:load-project~ + } + + &build.gradle={ + use ./gradle + put { gradle:load-project build.gradle } + } + + &build.gradle.kts={ + use ./gradle + put { gradle:load-project build.gradle.kts } + } + + &pyproject.toml={ + use ./python + put $python:load-project~ + } +] + +fn -from-descriptor-name { |descriptor-name| + console:inspect 'Requested descriptor' $descriptor-name + + var requested-retriever = (map:get-value $-loader-retrievers $descriptor-name) + + if $requested-retriever { + console:inspect &emoji=📤 'Fetching the requested loader for' $descriptor-name + + var loader = ($requested-retriever) + put $loader + } else { + console:echo 🎁 Unknown technology found! + + use ./unknown + put { unknown:load-project $descriptor-name } + } +} + +fn -infer-from-files { + console:echo 🔎 Now looking for a supported descriptor... + + keys $-loader-retrievers | each { |current-descriptor-name| + if (os:is-regular $current-descriptor-name) { + console:inspect &emoji=🌟 'Descriptor found' $current-descriptor-name + + var loader = ($-loader-retrievers[$current-descriptor-name]) + put $loader + + return + } + } + + fail 'Unknown technology found - and no descriptor name was specified!' +} + +fn load { |&descriptor-name=$nil| + var loader-retriever = (lang:ternary $descriptor-name { -from-descriptor-name $descriptor-name } { -infer-from-files }) + + var loader = ($loader-retriever) + + $loader +} \ No newline at end of file diff --git a/core/project/maven.elv b/core/project/maven.elv new file mode 100644 index 000000000..1dbf58797 --- /dev/null +++ b/core/project/maven.elv @@ -0,0 +1,16 @@ +use ./base +use ./descriptors/xml + +fn load-project { + base:load-project [ + &descriptor-namespace=$xml: + + &descriptor-name=pom.xml + + &technology=Maven + + &build-tool=mvn + + &emoji=🪶 + ] +} diff --git a/core/project/nodejs.elv b/core/project/nodejs.elv new file mode 100644 index 000000000..fa09f264e --- /dev/null +++ b/core/project/nodejs.elv @@ -0,0 +1,16 @@ +use ./base +use ./descriptors/json + +fn load-project { + base:load-project [ + &descriptor-namespace=$json: + + &descriptor-name=package.json + + &technology=NodeJS + + &build-tool=pnpm + + &emoji=📦 + ] +} diff --git a/core/project/python.elv b/core/project/python.elv new file mode 100644 index 000000000..6da4436db --- /dev/null +++ b/core/project/python.elv @@ -0,0 +1,16 @@ +use ./base +use ./descriptors/toml + +fn load-project { + base:load-project [ + &descriptor-namespace=$toml: + + &descriptor-name=pyproject.toml + + &technology=Python + + &build-tool=pdm + + &emoji=🐍 + ] +} diff --git a/core/project/rust.elv b/core/project/rust.elv new file mode 100644 index 000000000..d1cfa3139 --- /dev/null +++ b/core/project/rust.elv @@ -0,0 +1,16 @@ +use ./base +use ./descriptors/toml + +fn load-project { + base:load-project [ + &descriptor-namespace=$toml: + + &descriptor-name=Cargo.toml + + &technology=Rust + + &build-tool=cargo + + &emoji=🦀 + ] +} diff --git a/core/project/unknown.elv b/core/project/unknown.elv new file mode 100644 index 000000000..2c56c5ea0 --- /dev/null +++ b/core/project/unknown.elv @@ -0,0 +1,16 @@ +use ./base +use ./descriptors/plain-text + +fn load-project { |descriptor-name| + base:load-project [ + &descriptor-namespace=$plain-text: + + &descriptor-name=$descriptor-name + + &technology=Unknown + + &build-tool=$nil + + &emoji=🎁 + ] +} diff --git a/core/python/context.elv b/core/python/context.elv new file mode 100644 index 000000000..dc52d280c --- /dev/null +++ b/core/python/context.elv @@ -0,0 +1,19 @@ +use os +use github.com/giancosta86/aurora-elvish/console +use ./pdm + +fn -check-preconditions { + if (not (os:is-regular pyproject.toml)) { + fail 'The pyproject.toml descriptor is missing!' + } +} + +fn setup { |&pdm-version=$nil| + console:echo 🐍💻 Setting up Python context in "'"$pwd"'"... + + -check-preconditions + + pdm:ensure &version=$pdm-version + + console:echo ✅🐍 NodeJS context in "'"$pwd"'" ready! +} \ No newline at end of file diff --git a/core/python/core/check_action_references.py b/core/python/core/check_action_references.py deleted file mode 100644 index d88409246..000000000 --- a/core/python/core/check_action_references.py +++ /dev/null @@ -1,44 +0,0 @@ -from os import getenv - -from .detect_branch_version import detect_branch_version_info -from .exceptions import AuroraException -from .inputs import InputDto -from .processes import shell_run - - -class Inputs(InputDto): - actions_directory: str - - -def check_action_references(inputs: Inputs) -> None: - branch = detect_branch_version_info().branch - if not branch: - raise AuroraException("Cannot detect the branch!") - - print(f"🌲Current branch: '{branch}'") - - full_repo = getenv("GITHUB_REPOSITORY") - if not full_repo: - raise AuroraException("Cannot detect the full repository name!") - - print(f"🧭Full repository name: '{full_repo}'") - - reference_to_another_branch_regex = rf"uses:\s*{full_repo}[^@]+@(?!{branch})" - - grep_result = shell_run( - f"grep --color=always -P '{reference_to_another_branch_regex}' **/*.yml", - check=False, - cwd=inputs.actions_directory, - ) - - match grep_result.returncode: - case 0: - raise AuroraException( - f"There are references to actions within '{ inputs.actions_directory }' residing in other branches!" - ) - - case 1: - print("✅No cross-branch action references detected!") - - case _: - raise AuroraException("Error while invoking grep!") diff --git a/core/python/core/detect_branch_version.py b/core/python/core/detect_branch_version.py deleted file mode 100644 index 82d070d7f..000000000 --- a/core/python/core/detect_branch_version.py +++ /dev/null @@ -1,44 +0,0 @@ -import re -from dataclasses import dataclass -from os import getenv -from pathlib import Path - -from .exceptions import AuroraException -from .outputs import OutputDto - -leading_v = re.compile("^v") - - -@dataclass(frozen=True) -class BranchVersionInfo(OutputDto): - branch: str - version: str - escaped_version: str - major: str - - -def detect_branch_version_info() -> BranchVersionInfo: - head_ref = getenv("GITHUB_HEAD_REF") - ref = getenv("GITHUB_REF") - - retrieved_branch = head_ref if head_ref else ref - if not retrieved_branch: - raise AuroraException("Cannot detect the branch!") - - print(f"🌳Retrieved Git branch name: '{retrieved_branch}'") - - branch = retrieved_branch.replace("refs/heads/", "") - - print(f"🌲Current Git branch: '{branch}'") - - version = leading_v.sub("", Path(branch).name) - print(f"🦋Detected version: '{version}'") - - escaped_version = re.escape(version) - print(f"🧵Escaped version: '{escaped_version}'") - - major = version.split(".")[0].split("-")[0].split("+")[0] - - return BranchVersionInfo( - branch=branch, version=version, escaped_version=escaped_version, major=major - ) diff --git a/core/python/core/directories.py b/core/python/core/directories.py deleted file mode 100644 index 83d8ccd52..000000000 --- a/core/python/core/directories.py +++ /dev/null @@ -1,14 +0,0 @@ -from contextlib import contextmanager -from os import chdir, getcwd - - -@contextmanager -def switch_to(target_path): - previous_path = getcwd() - - chdir(target_path) - - try: - yield - finally: - chdir(previous_path) diff --git a/core/python/core/enforce_branch_version.py b/core/python/core/enforce_branch_version.py deleted file mode 100644 index 401d2c328..000000000 --- a/core/python/core/enforce_branch_version.py +++ /dev/null @@ -1,91 +0,0 @@ -from pathlib import Path -from typing import Optional - -from .detect_branch_version import detect_branch_version_info -from .exceptions import AuroraException -from .inputs import InputDto -from .projects import Project, UnknownProject, detect_project - - -class Inputs(InputDto): - mode: str - artifact_descriptor: Optional[str] - project_directory: str - - -def _detect_project(inputs: Inputs) -> Project: - project = detect_project(Path(inputs.project_directory), inputs.artifact_descriptor) - print(f"🔮Detected project: {project}") - - return project - - -def enforce_branch_version(inputs: Inputs) -> None: - match inputs.mode: - case "inject": - project = _detect_project(inputs) - strategy = lambda: _inject(project) - - case "check": - project = _detect_project(inputs) - strategy = lambda: _check(project) - - case "skip": - strategy = _skip - - case _: - raise AuroraException(f"Invalid value for 'mode' input: '{inputs.mode}'!") - - strategy() - - -def _inject(project: Project) -> None: - version = detect_branch_version_info().version - - print(f"🧬Injecting the branch version into {project}...") - - descriptor_file_content = project.descriptor_path.read_text() - - updated_content = descriptor_file_content.replace("0.0.0", version) - - project.descriptor_path.write_text(updated_content) - - print("✅Version injected!") - - project.print_descriptor() - - -def _check(project: Project) -> None: - project.print_descriptor() - - branch_version = detect_branch_version_info().version - - if isinstance(project, UnknownProject): - print(f"🌲Branch version: '{branch_version}'") - - print(f"🔎Ensuring the branch version exists in {project}...") - - version_found = branch_version in project.descriptor_path.read_text() - - if version_found: - print("✅Version found in the descriptor!") - else: - raise AuroraException( - "The branch version cannot be found in the artifact descriptor!" - ) - else: - artifact_version = project.read_version() - - print(f"🌲Branch version: '{branch_version}'") - print(f"🔎Artifact version: '{artifact_version}'") - - if branch_version == artifact_version: - print("✅The descriptor version matches the branch version!") - else: - raise AuroraException( - "The descriptor version and the branch version do not match!" - ) - - -def _skip() -> None: - print("💭Skipping branch version enforcement, as requested...") diff --git a/core/python/core/exceptions.py b/core/python/core/exceptions.py deleted file mode 100644 index 1b4297980..000000000 --- a/core/python/core/exceptions.py +++ /dev/null @@ -1,3 +0,0 @@ -class AuroraException(Exception): - def __init__(self, message): - super().__init__(f"❌{message}") diff --git a/core/python/core/extract_rust_snippets.py b/core/python/core/extract_rust_snippets.py deleted file mode 100644 index 63192e824..000000000 --- a/core/python/core/extract_rust_snippets.py +++ /dev/null @@ -1,82 +0,0 @@ -import re -from pathlib import Path -from sys import exit - -from .directories import switch_to -from .exceptions import AuroraException -from .inputs import InputDto - -_snippet_pattern = re.compile(r"``rust\s*(.*?)\s*```", re.DOTALL) - -_test_bootstrap_code = """ - -#[test] -fn run_code_snippet() { - main().unwrap(); -} -""" - - -class Inputs(InputDto): - markdown_file: str - optional: str - test_filename_prefix: str - project_directory: str - - -def extract_rust_snippets(inputs: Inputs) -> None: - with switch_to(inputs.project_directory): - markdown_path = Path(inputs.markdown_file) - - _check_markdown_file( - markdown_path=markdown_path, optional=inputs.optional == "true" - ) - - _extract_snippets_to_files( - markdown_path=markdown_path, - test_filename_prefix=inputs.test_filename_prefix, - ) - - -def _check_markdown_file(markdown_path: Path, optional: bool) -> None: - if markdown_path.is_file(): - print(f"🗒️{markdown_path} found!") - return - - if optional: - print(f"💭{markdown_path} not found - cannot extract snippets.") - exit(0) - - raise AuroraException(f"Missing source Markdown file: '{markdown_path}'!") - - -def _extract_snippets_to_files(markdown_path: Path, test_filename_prefix: str) -> None: - test_directory_path = Path(test_filename_prefix).parent - print(f"📁Ensuring test directory: '{test_directory_path}'") - test_directory_path.mkdir(parents=True) - print("✅Test directory ready!") - - generated_test_paths = [] - - print("🔁Trying to extract tests from Rust snippets in Markdown...") - for index, matcher in enumerate( - re.finditer(_snippet_pattern, markdown_path.read_text()) - ): - snippet = matcher.group(1) - updated_snippet = snippet + _test_bootstrap_code - - snippet_path = Path(f"{test_filename_prefix}{index + 1}.rs") - - snippet_path.write_text(updated_snippet) - - generated_test_paths.append(snippet_path) - - if generated_test_paths: - print("🎩Process completed! Generated test files:") - - for test_path in generated_test_paths: - print(test_path) - - print("🎩🎩🎩") - else: - print("💭No snippets found in the source Markdown file...") diff --git a/core/python/core/inputs.py b/core/python/core/inputs.py deleted file mode 100644 index faf7f9b58..000000000 --- a/core/python/core/inputs.py +++ /dev/null @@ -1,45 +0,0 @@ -from os import getenv -from typing import Union, get_args, get_origin, get_type_hints - -from .exceptions import AuroraException - - -class Input: - @staticmethod - def get(input_name: str) -> str: - source_env_var = f"INPUT_{input_name.upper().replace('-', '_')}" - - input_value = getenv(source_env_var, "") - - print(f"📥{input_name}: '{input_value}'") - - return input_value - - @staticmethod - def require(input_name: str) -> str: - value = Input.get(input_name) - - if not value: - raise AuroraException(f"Missing action input: '{input_name}'!") - - return value - - -class InputDto: - @classmethod - def from_env(cls): - instance = cls() - instance.set_fields_from_env() - return instance - - def set_fields_from_env(self) -> None: - for field_name, field_type in get_type_hints(type(self)).items(): - optional = get_origin(field_type) == Union and type(None) in get_args( - field_type - ) - - value_retriever = Input.get if optional else Input.require - - input_value = value_retriever(field_name) - - setattr(self, field_name, input_value) diff --git a/core/python/core/jvm.py b/core/python/core/jvm.py deleted file mode 100644 index 87dbba9bb..000000000 --- a/core/python/core/jvm.py +++ /dev/null @@ -1,28 +0,0 @@ -from dataclasses import dataclass -from pathlib import Path - -from .exceptions import AuroraException -from .inputs import InputDto -from .outputs import OutputDto -from .projects import Project, detect_project - - -class Inputs(InputDto): - project_directory: str - - -@dataclass(frozen=True) -class Outputs(OutputDto): - build_tool: str - descriptor: str - - -def get_jvm_build_tool(inputs: Inputs) -> Outputs: - project = detect_project(Path(inputs.project_directory)) - - build_tool = project.build_tool - - if build_tool not in ["mvn", "gradle"]: - raise AuroraException("No available JVM build tool for this project!") - - return Outputs(build_tool=build_tool, descriptor=project.descriptor_name) diff --git a/core/python/core/outputs.py b/core/python/core/outputs.py deleted file mode 100644 index bf5d05056..000000000 --- a/core/python/core/outputs.py +++ /dev/null @@ -1,50 +0,0 @@ -import re -from os import getenv -from typing import Callable, Optional, get_type_hints - -from .exceptions import AuroraException - -UNDERSCORE_TO_UPPERCASE_REGEX = re.compile(r"_([^_])") - - -class OutputDto: - def write_to_github_output(self) -> None: - self._write_to_cicd_context( - "GITHUB_OUTPUT", lambda source_field: source_field.replace("_", "-") - ) - - def write_to_github_env(self) -> None: - self._write_to_cicd_context( - "GITHUB_ENV", - lambda source_field: re.sub( - UNDERSCORE_TO_UPPERCASE_REGEX, - lambda m: m.group(1).upper(), - source_field, - ), - ) - - def _write_to_cicd_context( - self, - context_name: str, - to_context_field_name_converter: Callable[[str], str], - ) -> None: - source_fields = get_type_hints(type(self)).keys() - - env_file = getenv(context_name) - if not env_file: - raise AuroraException( - f"Cannot find a file associated with the '{context_name}' context" - ) - - print(f"✒️Writing fields in the '{context_name}' context...") - with open(env_file, "a") as github_context: - for source_field in source_fields: - context_field_name = to_context_field_name_converter(source_field) - context_field_value = getattr(self, source_field) - - print( - f"📤Setting context name '{context_field_name}' = '{context_field_value}'" - ) - - github_context.write(f"{context_field_name}={context_field_value}\n") - print(f"✒️✒️✒️") diff --git a/core/python/core/parse_npm_scope.py b/core/python/core/parse_npm_scope.py deleted file mode 100644 index ef9491e53..000000000 --- a/core/python/core/parse_npm_scope.py +++ /dev/null @@ -1,25 +0,0 @@ -from dataclasses import dataclass - -from .inputs import InputDto -from .outputs import OutputDto - - -class Inputs(InputDto): - scope: str - - -@dataclass(frozen=True) -class ScopeResult(OutputDto): - actual_scope: str - - -def parse_npm_scope(inputs: Inputs) -> ScopeResult: - if inputs.scope == "": - print("🫚Root npm scope detected!") - return ScopeResult(actual_scope="") - - actual_scope = inputs.scope.lstrip("@") - - print(f"🖌️Custom npm scope detected: '{actual_scope}'") - - return ScopeResult(actual_scope=actual_scope) diff --git a/core/python/core/processes.py b/core/python/core/processes.py deleted file mode 100644 index dd5e0fbf9..000000000 --- a/core/python/core/processes.py +++ /dev/null @@ -1,22 +0,0 @@ -import subprocess -import sys -from typing import Union - - -def shell_run(command: Union[str, list[str]], **kwargs) -> subprocess.CompletedProcess: - print(f"🚀Running shell command: {command}") - - kwargs["shell"] = True - - if not kwargs.get("capture_output"): - sys.stdout.flush() - sys.stderr.flush() - - return subprocess.run(command, **kwargs) - - -def text_run(command: Union[str, list[str]], **kwargs) -> subprocess.CompletedProcess: - kwargs["text"] = True - kwargs["capture_output"] = True - - return shell_run(command, **kwargs) diff --git a/core/python/core/projects/__init__.py b/core/python/core/projects/__init__.py deleted file mode 100644 index 4ec8c4d64..000000000 --- a/core/python/core/projects/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -from .base import Project -from .detect import detect_project -from .unknown import UnknownProject diff --git a/core/python/core/projects/base.py b/core/python/core/projects/base.py deleted file mode 100644 index 4fa56a172..000000000 --- a/core/python/core/projects/base.py +++ /dev/null @@ -1,62 +0,0 @@ -from abc import ABCMeta, abstractmethod -from pathlib import Path -from typing import Optional - -from ..exceptions import AuroraException - - -class Project(metaclass=ABCMeta): - def __init__(self, directory: Path): - self._directory = directory - - @property - def directory(self) -> Path: - return self._directory - - @property - @abstractmethod - def technology(self) -> str: - pass - - @property - @abstractmethod - def emoji(self) -> str: - pass - - @property - @abstractmethod - def descriptor_name(self) -> str: - pass - - @property - def descriptor_path(self) -> Path: - return self.directory / self.descriptor_name - - def print_descriptor(self) -> None: - print(f"{self.emoji}{self.descriptor_name} content:") - self._print_descriptor_content() - print(self.emoji * 3) - - def _print_descriptor_content(self) -> None: - descriptor_content = self.descriptor_path.read_text() - print(descriptor_content) - - def read_version(self) -> str: - version = self._read_version() - - if not version: - raise AuroraException(f"Cannot detect version for {self}") - - return version - - @abstractmethod - def _read_version(self) -> Optional[str]: - pass - - @property - @abstractmethod - def build_tool(self) -> str: - pass - - def __str__(self): - return f"{self.emoji}{self.technology}({self.descriptor_name})" diff --git a/core/python/core/projects/detect.py b/core/python/core/projects/detect.py deleted file mode 100644 index 80f5b453f..000000000 --- a/core/python/core/projects/detect.py +++ /dev/null @@ -1,69 +0,0 @@ -from pathlib import Path -from typing import Optional - -from ..exceptions import AuroraException -from .base import Project - -NODEJS_DESCRIPTOR_NAME = "package.json" - -RUST_DESCRIPTOR_NAME = "Cargo.toml" - -MAVEN_DESCRIPTOR_NAME = "pom.xml" - -GRADLE_DESCRIPTOR_NAMES = ["build.gradle", "build.gradle.kts"] - -PYTHON_DESCRIPTOR_NAME = "pyproject.toml" - - -def detect_project( - project_directory: Path, descriptor_name: Optional[str] = None -) -> Project: - if ( - descriptor_name == NODEJS_DESCRIPTOR_NAME - or (project_directory / NODEJS_DESCRIPTOR_NAME).is_file() - ): - from .nodejs import NodeJsProject - - return NodeJsProject(project_directory) - - if ( - descriptor_name == RUST_DESCRIPTOR_NAME - or (project_directory / RUST_DESCRIPTOR_NAME).is_file() - ): - from .rust import RustProject - - return RustProject(project_directory) - - if ( - descriptor_name == MAVEN_DESCRIPTOR_NAME - or (project_directory / MAVEN_DESCRIPTOR_NAME).is_file() - ): - from .maven import MavenProject - - return MavenProject(project_directory) - - for gradle_descriptor_name in GRADLE_DESCRIPTOR_NAMES: - if ( - descriptor_name == gradle_descriptor_name - or (project_directory / gradle_descriptor_name).is_file() - ): - from .gradle import GradleProject - - return GradleProject(project_directory, gradle_descriptor_name) - - if ( - descriptor_name == PYTHON_DESCRIPTOR_NAME - or (project_directory / PYTHON_DESCRIPTOR_NAME).is_file() - ): - from .python import PythonProject - - return PythonProject(project_directory) - - from .unknown import UnknownProject - - if not descriptor_name: - raise AuroraException( - "Descriptor file name must be specified for unknown technology!" - ) - - return UnknownProject(project_directory, descriptor_name) diff --git a/core/python/core/projects/gradle.py b/core/python/core/projects/gradle.py deleted file mode 100644 index 250b2c793..000000000 --- a/core/python/core/projects/gradle.py +++ /dev/null @@ -1,39 +0,0 @@ -import re -from pathlib import Path -from typing import Optional - -from .base import Project - - -class GradleProject(Project): - _version_regex = re.compile(r"""^version\s*=\s*["'](.*)["']""") - - def __init__(self, directory: Path, descriptor_name: str): - super().__init__(directory) - self._descriptor_name = descriptor_name - - @property - def technology(self) -> str: - return "Gradle" - - @property - def emoji(self) -> str: - return "🐘" - - @property - def descriptor_name(self) -> str: - return self._descriptor_name - - @property - def build_tool(self) -> str: - return "gradle" - - def _read_version(self) -> Optional[str]: - with self.descriptor_path.open() as descriptor: - for line in descriptor: - matcher = self._version_regex.match(line) - - if matcher: - return matcher.group(1) - - return None diff --git a/core/python/core/projects/maven.py b/core/python/core/projects/maven.py deleted file mode 100644 index f79456f3c..000000000 --- a/core/python/core/projects/maven.py +++ /dev/null @@ -1,34 +0,0 @@ -import xml.etree.ElementTree as ET -from typing import Optional - -from ..exceptions import AuroraException -from .base import Project - - -class MavenProject(Project): - @property - def technology(self) -> str: - return "Maven" - - @property - def emoji(self) -> str: - return "🪶" - - @property - def descriptor_name(self) -> str: - return "pom.xml" - - @property - def build_tool(self) -> str: - return "mvn" - - def _read_version(self) -> Optional[str]: - tree = ET.parse(self.descriptor_path) - root = tree.getroot() - namespaces = {"mvn": root.tag.split("}")[0].strip("{}")} - - version_tag = root.find(".//mvn:version", namespaces) - if version_tag is None: - raise AuroraException("Cannot find the tag!") - - return version_tag.text diff --git a/core/python/core/projects/nodejs.py b/core/python/core/projects/nodejs.py deleted file mode 100644 index 2c0604828..000000000 --- a/core/python/core/projects/nodejs.py +++ /dev/null @@ -1,34 +0,0 @@ -import json -import sys -from subprocess import run -from typing import Optional - -from .base import Project - - -class NodeJsProject(Project): - @property - def technology(self) -> str: - return "NodeJS" - - @property - def emoji(self) -> str: - return "📦" - - @property - def descriptor_name(self) -> str: - return "package.json" - - def _read_version(self) -> Optional[str]: - descriptor_json = json.loads(self.descriptor_path.read_text()) - - return descriptor_json["version"] - - def _print_descriptor_content(self): - sys.stdout.flush() - sys.stderr.flush() - run(["jq", "-C", ".", self.descriptor_path]) - - @property - def build_tool(self) -> str: - return "pnpm" diff --git a/core/python/core/projects/python.py b/core/python/core/projects/python.py deleted file mode 100644 index d0a3e7425..000000000 --- a/core/python/core/projects/python.py +++ /dev/null @@ -1,22 +0,0 @@ -import re -from typing import Optional - -from .toml import TomlProject - - -class PythonProject(TomlProject): - @property - def technology(self) -> str: - return "Python" - - @property - def emoji(self) -> str: - return "🐍" - - @property - def descriptor_name(self) -> str: - return "pyproject.toml" - - @property - def build_tool(self) -> str: - return "pdm" diff --git a/core/python/core/projects/rust.py b/core/python/core/projects/rust.py deleted file mode 100644 index 31eac4c3f..000000000 --- a/core/python/core/projects/rust.py +++ /dev/null @@ -1,22 +0,0 @@ -import re -from typing import Optional - -from .toml import TomlProject - - -class RustProject(TomlProject): - @property - def technology(self) -> str: - return "Rust" - - @property - def emoji(self) -> str: - return "🦀" - - @property - def descriptor_name(self) -> str: - return "Cargo.toml" - - @property - def build_tool(self) -> str: - return "cargo" diff --git a/core/python/core/projects/toml.py b/core/python/core/projects/toml.py deleted file mode 100644 index fad3dd87a..000000000 --- a/core/python/core/projects/toml.py +++ /dev/null @@ -1,18 +0,0 @@ -import re -from typing import Optional - -from .base import Project - - -class TomlProject(Project): - _version_regex = re.compile(r"""^version\s*=\s*["'](.*)["']""") - - def _read_version(self) -> Optional[str]: - with self.descriptor_path.open() as descriptor: - for line in descriptor: - matcher = self._version_regex.match(line) - - if matcher: - return matcher.group(1) - - return None diff --git a/core/python/core/projects/unknown.py b/core/python/core/projects/unknown.py deleted file mode 100644 index 58d169651..000000000 --- a/core/python/core/projects/unknown.py +++ /dev/null @@ -1,31 +0,0 @@ -from pathlib import Path -from typing import Optional - -from ..exceptions import AuroraException -from .base import Project - - -class UnknownProject(Project): - def __init__(self, directory: Path, descriptor_name: str): - super().__init__(directory) - - self._descriptor_name = descriptor_name - - @property - def technology(self) -> str: - return "Unknown" - - @property - def emoji(self) -> str: - return "🎁" - - @property - def descriptor_name(self) -> str: - return self._descriptor_name - - def _read_version(self) -> Optional[str]: - return None - - @property - def build_tool(self) -> str: - raise AuroraException("No build tool for unknown project") diff --git a/core/python/pdm.elv b/core/python/pdm.elv new file mode 100644 index 000000000..740a8ffe9 --- /dev/null +++ b/core/python/pdm.elv @@ -0,0 +1,27 @@ +use re +use github.com/giancosta86/aurora-elvish/console +use ./pipx + +fn -install { |version| + pipx:install-package &version=$version pdm +} + +fn ensure { |&version=$nil| + if (not (has-external pdm)) { + console:echo 💬 pdm is not available: now installing it! + -install $version + return + } + + console:echo 🌟 pdm is already installed! + + var installed-version = (pdm --version) + console:inspect 'Installed pdm version' $installed-version + + if (and $version (re:match '\b'$version'\b' installed-version )) { + console:echo ✅ The requested pdm version is already installed! + return + } + + -install $version +} \ No newline at end of file diff --git a/core/python/pipx.elv b/core/python/pipx.elv new file mode 100644 index 000000000..847f7c7a1 --- /dev/null +++ b/core/python/pipx.elv @@ -0,0 +1,19 @@ +use github.com/giancosta86/aurora-elvish/console + +fn install-package { |package &version=$nil| + console:echo 📥 Installing $package via pipx... + + var version-suffix + + if $version { + console:inspect &emoji=🏷 'Requested version' $version + set version-suffix = '=='$version + } else { + console:echo 🌟 Installing the latest version + set version-suffix = '' + } + + pipx install $package''$version-suffix + + console:echo ✅ $package installed! +} \ No newline at end of file diff --git a/core/python/project.elv b/core/python/project.elv new file mode 100644 index 000000000..cd9a1e0aa --- /dev/null +++ b/core/python/project.elv @@ -0,0 +1,23 @@ +use github.com/giancosta86/aurora-elvish/console + +fn verify { + console:echo 🔬 Verifying the project... + pdm run verify + console:echo ✅ Project verified! +} + +fn build { + console:echo 📦 Building the project... + pdm build + console:echo ✅ Project built successfully! +} + +fn publish { |dry-run| + if $dry-run { + console:echo 💭 dry-run is enabled: just building the 🐍 Python project... + pdm build + } else { + console:echo 📤 Publishing the 🐍 Python package... + pdm publish + } +} \ No newline at end of file diff --git a/core/rust/context.elv b/core/rust/context.elv new file mode 100644 index 000000000..2680a529d --- /dev/null +++ b/core/rust/context.elv @@ -0,0 +1,72 @@ +use os +use ../ci-cd/env +use github.com/giancosta86/aurora-elvish/command +use github.com/giancosta86/aurora-elvish/console +use github.com/giancosta86/aurora-elvish/lang + +fn -check-preconditions { + if (not (os:is-regular Cargo.toml)) { + fail 'The Cargo.toml descriptor is missing!' + } + + if (not (has-external cargo)) { + fail 'Some version of Cargo must be installed!' + } + + if (not (has-external rustup)) { + fail 'Some version of rustup must be installed!' + } +} + +fn -set-cargo-colors { |enabled| + var key = CARGO_TERM_COLOR + var value = (lang:ternary $enabled always never) + + set-env $key $value + env:write $key $value +} + +fn -check-toolchain-file { + var toolchain-file = rust-toolchain.toml + + if (os:is-regular $toolchain-file) { + console:inspect &emoji=✅ 'Toolchain file found' $toolchain-file + } else { + fail "Missing toolchain file: '"$toolchain-file"'" + } +} + +fn -ensure-required-components { + command:silence { + cargo --version + + rustup component add rustfmt clippy + } +} + +fn -print-component-versions { + console:section &emoji=🦀 'Rust component versions' { + cargo --version + rustc --version + cargo fmt --version + cargo clippy --version + } +} + +fn setup { |&cargo-colors=$true &check-toolchain-file=$true| + console:echo 🦀💻 Setting up Rust context in "'"$pwd"'"... + + -check-preconditions + + -set-cargo-colors $cargo-colors + + if $check-toolchain-file { + -check-toolchain-file + } + + -ensure-required-components + + -print-component-versions + + console:echo ✅🦀 Rust context in "'"$pwd"'" ready! +} diff --git a/core/rust/crate.elv b/core/rust/crate.elv new file mode 100644 index 000000000..a2a4d8887 --- /dev/null +++ b/core/rust/crate.elv @@ -0,0 +1,7 @@ +use github.com/giancosta86/aurora-elvish/lang + +fn publish { |dry-run| + var dry-run-arg = (lang:ternary $dry-run [--dry-run] []) + + cargo publish --all-features --allow-dirty $@dry-run-arg +} \ No newline at end of file diff --git a/core/rust/project.elv b/core/rust/project.elv new file mode 100644 index 000000000..32add2e4d --- /dev/null +++ b/core/rust/project.elv @@ -0,0 +1,76 @@ +use str +use github.com/giancosta86/aurora-elvish/console +use github.com/giancosta86/aurora-elvish/edit + +fn -check-format { + console:echo 🎨 Checking source code format... + cargo fmt --check + console:echo ✅ Source code format OK! +} + +fn -run-clippy-checks { + console:echo 📎 Running clippy checks... + cargo clippy --all-targets --all-features -- -D warnings + console:echo ✅ Clippy checks OK! +} + +fn -check-rustdoc { + console:echo 📚 Building rustdoc documentation with all the features enabled... + + tmp E:RUSTDOCFLAGS = '-D warnings' + + cargo doc --all-features + + console:echo ✅ Documentation built successfully! +} + +fn check-style { |&run-clippy-checks=$true &check-rustdoc=$true| + -check-format + + if $run-clippy-checks { + -run-clippy-checks + } + + if $check-rustdoc { + -check-rustdoc + } +} + +fn -run-vanilla-tests { + console:echo 🔬 Running tests with no features enabled... + cargo test + console:echo ✅ Tests with no features OK! +} + +fn -run-tests-with-all-features { + console:echo 🔬 Running tests with all the features enabled... + cargo test --all-features + console:echo ✅ Tests with all the features OK! +} + +fn run-tests { + -run-vanilla-tests + + -run-tests-with-all-features +} + +fn document-all-features { + edit:file Cargo.toml { |content| + var docs-header = '[package.metadata.docs.rs]' + + if (str:contains $content $docs-header) { + console:echo 💬 Skipping documentation addendum because $docs-header already appears in Cargo.toml... + + put $nil + } else { + console:echo 📚 Now adding the "'"all-features = true"'" documentation addendum to the project descriptor! + + var descriptor-addendum = (str:join "\n" [ + $docs-header + 'all-features = true' + ]) + + put (str:trim-space $content)"\n\n"$descriptor-addendum + } + } +} \ No newline at end of file diff --git a/core/rust/snippets.elv b/core/rust/snippets.elv new file mode 100644 index 000000000..43b2bde3a --- /dev/null +++ b/core/rust/snippets.elv @@ -0,0 +1,82 @@ +use os +use path +use re +use str +use github.com/giancosta86/aurora-elvish/console +use github.com/giancosta86/aurora-elvish/seq + +var -snippet-pattern = '(?s)```rust\s+(.*?)```' + +fn -get-test-bootstrap-code { |ordinal| + str:join "\n" [ + '#[test]' + 'fn run_code_snippet_'$ordinal'() {' + ' main().unwrap();' + '}' + ] +} + +fn -ensure-test-directory { |snippet-path| + var test-directory = (path:dir $snippet-path) + + if (not (os:is-dir $test-directory)) { + console:inspect &emoji=📁 'Creating test directory' $test-directory + os:mkdir-all $test-directory + console:echo ✅ Test directory ready! + } +} + +fn -extract-snippets-to-files { |markdown-path test-filename-prefix| + var test-directory = (path:dir $test-filename-prefix) + var generated-test-paths = [] + + console:echo 🎩 Trying to extract tests from Rust snippets in Markdown... + + slurp < $markdown-path | re:find $-snippet-pattern (all) | seq:enumerate { |index match| + var snippet = (str:trim-space $match[groups][1][text]) + + var ordinal = (+ $index 1) + + var test-bootstrap-code = (-get-test-bootstrap-code $ordinal) + + var updated-snippet = $snippet"\n\n"$test-bootstrap-code + + var snippet-path = $test-filename-prefix''$ordinal'.rs' + + -ensure-test-directory $snippet-path + + echo $updated-snippet > $snippet-path + + set generated-test-paths = (conj $generated-test-paths $snippet-path) + } + + if (seq:is-non-empty $generated-test-paths) { + console:section &emoji=🎩 'Process completed! Generated test files' { + for test-path $generated-test-paths { + console:echo 📄 $test-path + } + } + } else { + console:echo 💭 No snippets found in the source Markdown file... + } +} + +fn extract { |inputs| + console:inspect-inputs $inputs + + var markdown-path = $inputs[markdown-path] + var optional = $inputs[optional] + var test-filename-prefix = $inputs[test-filename-prefix] + + if $markdown-path { + console:inspect &emoji=🗒️ 'Source markdown found' $markdown-path + + -extract-snippets-to-files $markdown-path $test-filename-prefix + } else { + if $optional { + console:echo 💭 Source markdown path not found - cannot extract snippets + } else { + fail 'Missing source Markdown file!' + } + } +} \ No newline at end of file diff --git a/core/rust/wasm-pack.elv b/core/rust/wasm-pack.elv new file mode 100644 index 000000000..6a2207da8 --- /dev/null +++ b/core/rust/wasm-pack.elv @@ -0,0 +1,98 @@ +use os +use github.com/giancosta86/aurora-elvish/console +use github.com/giancosta86/aurora-elvish/edit +use github.com/giancosta86/aurora-elvish/lang +use ../nodejs/pnpm +use ../project/descriptors/json + +fn install { |version| + console:echo 🌐 Installing wasm-pack $version... + + npm install -g 'wasm-pack@'$version + + console:echo ✅ wasm-pack installed! +} + +fn -run { |inputs| + console:echo 📦 Generating the WebAssembly project files... + + var target = $inputs[target] + var npm-scope = $inputs[npm-scope] + var development = $inputs[development] + var target-directory = $inputs[target-directory] + + var mode-arg = ( + lang:ternary $development '--dev' '--release' + ) + + var actual-npm-scope = (pnpm:parse-scope $npm-scope) + + var npm-scope-args = ( + lang:ternary $actual-npm-scope ['--scope' $actual-npm-scope] [] + ) + + wasm-pack build --target $target $mode-arg $@npm-scope-args --out-dir $target-directory +} + +fn -inject-nodejs-version { |nodejs-version| + if (not (os:is-regular package.json)) { + fail 'package.json was not generated for this target - cannot inject the requested NodeJS version!' + } + + console:inspect &emoji=🧬 'Injecting the requested NodeJS version' $nodejs-version + + edit:json package.json '.engines.node = "'$nodejs-version'"' +} + +fn -inject-pnpm-version { |pnpm-version| + if (not (os:is-regular package.json)) { + fail 'package.json was not generated for this target - cannot inject the requested pnpm version!' + } + + console:inspect &emoji=🧬 'Injecting the requested pnpm version' $pnpm-version + + edit:json package.json '.packageManager = "pnpm@'$pnpm-version'"' +} + +fn -try-to-display-package-json { |target| + if (os:is-regular package.json) { + console:section &emoji=📦 'Generated package.json descriptor for the '''$target''' target' { + json:print-content package.json + } + } else { + console:echo 💭 No package.json descriptor generated for the "'"$target"'" target... + } +} + +fn run-browser-tests { + console:echo 🌐 Running headless browser tests... + + wasm-pack test --chrome --headless --release + + console:echo ✅ Headless browser tests OK! +} + +fn generate-target { |inputs| + console:inspect-inputs $inputs + + -run $inputs + + var target = $inputs[target] + var nodejs-version = $inputs[nodejs-version] + var pnpm-version = $inputs[pnpm-version] + var target-directory = $inputs[target-directory] + + tmp pwd = $target-directory + + if $nodejs-version { + -inject-nodejs-version $nodejs-version + } + + if $pnpm-version { + -inject-pnpm-version $pnpm-version + } + + -try-to-display-package-json $target + + console:inspect &emoji=✅ 'WebAssembly target ready in' $target-directory +} \ No newline at end of file diff --git a/core/rust/wasm.elv b/core/rust/wasm.elv new file mode 100644 index 000000000..faaa090d6 --- /dev/null +++ b/core/rust/wasm.elv @@ -0,0 +1,13 @@ +use os +use github.com/giancosta86/aurora-elvish/console +use github.com/giancosta86/aurora-elvish/fs + +fn copy-npmrc-from-project-directory { + if (os:is-regular .npmrc) { + console:echo 🎉 Root .npmrc configuration file found! Copying it to the package directory... + fs:copy .npmrc pkg/ + console:echo ✅ .npmrc file copied! + } else { + console:echo 💭 No .npmrc configuration file found in the project directory... + } +} diff --git a/core/script.elv b/core/script.elv new file mode 100644 index 000000000..1d70177d2 --- /dev/null +++ b/core/script.elv @@ -0,0 +1,78 @@ +use os +use path +use github.com/giancosta86/aurora-elvish/console +use github.com/giancosta86/aurora-elvish/map + +var -shells-by-extension = [ + &.elv='elvish' + &.sh='bash' +] + +var -prioritized-script-extensions = [.elv .sh] + +fn get-actual-path { |base-path| + if (os:is-regular $base-path) { + console:inspect &emoji=📃 'Script found at base path' $base-path + put $base-path + return + } + + for extension $-prioritized-script-extensions { + var extended-path = $base-path''$extension + console:inspect 'Looking for script at extended path' $extended-path + + if (os:is-regular $extended-path) { + console:inspect &emoji=📃 'Script found at extended path' $extended-path + put $extended-path + return + } + } + + console:echo 💭 No script found, even after adding extensions... + put $nil +} + +fn -detect-shell { |script-path| + var script-extension = (path:ext $script-path) + + map:get-value $-shells-by-extension $script-extension +} + +fn run { |&working-directory=$nil &optional=$false &shell=$nil script-path @script-args| + tmp pwd = (coalesce $working-directory $pwd) + + console:inspect &emoji=📁 'Current directory for scripting' $pwd + + var actual-script-path = (get-actual-path $script-path) + + if (not $actual-script-path) { + var error-message = "Cannot find a script associated with '"$script-path"'" + + if $optional { + console:echo 💭 $error-message... + return + } else { + fail $error-message + } + } + + console:inspect &emoji=🐚 'Requested shell' $shell + + var actual-shell = (coalesce $shell (-detect-shell $actual-script-path)) + console:inspect &emoji=🐚 'Actual shell' $actual-shell + + if (not $actual-shell) { + var error-message = "Cannot detect a shell for script path: '"$actual-script-path"'" + + if $optional { + console:echo 💭 $error-message... + return + } else { + fail $error-message + } + } + + console:inspect &emoji=📎 'Script args' $script-args + + (external $actual-shell) $actual-script-path $@script-args +} \ No newline at end of file diff --git a/core/system-packages.elv b/core/system-packages.elv new file mode 100644 index 000000000..3ff91bc6c --- /dev/null +++ b/core/system-packages.elv @@ -0,0 +1,66 @@ +use os +use github.com/giancosta86/aurora-elvish/command +use github.com/giancosta86/aurora-elvish/console + +fn -should-run-installer { |required-command| + if $required-command { + console:inspect &emoji=📥 'Required command' $required-command + + if (command:exists-in-bash $required-command) { + console:echo ✅ Required command available - no need to install it! + put $false + return + } else { + console:echo 💬 Required command not available - now installing its packages... + } + } else { + console:echo 💫 No required command passed - the requested packages will be installed unconditionally... + } + + put $true +} + +fn -run-initial-update { + var flag-file = ~/.install-system-packages-updated + + if (os:is-regular $flag-file) { + console:echo 💡 The package list has already been updated! + return + } + + console:echo 📥 Updating the package list... + + command:silence-until-error { + sudo apt-get update + } + + touch $flag-file +} + +fn -run-installer { |requested-packages| + console:echo 📦 Installing packages... + + command:silence-until-error { + sudo apt-get install -y $@requested-packages + } + + console:echo ✅ Packages installed! +} + +fn install { |inputs| + console:inspect-inputs $inputs + + var packages = $inputs[packages] + var required-command = $inputs[required-command] + var initial-update = $inputs[initial-update] + + if (not (-should-run-installer $required-command)) { + return + } + + if $initial-update { + -run-initial-update + } + + -run-installer $packages +} diff --git a/core/tag-and-release.elv b/core/tag-and-release.elv new file mode 100644 index 000000000..b6582bd4b --- /dev/null +++ b/core/tag-and-release.elv @@ -0,0 +1,87 @@ +use github.com/giancosta86/aurora-elvish/console +use github.com/giancosta86/aurora-elvish/semver +use ./branch-version/detection +use ./ci-cd/pull-request +use ./git +use ./tag-and-release/git-log +use ./tag-and-release/major-tag +use ./tag-and-release/preconditions +use ./tag-and-release/release + +fn -get-actual-draft-release { |draft-release semantic-version| + if (==s $draft-release true) { + put $true + return + } + + if (==s $draft-release false) { + put $false + return + } + + semver:is-new-major $semantic-version +} + +fn run-action { |inputs| + console:inspect-inputs $inputs + + var draft-release = $inputs[draft-release] + var notes-file-processor = $inputs[notes-file-processor] + var set-major-tag = $inputs[set-major-tag] + var dry-run = $inputs[dry-run] + var git-strategy = $inputs[git-strategy] + + preconditions:check $dry-run + + var version-info = (detection:detect) + var version = $version-info[version] + var branch = $version-info[branch] + var major = $version-info[major] + var semantic-version = $version-info[semantic-version] + + var pull-request = (pull-request:fetch-info $branch) + console:inspect &emoji=🔁 'Pull request' $pull-request + + git:hard-reset + + git-log:fetch $pull-request + + git:fetch-tags + + if (not $dry-run) { + pull-request:merge $branch $git-strategy + } else { + console:echo 💭 Just simulating pull request merging, in dry-run mode... + } + + var tag = v$version + console:inspect &emoji=📌 'Tag to create' $tag + + if (not $dry-run) { + git:create-and-push-tag $tag + } else { + console:echo 💭 Just simulating Git tag creation, in dry-run mode... + } + + release:create [ + &tag=$tag + &version=$version + &dry-run=$dry-run + &draft-release=(-get-actual-draft-release $draft-release $semantic-version) + ¬es-file-processor=$notes-file-processor + &pull-request=$pull-request + ] + + var major-tag + if $set-major-tag { + set major-tag = (major-tag:create $major $dry-run) + } else { + console:echo 💬 Skipping major tag, as requested + set major-tag = $nil + } + + put [ + &tag=$tag + &major-tag=$major-tag + ] +} \ No newline at end of file diff --git a/core/tag-and-release/git-log.elv b/core/tag-and-release/git-log.elv new file mode 100644 index 000000000..087f0302f --- /dev/null +++ b/core/tag-and-release/git-log.elv @@ -0,0 +1,22 @@ +use github.com/giancosta86/aurora-elvish/console +use ../ci-cd/pull-request +use ../git + +fn fetch { |pull-request| + var branch = $pull-request[branch] + var base-sha = $pull-request[base-sha] + var head-sha = $pull-request[head-sha] + + if (pull-request:triggers-current-workflow) { + console:echo 📥 Fetching Git log within a pull request workflow... + + git fetch origin $base-sha $head-sha + } else { + console:echo 📥 Fetching Git log not within a pull request workflow... + + git:fetch-branched-sha $branch $head-sha + git:fetch-branched-sha $branch $base-sha + } + + console:echo ✅ Git log ready! +} \ No newline at end of file diff --git a/core/tag-and-release/major-tag.elv b/core/tag-and-release/major-tag.elv new file mode 100644 index 000000000..d5b982d89 --- /dev/null +++ b/core/tag-and-release/major-tag.elv @@ -0,0 +1,18 @@ +use github.com/giancosta86/aurora-elvish/console +use ../git + +fn create { |major dry-run| + var major-tag = v$major + + console:inspect &emoji=🪩 'Setting major version tag' $major-tag + + if (not $dry-run) { + git:create-and-push-tag &force $major-tag + + console:echo 🪩 Major version tag set! + } else { + console:echo 💭 Just simulating major version tag creation, in dry-run mode... + } + + put $major-tag +} \ No newline at end of file diff --git a/core/tag-and-release/preconditions.elv b/core/tag-and-release/preconditions.elv new file mode 100644 index 000000000..5b69cceaf --- /dev/null +++ b/core/tag-and-release/preconditions.elv @@ -0,0 +1,19 @@ +use github.com/giancosta86/aurora-elvish/console +use ../ci-cd/pull-request + +fn -check-trigger { |dry-run| + var triggered-by-pull-request = (pull-request:triggers-current-workflow) + console:inspect 'Triggered by pull request' $triggered-by-pull-request + + if $triggered-by-pull-request { + if $dry-run { + console:echo ⛵ Since dry-run is enabled, the action can be run in a pull-request-triggered workflow + } else { + fail 'This action can be run from a workflow triggered by a pull-request only when dry-run is enabled' + } + } +} + +fn check { |dry-run| + -check-trigger $dry-run +} diff --git a/core/tag-and-release/release-notes.elv b/core/tag-and-release/release-notes.elv new file mode 100644 index 000000000..69c5711bf --- /dev/null +++ b/core/tag-and-release/release-notes.elv @@ -0,0 +1,77 @@ +use re +use str +use github.com/giancosta86/aurora-elvish/console +use github.com/giancosta86/aurora-elvish/lang +use github.com/giancosta86/aurora-elvish/seq +use ../ci-cd/repository + +fn -write-commit-list { |pull-request| + var base-sha = $pull-request[base-sha] + var head-sha = $pull-request[head-sha] + + var marker = '§+-+§' + + var commit-list = (git log --no-merges --reverse --pretty=format:$marker'* %B' $base-sha'..'$head-sha | + slurp | + re:replace '(?m)^' ' ' (all) | + str:replace ' '$marker '' (all) | + str:trim-space (all) + ) + + echo $commit-list +} + +fn -write-pull-request-data { |pull-request| + var title = $pull-request[title] + var number = $pull-request[number] + + echo '**Pull request**: '$title' (#'$number')' +} + +fn -write-changelog-footer { |pull-request tag| + var base-sha = $pull-request[base-sha] + + var most-specific-base-tag = ( + git tag --points-at $base-sha | + order &key={ |tag| count $tag } &reverse | + take 1 | + lang:ensure-put + ) + + var base-reference + + if $most-specific-base-tag { + console:echo 📌 Tag "'"$most-specific-base-tag"'" found for the "'"$base-sha"'" base SHA + set base-reference = $most-specific-base-tag + } else { + console:echo 💭 No tags associated with the "'"$base-sha"'" base SHA - using it directly + set base-reference = $base-sha + } + + console:inspect &emoji=🧭 'Base reference' $base-reference + console:inspect &emoji=📌 'Release tag' $tag + + echo '**Full changelog**: '(repository:get-changelog $base-reference $tag) +} + +fn generate { |inputs| + console:inspect-inputs $inputs + + var output-path = $inputs[output-path] + var tag = $inputs[tag] + var pull-request = $inputs[pull-request] + + { + -write-commit-list $pull-request + + echo '---' + + -write-pull-request-data $pull-request + + -write-changelog-footer $pull-request $tag + } >> $output-path + + console:section &emoji=📝 'Generated release notes' { + cat $output-path + } +} \ No newline at end of file diff --git a/core/tag-and-release/release.elv b/core/tag-and-release/release.elv new file mode 100644 index 000000000..f8929f323 --- /dev/null +++ b/core/tag-and-release/release.elv @@ -0,0 +1,74 @@ +use path +use github.com/giancosta86/aurora-elvish/console +use github.com/giancosta86/aurora-elvish/fs +use ../ci-cd/repository +use ../script +use ./release-notes + +fn -get-release-title { |version| + var repository-full-name = (repository:get-full-name) + + var repository-basename = (path:base $repository-full-name) + console:inspect &emoji=🧭 'Repository basename' $repository-basename + + put $repository-basename' '$version +} + +fn create { |inputs| + console:inspect-inputs $inputs + + var tag = $inputs[tag] + var version = $inputs[version] + var dry-run = $inputs[dry-run] + var draft-release = $inputs[draft-release] + var notes-file-processor = $inputs[notes-file-processor] + var pull-request = $inputs[pull-request] + + var release-title = (-get-release-title $version) + console:inspect &emoji=🔎 'Release title' $release-title + + var release-notes-path = (fs:temp-file-path) + defer { + fs:rimraf release-notes-path + } + + release-notes:generate [ + &output-path=$release-notes-path + &tag=$tag + &pull-request=$pull-request + ] + + if $notes-file-processor { + console:inspect &emoji=🖋 'Release notes file processor' $notes-file-processor + + script:run $notes-file-processor $release-notes-path + + console:section &emoji=🎀 'Processed release notes' { + cat $release-notes-path + } + } else { + console:echo 💭 No release notes file processor... + } + + if $draft-release { + console:inspect &emoji=📝 'Drafting release' $release-title + + if (not $dry-run) { + gh release create $tag --title $release-title --latest --notes-file $release-notes-path --draft + + console:echo 📝 Release drafted! + } else { + console:echo 💭 Just simulating draft release creation, in dry-run mode... + } + } else { + console:inspect &emoji=🌟 'Publishing release' $release-title + + if (not $dry-run) { + gh release create $tag --title $release-title --latest --notes-file $release-notes-path + + console:echo 🌟 Release published! + } else { + console:echo 💭 Just simulating release publication, in dry-run mode... + } + } +} \ No newline at end of file diff --git a/core/website.elv b/core/website.elv new file mode 100644 index 000000000..000694d4c --- /dev/null +++ b/core/website.elv @@ -0,0 +1,84 @@ +use os +use path +use github.com/giancosta86/aurora-elvish/console +use github.com/giancosta86/aurora-elvish/seq +use ./ci-cd/env + +fn -set-strategy { |strategy| + console:inspect &emoji=💡 'Current website publication strategy' $strategy + env:write strategy $strategy +} + +fn -enforce-exit-strategy { + -set-strategy exit +} + +fn detect-strategy-from-sources { |source-directory| + if (not $source-directory) { + -enforce-exit-strategy + return + } + + console:inspect &emoji=🌐📁 'Website source directory' $source-directory + + tmp pwd = $source-directory + + if (os:is-regular package.json) { + -set-strategy nodejs + } elif (os:is-regular pom.xml) { + -set-strategy maven + } else { + -set-strategy static-files + } +} + +fn set-artifact-directory { |@path-components| + env:write artifactDirectory (path:join $@path-components) +} + +fn build-via-nodejs { |source-directory| + tmp pwd = $source-directory + + console:echo 📦 Now building the website via NodeJS... + pnpm build + console:echo ✅ Website built! + + set-artifact-directory $source-directory dist +} + +fn build-via-maven { |source-directory| + use ./jvm/context + use ./jvm/maven + + tmp pwd = $source-directory + + context:setup + + console:echo 🪶 Now building the website via Maven... + maven:run site + console:echo ✅ Website built! + + set-artifact-directory $source-directory target site +} + +fn check-artifact-directory { |artifact-directory optional| + console:inspect &emoji=📁 'Website artifact directory' $artifact-directory + + if (os:is-dir $artifact-directory) { + console:echo ✅ The artifact directory for the 🌐 website exists! + } else { + if $optional { + console:echo 💬 Missing website artifact directory - cannot publish website + -enforce-exit-strategy + } else { + fail 'Missing website artifact directory!' + } + } +} + +fn skip-publication-on-dry-run { |dry-run| + if $dry-run { + console:echo 💭 Skipping publication, as requested by dry-run. + -enforce-exit-strategy + } +} diff --git a/docs/schema.drawio b/docs/schema.drawio deleted file mode 100644 index 143be6292..000000000 --- a/docs/schema.drawio +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/schema.png b/docs/schema.png deleted file mode 100644 index af54a144d..000000000 Binary files a/docs/schema.png and /dev/null differ diff --git a/lefthook.yml b/lefthook.yml index 92445f255..4db295685 100644 --- a/lefthook.yml +++ b/lefthook.yml @@ -1,5 +1,9 @@ +pre-commit: + scripts: + check-elvish-syntax.elv: + runner: elvish + post-checkout: - jobs: - - name: Update action references + scripts: + update-action-references.elv: runner: elvish - script: update-action-references.elv diff --git a/lib/core.elv b/lib/core.elv deleted file mode 100644 index 446a23c07..000000000 --- a/lib/core.elv +++ /dev/null @@ -1,29 +0,0 @@ -use str -use re - -fn write-env { |key value| - echo $key'='$value >> $E:GITHUB_ENV -} - -fn write-output { |key value| - echo $key'='$value >> $E:GITHUB_OUTPUT -} - -fn parse-string-list { |string-list| - re:split ',| ' $string-list | each { |entry| - if (not-eq $entry "") { - put $entry - } - } -} - -fn string-list-to-csv { |csv-list| - parse-string-list $csv-list | str:join , -} - -fn to-sha { |source| - echo $source | - sha256sum | - str:split ' ' (all) | - take 1 -} diff --git a/lib/startup-libs.elv b/lib/startup-libs.elv deleted file mode 100644 index af2b8afa3..000000000 --- a/lib/startup-libs.elv +++ /dev/null @@ -1,36 +0,0 @@ -use epm -use str -use ./core - -fn setup-env-vars { |inputs| - echo 🔎EPM managed directory: "'"$epm:managed-dir"'" - - var comma-separated-packages = (core:string-list-to-csv $inputs[packages]) - echo 🔎Comma-separated packages: "'"$comma-separated-packages"'" - - var packages-sha = (core:to-sha $comma-separated-packages) - echo 🔎Packages SHA: $packages-sha - - var epm-cache-key = $inputs[workflow]-$inputs[run-number]-$packages-sha - echo 🔎Epm cache key: "'"$epm-cache-key"'" - - core:write-env epm-dir $epm:managed-dir - core:write-env comma-separated-packages $comma-separated-packages - core:write-env epm-cache-key $epm-cache-key -} - -fn install { |comma-separated-packages| - str:split , $comma-separated-packages | each { |pkg| - epm:install $pkg - } - - echo 🚀Startup packages for Elvish installed! -} - -fn list { - echo 📚Elvish startup packages: - epm:installed | each { |pkg| - echo '*' $pkg - } - echo 📚📚📚 -} \ No newline at end of file diff --git a/logo.jpg b/logo.jpg new file mode 100644 index 000000000..913ba127c Binary files /dev/null and b/logo.jpg differ diff --git a/tests/custom/.gitignore b/tests/custom/.gitignore new file mode 100644 index 000000000..b01f4cd3c --- /dev/null +++ b/tests/custom/.gitignore @@ -0,0 +1 @@ +**/out.txt \ No newline at end of file diff --git a/tests/custom/bash/verify.sh b/tests/custom/bash/verify.sh new file mode 100644 index 000000000..63af88390 --- /dev/null +++ b/tests/custom/bash/verify.sh @@ -0,0 +1 @@ +echo 'TEST OK' > out.txt \ No newline at end of file diff --git a/tests/custom/elvish-custom/super-test.elv b/tests/custom/elvish-custom/super-test.elv new file mode 100644 index 000000000..63af88390 --- /dev/null +++ b/tests/custom/elvish-custom/super-test.elv @@ -0,0 +1 @@ +echo 'TEST OK' > out.txt \ No newline at end of file diff --git a/tests/custom/elvish/verify.elv b/tests/custom/elvish/verify.elv new file mode 100644 index 000000000..63af88390 --- /dev/null +++ b/tests/custom/elvish/verify.elv @@ -0,0 +1 @@ +echo 'TEST OK' > out.txt \ No newline at end of file diff --git a/tests/custom/nodejs/.gitignore b/tests/custom/nodejs/.gitignore deleted file mode 100644 index 457c5c7d0..000000000 --- a/tests/custom/nodejs/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/generated-file.txt \ No newline at end of file diff --git a/tests/custom/nodejs/package.json b/tests/custom/nodejs/package.json index 90c4fc490..72e40e80c 100644 --- a/tests/custom/nodejs/package.json +++ b/tests/custom/nodejs/package.json @@ -1,7 +1,7 @@ { "name": "nodejs-test", "scripts": { - "verify": "echo 'NodeJS-generated content' > generated-file.txt" + "verify": "echo 'TEST OK' > out.txt" }, "private": true, "engines": { diff --git a/tests/custom/rust/.gitignore b/tests/custom/rust/.gitignore index 44902230a..c41cc9e35 100644 --- a/tests/custom/rust/.gitignore +++ b/tests/custom/rust/.gitignore @@ -1,2 +1 @@ -/target -/generated-file.txt \ No newline at end of file +/target \ No newline at end of file diff --git a/tests/custom/rust/src/lib.rs b/tests/custom/rust/src/lib.rs index 4c9ea346f..3807640ab 100644 --- a/tests/custom/rust/src/lib.rs +++ b/tests/custom/rust/src/lib.rs @@ -4,6 +4,6 @@ mod tests { #[test] fn generate_file() { - fs::write("generated-file.txt", "Rust-generated content").unwrap(); + fs::write("out.txt", "TEST OK").unwrap(); } } diff --git a/tests/custom/script/.gitignore b/tests/custom/script/.gitignore deleted file mode 100644 index 457c5c7d0..000000000 --- a/tests/custom/script/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/generated-file.txt \ No newline at end of file diff --git a/tests/custom/script/verify.sh b/tests/custom/script/verify.sh deleted file mode 100644 index 0350f4496..000000000 --- a/tests/custom/script/verify.sh +++ /dev/null @@ -1 +0,0 @@ -echo "Bash-generated content" > generated-file.txt \ No newline at end of file diff --git a/tests/custom/test-runner/numbers.test.elv b/tests/custom/test-runner/numbers.test.elv new file mode 100644 index 000000000..1830d60e4 --- /dev/null +++ b/tests/custom/test-runner/numbers.test.elv @@ -0,0 +1,15 @@ +describe 'Among numeric operations' { + describe 'addition' { + it 'should work' { + + 90 2 | + should-be 92 + } + } + + describe 'division' { + it 'should work' { + / 90 3 | + should-be 30 + } + } +} \ No newline at end of file diff --git a/tests/custom/test-runner/protocol.test.elv b/tests/custom/test-runner/protocol.test.elv new file mode 100644 index 000000000..de10d1485 --- /dev/null +++ b/tests/custom/test-runner/protocol.test.elv @@ -0,0 +1,5 @@ +describe 'The testing protocol required by test-run-custom-tests' { + it 'should be satisfied' { + echo 'TEST OK' > out.txt + } +} \ No newline at end of file diff --git a/tests/custom/test-runner/string.test.elv b/tests/custom/test-runner/string.test.elv new file mode 100644 index 000000000..7fa178e6b --- /dev/null +++ b/tests/custom/test-runner/string.test.elv @@ -0,0 +1,9 @@ +describe 'Concatenating two strings' { + it 'should work' { + var a = 'A' + var b = 'B' + + put $a''$b | + should-be 'AB' + } +} \ No newline at end of file diff --git a/tests/elvish-library/metadata.json b/tests/elvish-library/metadata.json new file mode 100644 index 000000000..c0f319694 --- /dev/null +++ b/tests/elvish-library/metadata.json @@ -0,0 +1,9 @@ +{ + "description": "My description", + + "maintainers": ["Gianluca Costa "], + + "homepage": "https://github.com/giancosta86/aurora-elvish", + + "dependencies": [] +} diff --git a/tests/elvish-library/my-ops.elv b/tests/elvish-library/my-ops.elv new file mode 100644 index 000000000..bf11b7f67 --- /dev/null +++ b/tests/elvish-library/my-ops.elv @@ -0,0 +1,3 @@ +fn test-sum { |a b c| + + $a $b $c +} \ No newline at end of file diff --git a/tests/elvish-library/my-ops.test.elv b/tests/elvish-library/my-ops.test.elv new file mode 100644 index 000000000..1b7cb2856 --- /dev/null +++ b/tests/elvish-library/my-ops.test.elv @@ -0,0 +1,17 @@ +use ./my-ops + +describe 'Summing three numbers' { + describe 'when they are all 0' { + it 'should return 0' { + my-ops:test-sum 0 0 0 | + should-be 0 + } + } + + describe 'when they are not 0' { + it 'should return the expected sum' { + my-ops:test-sum 90 5 3 | + should-be 98 + } + } +} \ No newline at end of file diff --git a/tests/npm-package/package.json b/tests/npm-package/package.json index 4b6f825a5..851f21168 100644 --- a/tests/npm-package/package.json +++ b/tests/npm-package/package.json @@ -4,16 +4,15 @@ "type": "module", "description": "Toy npm package", "scripts": { - "test": "echo '✅NodeJS tests simulated!'", - "build": "echo '✅NodeJS build simulated!'", - "verify": "pnpm test && pnpm build" + "verify": "echo '📦📃 package.json `verify` script!'", + "build": "echo '📦📃 package.json `build` script!'" }, "devDependencies": { "@giancosta86/typed-env": "^2.0.3" }, "private": true, "engines": { - "node": "20.15.1" + "node": "20.18.3" }, "packageManager": "pnpm@9.7.1" } diff --git a/core/python/core/__init__.py b/tests/npm-package/src/alpha/index.d.ts similarity index 100% rename from core/python/core/__init__.py rename to tests/npm-package/src/alpha/index.d.ts diff --git a/tests/npm-package/src/alpha/index.ts b/tests/npm-package/src/alpha/index.js similarity index 100% rename from tests/npm-package/src/alpha/index.ts rename to tests/npm-package/src/alpha/index.js diff --git a/tests/npm-package/src/omega/index.ts b/tests/npm-package/src/beta/index.d.ts similarity index 100% rename from tests/npm-package/src/omega/index.ts rename to tests/npm-package/src/beta/index.d.ts diff --git a/tests/npm-package/src/omega/index.js b/tests/npm-package/src/omega/index.js new file mode 100644 index 000000000..e69de29bb diff --git a/tests/python-lib/pyproject.toml b/tests/python-lib/pyproject.toml index 9607677c4..cd0c065ea 100644 --- a/tests/python-lib/pyproject.toml +++ b/tests/python-lib/pyproject.toml @@ -15,4 +15,4 @@ build-backend = "hatchling.build" distribution = true [tool.pdm.scripts] -verify = "echo '✅Simulating passing tests!'" +verify = "echo '🐍📃 pyproject.toml `verify` script!'" diff --git a/tests/rust-crate/src/lib.rs b/tests/rust-crate/src/lib.rs index b93cf3ffd..855cce2ee 100644 --- a/tests/rust-crate/src/lib.rs +++ b/tests/rust-crate/src/lib.rs @@ -1,3 +1,12 @@ +/// Sums two numbers. +/// +/// ``` +/// use rust_crate::*; +/// +/// let result = add(90, 2); +/// +/// assert_eq!(result, 92); +/// ``` pub fn add(left: u64, right: u64) -> u64 { left + right } diff --git a/website/nextjs/global.d.ts b/website/nextjs/global.d.ts new file mode 100644 index 000000000..dd4ab7e91 --- /dev/null +++ b/website/nextjs/global.d.ts @@ -0,0 +1 @@ +declare module "*.svg"; diff --git a/website/nextjs/package.json b/website/nextjs/package.json index acf47000e..e84ca9782 100644 --- a/website/nextjs/package.json +++ b/website/nextjs/package.json @@ -4,8 +4,9 @@ "private": true, "scripts": { "dev": "next dev", + "start": "pnpm dev", "build": "next build", - "start": "next start", + "start:prod": "next start", "lint": "next lint" }, "dependencies": { diff --git a/website/nextjs/src/app/page.tsx b/website/nextjs/src/app/page.tsx index af635d022..05eb24ec6 100644 --- a/website/nextjs/src/app/page.tsx +++ b/website/nextjs/src/app/page.tsx @@ -22,6 +22,8 @@ export default function Home() { {" "} can actually publish websites via GitHub Pages! 🤗🦋

+ +

🔮Now using the Elvish shell! 🥳

);