name: CI Linux on: workflow_dispatch: push: branches: - master paths-ignore: - '**.md' - '**.yml' - '!**/linux_ci.yml' - 'cmd/tools/**' - '!cmd/tools/builders/**.v' pull_request: paths-ignore: - '**.md' - '**.yml' - '!**/linux_ci.yml' - 'cmd/tools/**' - '!cmd/tools/builders/**.v' concurrency: group: linux-${{ github.workflow }}-${{ github.ref == 'refs/heads/master' && github.sha || github.ref }} cancel-in-progress: true jobs: tcc-linux: runs-on: ubuntu-24.04 timeout-minutes: 121 env: VFLAGS: -cc tcc -no-retry-compilation VTEST_SHOW_LONGEST_BY_RUNTIME: 3 VTEST_SHOW_LONGEST_BY_COMPTIME: 3 VTEST_SHOW_LONGEST_BY_TOTALTIME: 3 steps: - uses: actions/checkout@v7 - uses: ./.github/actions/cache-apt-packages-action - name: Build v run: make -j4 && ./v symlink - name: Build v with -prealloc run: v run ci/linux_ci.vsh build_v_with_prealloc - name: All code is formatted run: v run ci/linux_ci.vsh all_code_is_formatted_tcc - name: Install dependencies for examples and tools run: v run ci/linux_ci.vsh install_dependencies_for_examples_and_tools_tcc - name: Test v->c run: v run ci/linux_ci.vsh test_v_to_c_tcc - name: v self compilation run: v run ci/linux_ci.vsh v_self_compilation_tcc - name: v doctor run: v run ci/linux_ci.vsh v_doctor_tcc - name: Verify `v test` works run: v run ci/linux_ci.vsh verify_v_test_works_tcc - name: Test pure V math module run: v run ci/linux_ci.vsh test_pure_v_math_module_tcc - name: Test inline assembly on linux run: v run ci/linux_ci.vsh test_inline_assembly - name: Self tests run: v run ci/linux_ci.vsh self_tests_tcc - name: Build examples run: v run ci/linux_ci.vsh build_examples_tcc - name: Run the submodule example, using a relative path run: v run ci/linux_ci.vsh run_submodule_example_tcc - name: Build v tools run: v run ci/linux_ci.vsh build_tools_tcc - name: Build v binaries run: v run ci/linux_ci.vsh build_vbinaries_tcc - name: Build benches run: v run ci/linux_ci.vsh build_benches_tcc - name: Run a VSH script run: v run ci/linux_ci.vsh run_vsh_script_tcc - name: Test v tutorials run: v run ci/linux_ci.vsh test_v_tutorials_tcc - name: Build cmd/tools/fast run: v run ci/linux_ci.vsh build_fast_tcc - name: V self compilation with -usecache run: v run ci/linux_ci.vsh v_self_compilation_usecache_tcc - name: Test password input run: v run ci/linux_ci.vsh test_password_input_tcc - name: Test readline run: v run ci/linux_ci.vsh test_readline_tcc - name: Test leak detector run: v run ci/linux_ci.vsh test_leak_detector_tcc - name: Test leak detector not being active for normal compile run: v run ci/linux_ci.vsh test_leak_detector_not_active_tcc gcc-linux: runs-on: ubuntu-24.04 timeout-minutes: 121 env: VTEST_SHOW_LONGEST_BY_RUNTIME: 3 VTEST_SHOW_LONGEST_BY_COMPTIME: 3 VTEST_SHOW_LONGEST_BY_TOTALTIME: 3 steps: - uses: actions/checkout@v7 - uses: ./.github/actions/cache-apt-packages-action - name: Build V run: make -j4 && ./v symlink - name: backend x64 regressions if: ${{ false }} # Temporarily disabled. run: | set -e VJOBS=1 ./v test \ vlib/v2_toberemoved/abi \ vlib/v2_toberemoved/gen/x64/x64_abi_test.v \ vlib/v2_toberemoved/gen/x64/x64_backend_diagnostics_test.v \ vlib/v2_toberemoved/gen/x64/x64_object_format_test.v \ vlib/v2_toberemoved/gen/x64/x64_pe_linker_test.v \ vlib/v2_toberemoved/ssa/tree_sumtype_lowering_test.v VJOBS=1 ./v test -run-only test_module_qualified_alias_array_field_index_has_alias_element_type,test_module_storage_legacy_direct_import_nested_module_selector_uses_declared_leaf_module,test_module_storage_flat_direct_import_nested_module_selector_uses_declared_leaf_module vlib/v2_toberemoved/ssa/module_storage_test.v VJOBS=1 ./v test -run-only test_x64_linux_math_log_20_stdout_exact_bytes,test_x64_linux_generic_sumtype_direct_wrap_stdout_exact_bytes,test_x64_linux_generic_sumtype_repeated_base_specialization_stdout_exact_bytes,test_x64_linux_generic_sumtype_receiver_size_stdout_exact_bytes,test_x64_linux_generic_sumtype_insert_size_stdout_exact_bytes,test_x64_linux_struct_float_fields_stdout_exact_bytes,test_x64_linux_union_f64_bits_stdout_exact_bytes,test_x64_linux_f64_str_interpolation_stdout_exact_bytes,test_x64_linux_f64_for_interpolation_stdout_exact_bytes,test_x64_linux_formatted_int_interpolation_stdout_exact_bytes,test_x64_linux_formatted_int_width_100_interpolation_stdout_exact_bytes,test_x64_linux_formatted_f64_interpolation_stdout_exact_bytes,test_x64_linux_formatted_string_return_lifetime_stdout_exact_bytes,test_x64_linux_spectral_reduced_formatted_stdout_exact_bytes,test_x64_linux_bits_len32_stdout_exact_bytes,test_x64_linux_rand_u32n_interface_result_stdout_exact_bytes,test_x64_linux_rand_intn_range_interface_result_stdout_exact_bytes,test_x64_linux_textscanner_embedded_parser_stdout_exact_bytes,test_x64_linux_struct_positional_side_effect_stdout_exact_bytes,test_x64_linux_struct_named_side_effect_stdout_exact_bytes,test_x64_linux_unrelated_same_shape_struct_stdout_exact_bytes,test_x64_linux_named_init_embedded_value_stdout_exact_bytes,test_x64_linux_get_raw_line_example_stdin_stdout_exact_bytes,test_x64_linux_mini_calculator_example_stdin_stdout_exact_bytes,test_x64_linux_mini_calculator_recursive_descent_example_stdin_stdout_exact_bytes,test_x64_linux_external_c_flag_source_uses_hosted_link_with_compile_flags vlib/v2_toberemoved/gen/x64/x64_runtime_smoke_test.v VJOBS=1 ./v test -run-only test_non_generic_concrete_sumtype_return_wraps_variant,test_option_concrete_sumtype_return_wraps_variant,test_generic_sumtype_declared_param_order_is_preserved_for_crossed_variants,test_worker_clone_sees_sumtype_decl_variant_cache,test_sumtype_decl_variant_cache_records_concrete_generic_variants_only,test_generic_sumtype_match_uses_full_specialization_when_generic_base_repeats,test_flat_direct_generic_sumtype_match_uses_full_specialization_when_generic_base_repeats,test_generic_sumtype_match_smartcast_scans_full_specialization_body,test_flat_direct_generic_sumtype_match_smartcast_scans_full_specialization_body,test_nested_module_concrete_generic_sumtype_base_does_not_fall_back_to_local_tree,test_leaf_module_concrete_generic_sumtype_base_fallback_beats_parent_module_tree vlib/v2_toberemoved/transformer/monomorphize_test.v ./v test vlib/v2_toberemoved/builder/native_test.v vlib/v2_toberemoved/builder/target_os_test.v ./v test vlib/v2_toberemoved/ssa/optimize V2_VERIFY_STRICT=1 ./v test vlib/v2_toberemoved/ssa/optimize - name: backend x64 examples if: ${{ false }} # Temporarily disabled. run: | set -e tmp="$(mktemp -d)" trap 'rm -rf "$tmp"' EXIT check_empty_stderr() { label="$1" stderr="$2" if [ -s "$stderr" ]; then echo "::error::$label wrote to stderr" cat "$stderr" return 1 fi } check_stdout() { label="$1" expected="$2" actual="$3" if ! cmp -s "$expected" "$actual"; then echo "::error::$label stdout mismatch" echo "expected:" cat "$expected" echo "actual:" cat "$actual" return 1 fi } run_native_x64_example() { source="$1" name="$2" expected="$3" shift 3 ./v -v2 -no-parallel -b x64 "$source" -o "$tmp/$name" "$tmp/$name" "$@" > "$tmp/$name.out" 2> "$tmp/$name.err" check_empty_stderr "$name" "$tmp/$name.err" check_stdout "$name" "$expected" "$tmp/$name.out" } run_native_x64_example_with_stdin() { source="$1" name="$2" input="$3" expected="$4" shift 4 ./v -v2 -no-parallel -b x64 "$source" -o "$tmp/$name" "$tmp/$name" "$@" < "$input" > "$tmp/$name.out" 2> "$tmp/$name.err" check_empty_stderr "$name" "$tmp/$name.err" check_stdout "$name" "$expected" "$tmp/$name.out" } run_native_x64_example_capture() { source="$1" name="$2" shift 2 ./v -v2 -no-parallel -b x64 "$source" -o "$tmp/$name" "$tmp/$name" "$@" > "$tmp/$name.out" 2> "$tmp/$name.err" check_empty_stderr "$name" "$tmp/$name.err" } check_random_ips_stdout() { label="$1" actual="$2" python3 - "$label" "$actual" <<'PY' import sys label = sys.argv[1] path = sys.argv[2] lines = open(path, "r", encoding="utf-8").read().splitlines() if len(lines) != 10: raise SystemExit(f"{label}: expected 10 lines, got {len(lines)}") rows = [] for line in lines: parts = line.split(".") if len(parts) != 4: raise SystemExit(f"{label}: invalid IPv4 shape: {line!r}") row = [] for part in parts: if not part.isdigit(): raise SystemExit(f"{label}: non-numeric octet in {line!r}") value = int(part) if value < 0 or value > 254: raise SystemExit(f"{label}: octet out of range in {line!r}") row.append(value) rows.append(tuple(row)) if len(set(rows)) < 3: raise SystemExit(f"{label}: output has too little row diversity") if all(row[1] == 0 for row in rows) and all(row[3] == 0 for row in rows): raise SystemExit(f"{label}: suspicious old x.0.x.0 pattern") PY } check_rule110_stdout() { label="$1" actual="$2" width="$3" python3 - "$label" "$actual" "$width" <<'PY' import sys label = sys.argv[1] path = sys.argv[2] width = int(sys.argv[3]) lines = open(path, "r", encoding="utf-8").read().splitlines() title = "Rule 110 V Implementation" title_lines = [idx for idx, line in enumerate(lines) if title in line] if not title_lines: raise SystemExit(f"{label}: missing title") idx = title_lines[0] generations = lines[idx + 1:] if generations and generations[0] == "": generations = generations[1:] if len(generations) != width: raise SystemExit(f"{label}: expected {width} generation lines, got {len(generations)}") for line in generations: if len(line) != width: raise SystemExit(f"{label}: generation line has width {len(line)}, expected {width}: {line!r}") if any(ch not in " *" for ch in line): raise SystemExit(f"{label}: invalid generation chars: {line!r}") if not any("*" in line for line in generations): raise SystemExit(f"{label}: expected at least one live cell") if len(set(generations)) < 3: raise SystemExit(f"{label}: expected at least 3 distinct generation lines") PY } write_v_run_expected() { source="$1" expected="$2" shift 2 stderr="$tmp/$(basename "$expected").stderr" ./v run "$source" "$@" > "$expected" 2> "$stderr" check_empty_stderr "v run $source $*" "$stderr" } write_v_run_expected_with_stdin() { source="$1" input="$2" expected="$3" shift 3 stderr="$tmp/$(basename "$expected").stderr" ./v run "$source" "$@" < "$input" > "$expected" 2> "$stderr" check_empty_stderr "v run $source $*" "$stderr" } write_fizz_buzz_expected() { i=1 while [ "$i" -le 100 ]; do if [ $((i % 15)) -eq 0 ]; then echo FizzBuzz elif [ $((i % 3)) -eq 0 ]; then echo Fizz elif [ $((i % 5)) -eq 0 ]; then echo Buzz else echo "$i" fi i=$((i + 1)) done } write_hanoi_expected() { python3 - <<'PY' def hanoi(n, a, b, c): if n == 1: print(f"Disc 1 from {a} to {c}...") else: hanoi(n - 1, a, c, b) print(f"Disc {n} from {a} to {c}...") hanoi(n - 1, b, a, c) hanoi(7, "A", "B", "C") PY } write_sudoku_expected() { python3 - <<'PY' import sys puzzle = [ [0, 3, 0, 0, 7, 0, 0, 0, 0], [0, 0, 0, 1, 3, 5, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 5, 0], [1, 0, 0, 0, 6, 0, 0, 0, 3], [4, 0, 0, 8, 0, 3, 0, 0, 1], [7, 0, 0, 0, 2, 0, 0, 0, 6], [0, 0, 0, 0, 0, 0, 2, 1, 0], [0, 0, 0, 4, 1, 2, 0, 0, 5], [0, 0, 0, 0, 0, 0, 0, 7, 4], ] solution = [ [2, 3, 5, 6, 7, 8, 1, 4, 9], [9, 4, 7, 1, 3, 5, 8, 6, 2], [6, 8, 1, 2, 4, 9, 3, 5, 7], [1, 2, 8, 7, 6, 4, 5, 9, 3], [4, 5, 6, 8, 9, 3, 7, 2, 1], [7, 9, 3, 5, 2, 1, 4, 8, 6], [3, 6, 4, 9, 5, 7, 2, 1, 8], [8, 7, 9, 4, 1, 2, 6, 3, 5], [5, 1, 2, 3, 8, 6, 9, 7, 4], ] def append_grid(lines, label, grid): lines.append(label) for i, row in enumerate(grid): if i % 3 == 0 and i != 0: lines.append("- - - - - - - - - - - -") line = "" for j, value in enumerate(row): if j % 3 == 0 and j != 0: line += " | " line += f"{value} " lines.append(line) lines = [] append_grid(lines, "Sudoku Puzzle:", puzzle) lines.append("Solving...") append_grid(lines, "Solution:", solution) out = ("\n".join(lines) + "\n").encode() if len(out) != 582: raise SystemExit(f"sudoku stdout oracle shape changed: {len(out)} bytes") sys.stdout.buffer.write(out) PY } write_tree_of_nodes_expected() { cat <<'EOF' tree structure: Node{ value: 10 left: Tree(Node{ value: 30 left: Tree(Empty{}) right: Tree(Empty{}) }) right: Tree(Node{ value: 20 left: Tree(Empty{}) right: Tree(Empty{}) }) } tree size: 3 EOF } write_js_hello_world_expected() { printf 'Hello from V.js (0)\nHello from V.js (1)\nHello from V.js (2)\n' } write_vascii_expected() { python3 - <<'PY' from pathlib import Path import sys source = Path("examples/vascii.v").read_text(encoding="utf-8") start_marker = "println('" end_marker = "')" if source.count(start_marker) != 1: raise SystemExit("vascii stdout oracle expects one single-quoted println literal") start = source.index(start_marker) + len(start_marker) end = source.rindex(end_marker) if source[end + len(end_marker):].strip() != "}": raise SystemExit("vascii stdout oracle expects the println literal to be the final main statement") out = bytearray() literal = source[start:end] i = 0 while i < len(literal): ch = literal[i] if ch == "\\": i += 1 if i >= len(literal): raise SystemExit("unterminated escape in vascii literal") escaped = literal[i] if escaped == "n": out.append(10) elif escaped == "t": out.append(9) elif escaped == "r": out.append(13) elif escaped == "\\": out.append(92) elif escaped == "'": out.append(39) elif escaped == '"': out.append(34) else: out.extend(escaped.encode("utf-8")) else: out.extend(ch.encode("utf-8")) i += 1 out.append(10) sys.stdout.buffer.write(out) PY } write_rune_expected() { printf '\360\237\230\200\n@\n' } printf 'Hello, World!\n' > "$tmp/hello_world.expected" write_fizz_buzz_expected > "$tmp/fizz_buzz.expected" write_hanoi_expected > "$tmp/hanoi.expected" write_sudoku_expected > "$tmp/sudoku.expected" printf 'HELLO WORLD\nHELLO WORLD\nHELLO WORLD\n' > "$tmp/function_types.expected" printf '5\n3\n' > "$tmp/submodule.expected" printf '1\n1\n2\n3\n5\n8\n13\n21\n34\n55\n89\n' > "$tmp/fibonacci_10.expected" printf '120\n' > "$tmp/dump_factorial.expected" write_v_run_expected examples/primes.v "$tmp/primes_20.expected" 20 write_tree_of_nodes_expected > "$tmp/tree_of_nodes.expected" write_js_hello_world_expected > "$tmp/js_hello_world.expected" write_vascii_expected > "$tmp/vascii.expected" write_rune_expected > "$tmp/rune.expected" write_v_run_expected examples/graphs/bfs.v "$tmp/bfs.expected" write_v_run_expected examples/graphs/bfs3.v "$tmp/bfs3.expected" write_v_run_expected examples/graphs/dfs.v "$tmp/dfs.expected" write_v_run_expected examples/graphs/dijkstra.v "$tmp/dijkstra.expected" write_v_run_expected examples/graphs/topological_sorting_greedy.v "$tmp/topological_sorting_greedy.expected" write_v_run_expected examples/graphs/topological_sorting_dfs.v "$tmp/topological_sorting_dfs.expected" write_v_run_expected examples/graphs/dfs2.v "$tmp/dfs2.expected" write_v_run_expected examples/graphs/minimal_spann_tree_prim.v "$tmp/minimal_spann_tree_prim.expected" write_v_run_expected examples/graphs/bellman-ford.v "$tmp/bellman_ford.expected" write_v_run_expected examples/binary_search_tree.v "$tmp/binary_search_tree.expected" printf 'wrong format\nempty input\n' > "$tmp/errors.expected" write_v_run_expected examples/custom_error.v "$tmp/custom_error.expected" write_v_run_expected examples/spectral.v "$tmp/spectral_10.expected" 10 printf 'length of random array is 1000\nbefore quick sort whether array is sorted: false\nafter quick sort whether array is sorted: true\n' > "$tmp/quick_sort.expected" printf 'hello\nworld\n' > "$tmp/get_raw_line.in" write_v_run_expected_with_stdin examples/get_raw_line.v "$tmp/get_raw_line.in" "$tmp/get_raw_line.expected" printf '3+4*2\nexit\n' > "$tmp/mini_calculator.in" write_v_run_expected_with_stdin examples/mini_calculator.v "$tmp/mini_calculator.in" "$tmp/mini_calculator.expected" printf '3+4*2\nexit\n' > "$tmp/mini_calculator_recursive_descent.in" write_v_run_expected_with_stdin examples/mini_calculator_recursive_descent.v "$tmp/mini_calculator_recursive_descent.in" "$tmp/mini_calculator_recursive_descent.expected" run_native_x64_example examples/hello_world.v hello_world "$tmp/hello_world.expected" run_native_x64_example examples/fizz_buzz.v fizz_buzz "$tmp/fizz_buzz.expected" run_native_x64_example examples/hanoi.v hanoi "$tmp/hanoi.expected" run_native_x64_example examples/sudoku.v sudoku "$tmp/sudoku.expected" run_native_x64_example examples/function_types.v function_types "$tmp/function_types.expected" run_native_x64_example examples/submodule/main.v submodule "$tmp/submodule.expected" run_native_x64_example examples/fibonacci.v fibonacci "$tmp/fibonacci_10.expected" 10 run_native_x64_example examples/dump_factorial.v dump_factorial "$tmp/dump_factorial.expected" run_native_x64_example examples/primes.v primes "$tmp/primes_20.expected" 20 run_native_x64_example examples/tree_of_nodes.v tree_of_nodes "$tmp/tree_of_nodes.expected" run_native_x64_example examples/js_hello_world.v js_hello_world "$tmp/js_hello_world.expected" run_native_x64_example examples/vascii.v vascii "$tmp/vascii.expected" run_native_x64_example examples/rune.v rune "$tmp/rune.expected" run_native_x64_example examples/graphs/bfs.v bfs "$tmp/bfs.expected" run_native_x64_example examples/graphs/bfs3.v bfs3 "$tmp/bfs3.expected" run_native_x64_example examples/graphs/dfs.v dfs "$tmp/dfs.expected" run_native_x64_example examples/graphs/dijkstra.v dijkstra "$tmp/dijkstra.expected" run_native_x64_example examples/graphs/topological_sorting_greedy.v topological_sorting_greedy "$tmp/topological_sorting_greedy.expected" run_native_x64_example examples/graphs/topological_sorting_dfs.v topological_sorting_dfs "$tmp/topological_sorting_dfs.expected" run_native_x64_example examples/graphs/dfs2.v dfs2 "$tmp/dfs2.expected" run_native_x64_example examples/graphs/minimal_spann_tree_prim.v minimal_spann_tree_prim "$tmp/minimal_spann_tree_prim.expected" run_native_x64_example examples/graphs/bellman-ford.v bellman_ford "$tmp/bellman_ford.expected" run_native_x64_example examples/binary_search_tree.v binary_search_tree "$tmp/binary_search_tree.expected" run_native_x64_example examples/errors.v errors "$tmp/errors.expected" run_native_x64_example examples/custom_error.v custom_error "$tmp/custom_error.expected" run_native_x64_example examples/spectral.v spectral "$tmp/spectral_10.expected" 10 run_native_x64_example examples/quick_sort.v quick_sort "$tmp/quick_sort.expected" run_native_x64_example_with_stdin examples/get_raw_line.v get_raw_line "$tmp/get_raw_line.in" "$tmp/get_raw_line.expected" run_native_x64_example_with_stdin examples/mini_calculator.v mini_calculator "$tmp/mini_calculator.in" "$tmp/mini_calculator.expected" run_native_x64_example_with_stdin examples/mini_calculator_recursive_descent.v mini_calculator_recursive_descent "$tmp/mini_calculator_recursive_descent.in" "$tmp/mini_calculator_recursive_descent.expected" run_native_x64_example_capture examples/random_ips.v random_ips check_random_ips_stdout random_ips "$tmp/random_ips.out" run_native_x64_example_capture examples/rule110.v rule110 31 check_rule110_stdout rule110 "$tmp/rule110.out" 31 - name: All code is formatted run: v run ci/linux_ci.vsh all_code_is_formatted_gcc - name: Install dependencies for examples and tools run: v run ci/linux_ci.vsh install_dependencies_for_examples_and_tools_gcc - name: Recompile V with -cstrict and gcc run: v run ci/linux_ci.vsh recompile_v_with_cstrict_gcc - name: Valgrind v.c run: v run ci/linux_ci.vsh valgrind_v_c_gcc - name: Run sanitizers run: v run ci/linux_ci.vsh run_sanitizers_gcc - name: v self compilation run: v run ci/linux_ci.vsh v_self_compilation_gcc - name: v self compilation with -usecache run: v run ci/linux_ci.vsh v_self_compilation_usecache_gcc - name: Verify `v test` works run: v run ci/linux_ci.vsh verify_v_test_works_gcc - name: Test pure V math module run: v run ci/linux_ci.vsh test_pure_v_math_module_gcc - name: Self tests run: v run ci/linux_ci.vsh self_tests_gcc - name: Self tests (-prod) run: v run ci/linux_ci.vsh self_tests_prod_gcc - name: Self tests (-cstrict) run: v run ci/linux_ci.vsh self_tests_cstrict_gcc - name: Build examples run: v run ci/linux_ci.vsh build_examples_gcc - name: Build tetris with -autofree run: v run ci/linux_ci.vsh build_tetris_autofree_gcc - name: Build blog tutorial with -autofree run: v run ci/linux_ci.vsh build_blog_autofree_gcc - name: Build option_test.c.v with -autofree run: v run ci/linux_ci.vsh build_option_test_autofree_gcc - name: V self compilation with -parallel-cc run: v run ci/linux_ci.vsh v_self_compilation_parallel_cc_gcc - name: Build modules run: v run ci/linux_ci.vsh build_modules_gcc - name: compile vdoctor.v with -prod run: v run ci/linux_ci.vsh compile_vdoctor_prod_gcc - name: compile vup.v with -prod run: v run ci/linux_ci.vsh compile_vup_prod_gcc clang-linux: runs-on: ubuntu-24.04 timeout-minutes: 121 env: VFLAGS: -cc clang VTEST_SHOW_LONGEST_BY_RUNTIME: 3 VTEST_SHOW_LONGEST_BY_COMPTIME: 3 VTEST_SHOW_LONGEST_BY_TOTALTIME: 3 steps: - uses: actions/checkout@v7 - uses: ./.github/actions/cache-apt-packages-action - name: Build V run: make -j4 && ./v symlink - name: All code is formatted run: v run ci/linux_ci.vsh all_code_is_formatted_clang - name: Install dependencies for examples and tools run: v run ci/linux_ci.vsh install_dependencies_for_examples_and_tools_clang - name: Recompile V with -cstrict and clang run: v run ci/linux_ci.vsh recompile_v_with_cstrict_clang - name: Valgrind run: v run ci/linux_ci.vsh valgrind_clang - name: Run sanitizers run: v run ci/linux_ci.vsh run_sanitizers_clang - name: v self compilation run: v run ci/linux_ci.vsh v_self_compilation_clang - name: v self compilation with -usecache run: v run ci/linux_ci.vsh v_self_compilation_usecache_clang - name: Verify `v test` works run: v run ci/linux_ci.vsh verify_v_test_works_clang - name: Test pure V math module run: v run ci/linux_ci.vsh test_pure_v_math_module_clang - name: Self tests run: v run ci/linux_ci.vsh self_tests_clang - name: Self tests (vprod) run: v run ci/linux_ci.vsh self_tests_vprod_clang - name: Self tests (-cstrict) run: v run ci/linux_ci.vsh self_tests_cstrict_clang - name: Build examples run: v run ci/linux_ci.vsh build_examples_clang - name: Build examples with -autofree run: v run ci/linux_ci.vsh build_examples_autofree_clang - name: Build modules run: v run ci/linux_ci.vsh build_modules_clang