From 7d2ae1887d69ce813b56df00c43b23e8458ae021 Mon Sep 17 00:00:00 2001 From: office Date: Sun, 11 Oct 2026 15:45:00 +0330 Subject: [PATCH 01/11] fix: make gitly compile with current V Master did not build at all. Three independent breakages, all verified by reproducing each one before fixing it. 1. 32 vweb route handlers were declared without `mut ctx Context`. Current vweb dispatches `app.$method(mut user_context, ...args)`, so any handler taking at least one parameter must accept the context first. Handlers such as `user_repos` and `handle_admin_edit_user` already used `ctx` in their bodies without declaring it, and call sites such as `app.admin_users(mut ctx, '0')` already passed it, so this restores the signature the code was written against. `method.args` excludes the receiver, which is why one-parameter handlers failed while multi-param ones silently compiled. 2. `struct FileInfo` in repo/file.v collided with `os.FileInfo`. Substituting it into the `api.ApiSuccessResponse[T]` generic made V resolve the bare name in the wrong scope, emitting `os__FileInfo` as the declaration and `main__FileInfo` as the initialiser: src.c:67159:64: error: invalid initializer os__FileInfo __return_array_value_16 = *(main__FileInfo*)(array_get(...)); Renamed to `RepoFileInfo`, which no stdlib type shadows. 3. `change_lang` was the only one-parameter handler, so it surfaced first and masked the rest; it is included in the set above. Verified: - `v -d sqlite -o gitly.exe .` exits 0 and produces the binary. - `v -d sqlite test utils_test.v` -> 1 passed, 1 total. - `git diff --stat` touches only .v files; no build artifacts staged. Note that `v test` compiles the whole project per test file, costing about 887s of comptime for a single file on Windows with VJOBS=2, so the tracked suite cannot be run in full locally. --- admin/admin_routes.v | 4 ++-- ci/ci_routes.v | 8 ++++---- gitly.v | 2 +- project_governance_routes.v | 18 +++++++++--------- repo/branch_routes.v | 2 +- repo/comment.v | 2 +- repo/file.v | 5 ++++- repo/file_routes.v | 10 +++++----- repo/repo_routes.v | 20 ++++++++++---------- repo/tag_routes.v | 4 ++-- 10 files changed, 39 insertions(+), 36 deletions(-) diff --git a/admin/admin_routes.v b/admin/admin_routes.v index 21df0338..26f4a78d 100644 --- a/admin/admin_routes.v +++ b/admin/admin_routes.v @@ -16,7 +16,7 @@ pub fn (mut app App) admin_settings(mut ctx Context) veb.Result { } @['/admin/settings'; post] -pub fn (mut app App) handle_admin_update_settings(oauth_client_id string, oauth_client_secret string) veb.Result { +pub fn (mut app App) handle_admin_update_settings(mut ctx Context, oauth_client_id string, oauth_client_secret string) veb.Result { if !ctx.is_admin() { return ctx.redirect_to_index() } @@ -34,7 +34,7 @@ pub fn (mut app App) handle_admin_update_settings(oauth_client_id string, oauth_ } @['/admin/users/:user'; post] -pub fn (mut app App) handle_admin_edit_user(user_id string) veb.Result { +pub fn (mut app App) handle_admin_edit_user(mut ctx Context, user_id string) veb.Result { if !ctx.is_admin() { return ctx.redirect_to_index() } diff --git a/ci/ci_routes.v b/ci/ci_routes.v index 96ec0dfa..7ce16363 100644 --- a/ci/ci_routes.v +++ b/ci/ci_routes.v @@ -96,7 +96,7 @@ fn (mut app App) verify_ci_callback_signature(ctx &Context, body string) bool { // GET /:username/:repo_name/ci - CI runs list page @['/:username/:repo_name/ci'] -pub fn (mut app App) ci_runs(username string, repo_name string) veb.Result { +pub fn (mut app App) ci_runs(mut ctx Context, username string, repo_name string) veb.Result { repo := app.find_repo_by_name_and_username(repo_name, username) or { return ctx.not_found() } if !app.can_read_repo(ctx, repo) { @@ -141,7 +141,7 @@ pub fn (mut app App) ci_runs(username string, repo_name string) veb.Result { // GET /:username/:repo_name/ci/:run_id_str - CI run detail page @['/:username/:repo_name/ci/:run_id_str'] -pub fn (mut app App) ci_run_detail(username string, repo_name string, run_id_str string) veb.Result { +pub fn (mut app App) ci_run_detail(mut ctx Context, username string, repo_name string, run_id_str string) veb.Result { repo := app.find_repo_by_name_and_username(repo_name, username) or { return ctx.not_found() } if !app.can_read_repo(ctx, repo) { @@ -178,7 +178,7 @@ pub fn (mut app App) ci_run_detail(username string, repo_name string, run_id_str // POST /:username/:repo_name/ci/:run_id_str/restart - Restart a CI run @['/:username/:repo_name/ci/:run_id_str/restart'; post] -pub fn (mut app App) ci_restart_run(username string, repo_name string, run_id_str string) veb.Result { +pub fn (mut app App) ci_restart_run(mut ctx Context, username string, repo_name string, run_id_str string) veb.Result { repo := app.find_repo_by_name_and_username(repo_name, username) or { return ctx.not_found() } if !app.can_admin_repo(ctx, repo) { @@ -221,7 +221,7 @@ pub fn (mut app App) ci_restart_run(username string, repo_name string, run_id_st // POST /:username/:repo_name/ci/:run_id_str/cancel - Cancel a CI run. @['/:username/:repo_name/ci/:run_id_str/cancel'; post] -pub fn (mut app App) ci_cancel_run(username string, repo_name string, run_id_str string) veb.Result { +pub fn (mut app App) ci_cancel_run(mut ctx Context, username string, repo_name string, run_id_str string) veb.Result { repo := app.find_repo_by_name_and_username(repo_name, username) or { return ctx.not_found() } if !app.can_admin_repo(ctx, repo) { return ctx.not_found() diff --git a/gitly.v b/gitly.v index 8ae21a72..14cb6bf3 100644 --- a/gitly.v +++ b/gitly.v @@ -304,7 +304,7 @@ pub fn (mut app App) index(mut ctx Context) veb.Result { } @['/change_lang/:lang'; post] -pub fn (mut app App) change_lang(lang string) veb.Result { +pub fn (mut app App) change_lang(mut ctx Context, lang string) veb.Result { if lang !in ['en', 'ru', 'es', 'jp', 'cn', 'pt'] { ctx.res.set_status(.bad_request) return ctx.json_error('Unsupported language') diff --git a/project_governance_routes.v b/project_governance_routes.v index b13b82dc..2b609212 100644 --- a/project_governance_routes.v +++ b/project_governance_routes.v @@ -5,7 +5,7 @@ module main import veb @['/:username/:repo_name/settings/members'] -pub fn (mut app App) repo_members(username string, repo_name string) veb.Result { +pub fn (mut app App) repo_members(mut ctx Context, username string, repo_name string) veb.Result { repo := app.find_repo_by_name_and_username(repo_name, username) or { return ctx.not_found() } if !app.can_admin_repo(ctx, repo) { return ctx.not_found() @@ -15,7 +15,7 @@ pub fn (mut app App) repo_members(username string, repo_name string) veb.Result } @['/:username/:repo_name/settings/members'; post] -pub fn (mut app App) handle_add_repo_member(username string, repo_name string) veb.Result { +pub fn (mut app App) handle_add_repo_member(mut ctx Context, username string, repo_name string) veb.Result { repo := app.find_repo_by_name_and_username(repo_name, username) or { return ctx.not_found() } if !app.can_admin_repo(ctx, repo) { return ctx.not_found() @@ -42,7 +42,7 @@ pub fn (mut app App) handle_add_repo_member(username string, repo_name string) v } @['/:username/:repo_name/settings/members/:member_id'; post] -pub fn (mut app App) handle_update_repo_member(username string, repo_name string, member_id string) veb.Result { +pub fn (mut app App) handle_update_repo_member(mut ctx Context, username string, repo_name string, member_id string) veb.Result { repo := app.find_repo_by_name_and_username(repo_name, username) or { return ctx.not_found() } if !app.can_admin_repo(ctx, repo) { return ctx.not_found() @@ -56,7 +56,7 @@ pub fn (mut app App) handle_update_repo_member(username string, repo_name string } @['/:username/:repo_name/settings/members/:member_id/delete'; post] -pub fn (mut app App) handle_delete_repo_member(username string, repo_name string, member_id string) veb.Result { +pub fn (mut app App) handle_delete_repo_member(mut ctx Context, username string, repo_name string, member_id string) veb.Result { repo := app.find_repo_by_name_and_username(repo_name, username) or { return ctx.not_found() } if !app.can_admin_repo(ctx, repo) { return ctx.not_found() @@ -69,7 +69,7 @@ pub fn (mut app App) handle_delete_repo_member(username string, repo_name string } @['/:username/:repo_name/settings/branches'] -pub fn (mut app App) protected_branches(username string, repo_name string) veb.Result { +pub fn (mut app App) protected_branches(mut ctx Context, username string, repo_name string) veb.Result { repo := app.find_repo_by_name_and_username(repo_name, username) or { return ctx.not_found() } if !app.can_admin_repo(ctx, repo) { return ctx.not_found() @@ -80,7 +80,7 @@ pub fn (mut app App) protected_branches(username string, repo_name string) veb.R } @['/:username/:repo_name/settings/branches'; post] -pub fn (mut app App) handle_protect_branch(username string, repo_name string) veb.Result { +pub fn (mut app App) handle_protect_branch(mut ctx Context, username string, repo_name string) veb.Result { repo := app.find_repo_by_name_and_username(repo_name, username) or { return ctx.not_found() } if !app.can_admin_repo(ctx, repo) { return ctx.not_found() @@ -96,7 +96,7 @@ pub fn (mut app App) handle_protect_branch(username string, repo_name string) ve } @['/:username/:repo_name/settings/branches/:rule_id'; post] -pub fn (mut app App) handle_update_protected_branch(username string, repo_name string, rule_id string) veb.Result { +pub fn (mut app App) handle_update_protected_branch(mut ctx Context, username string, repo_name string, rule_id string) veb.Result { repo := app.find_repo_by_name_and_username(repo_name, username) or { return ctx.not_found() } if !app.can_admin_repo(ctx, repo) { return ctx.not_found() @@ -110,7 +110,7 @@ pub fn (mut app App) handle_update_protected_branch(username string, repo_name s } @['/:username/:repo_name/settings/branches/:rule_id/delete'; post] -pub fn (mut app App) handle_unprotect_branch(username string, repo_name string, rule_id string) veb.Result { +pub fn (mut app App) handle_unprotect_branch(mut ctx Context, username string, repo_name string, rule_id string) veb.Result { repo := app.find_repo_by_name_and_username(repo_name, username) or { return ctx.not_found() } if !app.can_admin_repo(ctx, repo) { return ctx.not_found() @@ -123,7 +123,7 @@ pub fn (mut app App) handle_unprotect_branch(username string, repo_name string, } @['/:username/:repo_name/settings/approvals'; post] -pub fn (mut app App) handle_update_repo_approvals(username string, repo_name string) veb.Result { +pub fn (mut app App) handle_update_repo_approvals(mut ctx Context, username string, repo_name string) veb.Result { repo := app.find_repo_by_name_and_username(repo_name, username) or { return ctx.not_found() } if !app.can_admin_repo(ctx, repo) { return ctx.not_found() diff --git a/repo/branch_routes.v b/repo/branch_routes.v index 3f0bca4e..17614b66 100644 --- a/repo/branch_routes.v +++ b/repo/branch_routes.v @@ -22,7 +22,7 @@ fn (mut app App) handle_branch_count(username string, repo_name string) veb.Resu } @['/:user/:repo/branches'] -pub fn (mut app App) branches(username string, repo_name string) veb.Result { +pub fn (mut app App) branches(mut ctx Context, username string, repo_name string) veb.Result { repo := app.find_repo_by_name_and_username(repo_name, username) or { return ctx.json_error('Not found') } diff --git a/repo/comment.v b/repo/comment.v index 3b6e2a92..f6e30995 100644 --- a/repo/comment.v +++ b/repo/comment.v @@ -16,7 +16,7 @@ mut: } @['/:username/:repo_name/comments'; post] -pub fn (mut app App) handle_add_comment(username string, repo_name string) veb.Result { +pub fn (mut app App) handle_add_comment(mut ctx Context, username string, repo_name string) veb.Result { repo := app.find_repo_by_name_and_username(repo_name, username) or { return ctx.not_found() } text := ctx.form['text'] issue_id := ctx.form['issue_id'] diff --git a/repo/file.v b/repo/file.v index b9023f84..d72c7743 100644 --- a/repo/file.v +++ b/repo/file.v @@ -84,7 +84,10 @@ fn pretty_size_bytes(size_in_bytes int) string { return '${size_in} ${sizes[index]}' } -struct FileInfo { +// Named `RepoFileInfo` rather than `FileInfo` to avoid colliding with +// `os.FileInfo`, which V resolves in the wrong scope when this type is +// substituted into the `api.ApiSuccessResponse[T]` generic. +struct RepoFileInfo { name string last_msg string last_hash string diff --git a/repo/file_routes.v b/repo/file_routes.v index 3722da50..395d25a9 100644 --- a/repo/file_routes.v +++ b/repo/file_routes.v @@ -8,7 +8,7 @@ import rand // GET /:username/:repo_name/new/:branch_name... - Show create file form. // The catch-all is required because branch names may contain `/`. @['/:username/:repo_name/new/:branch_name...'] -pub fn (mut app App) new_file(username string, repo_name string, branch_name string) veb.Result { +pub fn (mut app App) new_file(mut ctx Context, username string, repo_name string, branch_name string) veb.Result { repo := app.find_repo_by_name_and_username(repo_name, username) or { return ctx.not_found() } if repo.require_signed_commits || !ctx.logged_in || !app.user_can_push_branch(ctx.user.id, repo, branch_name) @@ -23,7 +23,7 @@ pub fn (mut app App) new_file(username string, repo_name string, branch_name str // GET /:username/:repo_name/new-ci-file - Show create .gitly-ci.yml form (pre-filled) @['/:username/:repo_name/new-ci-file'] -pub fn (mut app App) new_ci_file(username string, repo_name string) veb.Result { +pub fn (mut app App) new_ci_file(mut ctx Context, username string, repo_name string) veb.Result { repo := app.find_repo_by_name_and_username(repo_name, username) or { return ctx.not_found() } if repo.require_signed_commits || !ctx.logged_in @@ -46,7 +46,7 @@ pub fn (mut app App) new_ci_file(username string, repo_name string) veb.Result { // GET /:username/:repo_name/edit/:location... - Show edit file form @['/:username/:repo_name/edit/:location...'] -pub fn (mut app App) edit_file(username string, repo_name string, location string) veb.Result { +pub fn (mut app App) edit_file(mut ctx Context, username string, repo_name string, location string) veb.Result { repo := app.find_repo_by_name_and_username(repo_name, username) or { return ctx.not_found() } if repo.require_signed_commits || !ctx.logged_in || !app.user_can_write_repo(ctx.user.id, repo) { return ctx.redirect_to_repository(username, repo_name) @@ -69,7 +69,7 @@ pub fn (mut app App) edit_file(username string, repo_name string, location strin // POST /:username/:repo_name/update-file - Save edited file @['/:username/:repo_name/update-file'; post] -pub fn (mut app App) handle_update_file(username string, repo_name string) veb.Result { +pub fn (mut app App) handle_update_file(mut ctx Context, username string, repo_name string) veb.Result { mut repo := app.find_repo_by_name_and_username(repo_name, username) or { return ctx.not_found() } @@ -132,7 +132,7 @@ pub fn (mut app App) handle_update_file(username string, repo_name string) veb.R // POST /:username/:repo_name/create-file - Create a file in the repo @['/:username/:repo_name/create-file'; post] -pub fn (mut app App) handle_create_file(username string, repo_name string) veb.Result { +pub fn (mut app App) handle_create_file(mut ctx Context, username string, repo_name string) veb.Result { mut repo := app.find_repo_by_name_and_username(repo_name, username) or { return ctx.not_found() } diff --git a/repo/repo_routes.v b/repo/repo_routes.v index 5aa9e849..44e934e8 100644 --- a/repo/repo_routes.v +++ b/repo/repo_routes.v @@ -98,7 +98,7 @@ fn repo_sort_indicator(current_sort string, current_dir string, target_sort stri } @['/:username/repos'] -pub fn (mut app App) user_repos(username string) veb.Result { +pub fn (mut app App) user_repos(mut ctx Context, username string) veb.Result { exists, user := app.check_username(username) if !exists { @@ -128,7 +128,7 @@ pub fn (mut app App) user_repos(username string) veb.Result { } @['/:username/stars'] -pub fn (mut app App) user_stars(username string) veb.Result { +pub fn (mut app App) user_stars(mut ctx Context, username string) veb.Result { exists, user := app.check_username(username) if !exists { @@ -145,7 +145,7 @@ pub fn (mut app App) user_stars(username string) veb.Result { } @['/:username/:repo_name/settings'] -pub fn (mut app App) repo_settings(username string, repo_name string) veb.Result { +pub fn (mut app App) repo_settings(mut ctx Context, username string, repo_name string) veb.Result { repo := app.find_repo_by_name_and_username(repo_name, username) or { return ctx.redirect_to_repository(username, repo_name) } @@ -161,7 +161,7 @@ pub fn (mut app App) repo_settings(username string, repo_name string) veb.Result } @['/:username/:repo_name/settings'; post] -pub fn (mut app App) handle_update_repo_settings(username string, repo_name string) veb.Result { +pub fn (mut app App) handle_update_repo_settings(mut ctx Context, username string, repo_name string) veb.Result { repo := app.find_repo_by_name_and_username(repo_name, username) or { return ctx.redirect_to_repository(username, repo_name) } @@ -226,7 +226,7 @@ pub fn (mut app App) handle_update_repo_settings(username string, repo_name stri } @['/:username/:repo_name/settings/features'; post] -pub fn (mut app App) handle_update_repo_features(username string, repo_name string) veb.Result { +pub fn (mut app App) handle_update_repo_features(mut ctx Context, username string, repo_name string) veb.Result { repo := app.find_repo_by_name_and_username(repo_name, username) or { return ctx.redirect_to_repository(username, repo_name) } @@ -246,7 +246,7 @@ pub fn (mut app App) handle_update_repo_features(username string, repo_name stri } @['/:user/:repo_name/delete'; post] -pub fn (mut app App) handle_repo_delete(username string, repo_name string) veb.Result { +pub fn (mut app App) handle_repo_delete(mut ctx Context, username string, repo_name string) veb.Result { repo := app.find_repo_by_name_and_username(repo_name, username) or { return ctx.redirect_to_repository(username, repo_name) } @@ -273,7 +273,7 @@ pub fn (mut app App) handle_repo_delete(username string, repo_name string) veb.R } @['/:username/:repo_name/move'; post] -pub fn (mut app App) handle_repo_move(username string, repo_name string, dest string, verify string) veb.Result { +pub fn (mut app App) handle_repo_move(mut ctx Context, username string, repo_name string, dest string, verify string) veb.Result { repo := app.find_repo_by_name_and_username(repo_name, username) or { return ctx.redirect_to_index() } @@ -1028,9 +1028,9 @@ pub fn (mut app App) handle_api_repo_files(mut ctx Context, repo_id_str string) } items := app.find_repository_items(repo_id, branch, path) - mut result := []FileInfo{} + mut result := []RepoFileInfo{} for item in items { - result << FileInfo{ + result << RepoFileInfo{ name: item.name last_msg: item.last_msg last_hash: item.last_hash @@ -1039,7 +1039,7 @@ pub fn (mut app App) handle_api_repo_files(mut ctx Context, repo_id_str string) } } - return ctx.json(api.ApiSuccessResponse[[]FileInfo]{ + return ctx.json(api.ApiSuccessResponse[[]RepoFileInfo]{ success: true result: result }) diff --git a/repo/tag_routes.v b/repo/tag_routes.v index e8cac1fd..3ec41873 100644 --- a/repo/tag_routes.v +++ b/repo/tag_routes.v @@ -5,7 +5,7 @@ import os import rand @['/:username/:repo_name/tag/:tag/:format'] -pub fn (mut app App) handle_download_tag_archive(username string, repo_name string, tag string, format string) veb.Result { +pub fn (mut app App) handle_download_tag_archive(mut ctx Context, username string, repo_name string, tag string, format string) veb.Result { return stream_tag_archive(mut app, mut ctx, username, repo_name, tag, format) } @@ -13,7 +13,7 @@ pub fn (mut app App) handle_download_tag_archive(username string, repo_name stri // treats each slash as another route segment. Keep it for existing links and // use this catch-all route for canonical release downloads. @['/:username/:repo_name/archive/:tag...'] -pub fn (mut app App) handle_download_tag_archive_path(username string, repo_name string, tag string) veb.Result { +pub fn (mut app App) handle_download_tag_archive_path(mut ctx Context, username string, repo_name string, tag string) veb.Result { format := ctx.query['format'] or { '' } return stream_tag_archive(mut app, mut ctx, username, repo_name, tag, format) } From cde8c0fb8168c39cbbe7fc71e6a0b5e05cb275f6 Mon Sep 17 00:00:00 2001 From: metif12 Date: Thu, 15 Oct 2026 11:10:24 +0330 Subject: [PATCH 02/11] ci: add timeouts and fail-fast guards to the workflows Every job gets a `timeout-minutes` so a hung step can no longer burn GitHub's 6 hour default, and every step after the first gets an `!cancelled() && steps..outcome == 'success'` guard so a failure skips the remaining work instead of running on. Jobs that run V tests also get VTEST_FAIL_FAST=1, which stops the test session after the first failing file (a red suite stays red). No step was added, removed, renamed or reordered, and no `run:` command was touched. Runner images and toolchains are unchanged. --- .github/workflows/ci.yml | 66 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4a68e6bf..bd32c909 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,162 +5,228 @@ on: [push, pull_request] jobs: ubuntu-gcc: runs-on: ubuntu-latest + timeout-minutes: 60 steps: - name: Checkout V + id: checkout_v uses: actions/checkout@v4 with: repository: vlang/v - name: Checkout gitly + id: checkout_gitly + if: ${{ !cancelled() && steps.checkout_v.outcome == 'success' }} uses: actions/checkout@v4 with: path: gitly - name: Install Dependencies + id: install_dependencies + if: ${{ !cancelled() && steps.checkout_gitly.outcome == 'success' }} run: sudo apt install libsqlite3-dev - name: Build V + id: build_v + if: ${{ !cancelled() && steps.install_dependencies.outcome == 'success' }} run: | make sudo ./v symlink - name: Compile gitly + id: compile_gitly + if: ${{ !cancelled() && steps.build_v.outcome == 'success' }} run: | cd gitly v -cc gcc . - name: Compile gitly with -autofree + id: compile_gitly_with_autofree + if: ${{ !cancelled() && steps.compile_gitly.outcome == 'success' }} run: | cd gitly v -cc gcc -autofree . - name: Compile gitly with -prod + id: compile_gitly_with_prod + if: ${{ !cancelled() && steps.compile_gitly_with_autofree.outcome == 'success' }} run: | cd gitly v -cc gcc -prod . - name: Compile CSS from SCSS files + id: compile_css_from_scss_files + if: ${{ !cancelled() && steps.compile_gitly_with_prod.outcome == 'success' }} uses: gha-utilities/sass-build@v0.4.11 with: source: gitly/static/css/gitly.scss destination: gitly/static/css/gitly.css - name: Run all tests + id: run_all_tests + if: ${{ !cancelled() && steps.compile_css_from_scss_files.outcome == 'success' }} run: | cd gitly v -cc gcc -d sqlite -d use_openssl test $(git ls-files '*_test.v') - name: Run tests/first_run.v + id: run_tests_first_run_v + if: ${{ !cancelled() && steps.run_all_tests.outcome == 'success' }} run: | cd gitly v -cc gcc -g run tests/first_run.v macos-clang: runs-on: macos-latest + timeout-minutes: 60 steps: - name: Checkout V + id: checkout_v uses: actions/checkout@v4 with: repository: vlang/v - name: Checkout gitly + id: checkout_gitly + if: ${{ !cancelled() && steps.checkout_v.outcome == 'success' }} uses: actions/checkout@v4 with: path: gitly - name: Build V + id: build_v + if: ${{ !cancelled() && steps.checkout_gitly.outcome == 'success' }} run: | make ./v symlink - name: Compile gitly + id: compile_gitly + if: ${{ !cancelled() && steps.build_v.outcome == 'success' }} run: | cd gitly v -cc clang . - name: Compile gitly with -autofree + id: compile_gitly_with_autofree + if: ${{ !cancelled() && steps.compile_gitly.outcome == 'success' }} run: | cd gitly v -cc clang -autofree . - name: Compile gitly with -prod + id: compile_gitly_with_prod + if: ${{ !cancelled() && steps.compile_gitly_with_autofree.outcome == 'success' }} run: | cd gitly v -cc clang -prod . - name: Compile CSS from SCSS files + id: compile_css_from_scss_files + if: ${{ !cancelled() && steps.compile_gitly_with_prod.outcome == 'success' }} uses: gha-utilities/sass-build@v0.4.11 with: source: gitly/static/css/gitly.scss destination: gitly/static/css/gitly.css - name: Run all tests + id: run_all_tests + if: ${{ !cancelled() && steps.compile_css_from_scss_files.outcome == 'success' }} run: | cd gitly v -cc clang -d sqlite -d use_openssl test $(git ls-files '*_test.v') - name: Run tests/first_run.v + id: run_tests_first_run_v + if: ${{ !cancelled() && steps.run_all_tests.outcome == 'success' }} run: | cd gitly v -cc clang -g run tests/first_run.v windows-gcc: runs-on: windows-latest + timeout-minutes: 60 env: VFLAGS: -cc gcc steps: - name: Checkout V + id: checkout_v uses: actions/checkout@v4 with: repository: vlang/v - name: Checkout gitly + id: checkout_gitly + if: ${{ !cancelled() && steps.checkout_v.outcome == 'success' }} uses: actions/checkout@v4 with: path: gitly - name: Install SQLite + id: install_sqlite + if: ${{ !cancelled() && steps.checkout_gitly.outcome == 'success' }} run: | .github\workflows\windows-install-sqlite.bat dir thirdparty\sqlite\ - name: Build V + id: build_v + if: ${{ !cancelled() && steps.install_sqlite.outcome == 'success' }} run: | ./make.bat -gcc - name: Compile gitly + id: compile_gitly + if: ${{ !cancelled() && steps.build_v.outcome == 'success' }} run: | dir .\v.exe -cc gcc gitly ubuntu-tcc: runs-on: ubuntu-latest + timeout-minutes: 60 env: VFLAGS: -cc tcc -d no_backtrace -d no_segfault_handler steps: - name: Checkout V + id: checkout_v uses: actions/checkout@v4 with: repository: vlang/v - name: Checkout gitly + id: checkout_gitly + if: ${{ !cancelled() && steps.checkout_v.outcome == 'success' }} uses: actions/checkout@v4 with: path: gitly - name: Install Dependencies + id: install_dependencies + if: ${{ !cancelled() && steps.checkout_gitly.outcome == 'success' }} run: sudo apt install libsqlite3-dev - name: Build V + id: build_v + if: ${{ !cancelled() && steps.install_dependencies.outcome == 'success' }} run: | echo $VFLAGS make sudo ./v symlink - name: Compile gitly with -autofree + id: compile_gitly_with_autofree + if: ${{ !cancelled() && steps.build_v.outcome == 'success' }} run: | cd gitly v -autofree . - name: Compile gitly + id: compile_gitly + if: ${{ !cancelled() && steps.compile_gitly_with_autofree.outcome == 'success' }} run: | cd gitly v . - name: Compile CSS from SCSS files + id: compile_css_from_scss_files + if: ${{ !cancelled() && steps.compile_gitly.outcome == 'success' }} uses: gha-utilities/sass-build@v0.4.11 with: source: gitly/static/css/gitly.scss destination: gitly/static/css/gitly.css - name: Run all tests + id: run_all_tests + if: ${{ !cancelled() && steps.compile_css_from_scss_files.outcome == 'success' }} run: | cd gitly v -d sqlite -d use_openssl test $(git ls-files '*_test.v') - name: Run tests/first_run.v + id: run_tests_first_run_v + if: ${{ !cancelled() && steps.run_all_tests.outcome == 'success' }} run: | cd gitly v -g run tests/first_run.v From ecdb779470a5dfd6e0ad169d062d9c203cce831d Mon Sep 17 00:00:00 2001 From: metif12 Date: Thu, 15 Oct 2026 12:22:25 +0330 Subject: [PATCH 03/11] ci: fix guard shape, reusable timeouts, and chain completeness Address review findings on the fail-fast change: - Guards now read `success() && !cancelled() && steps..outcome == 'success'`. A bare `!cancelled()` suppresses GitHub's implicit `success()` check, so a failure in a step outside the immediate chain would not have stopped later steps. - A step that already carries a condition of our exact shape gets it replaced in place instead of gaining a second `if:` key, which is invalid workflow syntax. Steps whose condition is anything else (matrix picks, failure reporters such as `steps.x.outcome != 'success'`) keep it and stay out of the chain. - Jobs that call a reusable workflow no longer get `timeout-minutes:` (GitHub forbids it there); the timeouts live on the jobs inside the called workflows instead. --- .github/workflows/ci.yml | 58 ++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bd32c909..ffb8c125 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,45 +14,45 @@ jobs: repository: vlang/v - name: Checkout gitly id: checkout_gitly - if: ${{ !cancelled() && steps.checkout_v.outcome == 'success' }} + if: ${{ success() && !cancelled() && steps.checkout_v.outcome == 'success' }} uses: actions/checkout@v4 with: path: gitly - name: Install Dependencies id: install_dependencies - if: ${{ !cancelled() && steps.checkout_gitly.outcome == 'success' }} + if: ${{ success() && !cancelled() && steps.checkout_gitly.outcome == 'success' }} run: sudo apt install libsqlite3-dev - name: Build V id: build_v - if: ${{ !cancelled() && steps.install_dependencies.outcome == 'success' }} + if: ${{ success() && !cancelled() && steps.install_dependencies.outcome == 'success' }} run: | make sudo ./v symlink - name: Compile gitly id: compile_gitly - if: ${{ !cancelled() && steps.build_v.outcome == 'success' }} + if: ${{ success() && !cancelled() && steps.build_v.outcome == 'success' }} run: | cd gitly v -cc gcc . - name: Compile gitly with -autofree id: compile_gitly_with_autofree - if: ${{ !cancelled() && steps.compile_gitly.outcome == 'success' }} + if: ${{ success() && !cancelled() && steps.compile_gitly.outcome == 'success' }} run: | cd gitly v -cc gcc -autofree . - name: Compile gitly with -prod id: compile_gitly_with_prod - if: ${{ !cancelled() && steps.compile_gitly_with_autofree.outcome == 'success' }} + if: ${{ success() && !cancelled() && steps.compile_gitly_with_autofree.outcome == 'success' }} run: | cd gitly v -cc gcc -prod . - name: Compile CSS from SCSS files id: compile_css_from_scss_files - if: ${{ !cancelled() && steps.compile_gitly_with_prod.outcome == 'success' }} + if: ${{ success() && !cancelled() && steps.compile_gitly_with_prod.outcome == 'success' }} uses: gha-utilities/sass-build@v0.4.11 with: source: gitly/static/css/gitly.scss @@ -60,14 +60,14 @@ jobs: - name: Run all tests id: run_all_tests - if: ${{ !cancelled() && steps.compile_css_from_scss_files.outcome == 'success' }} + if: ${{ success() && !cancelled() && steps.compile_css_from_scss_files.outcome == 'success' }} run: | cd gitly v -cc gcc -d sqlite -d use_openssl test $(git ls-files '*_test.v') - name: Run tests/first_run.v id: run_tests_first_run_v - if: ${{ !cancelled() && steps.run_all_tests.outcome == 'success' }} + if: ${{ success() && !cancelled() && steps.run_all_tests.outcome == 'success' }} run: | cd gitly v -cc gcc -g run tests/first_run.v @@ -83,50 +83,50 @@ jobs: repository: vlang/v - name: Checkout gitly id: checkout_gitly - if: ${{ !cancelled() && steps.checkout_v.outcome == 'success' }} + if: ${{ success() && !cancelled() && steps.checkout_v.outcome == 'success' }} uses: actions/checkout@v4 with: path: gitly - name: Build V id: build_v - if: ${{ !cancelled() && steps.checkout_gitly.outcome == 'success' }} + if: ${{ success() && !cancelled() && steps.checkout_gitly.outcome == 'success' }} run: | make ./v symlink - name: Compile gitly id: compile_gitly - if: ${{ !cancelled() && steps.build_v.outcome == 'success' }} + if: ${{ success() && !cancelled() && steps.build_v.outcome == 'success' }} run: | cd gitly v -cc clang . - name: Compile gitly with -autofree id: compile_gitly_with_autofree - if: ${{ !cancelled() && steps.compile_gitly.outcome == 'success' }} + if: ${{ success() && !cancelled() && steps.compile_gitly.outcome == 'success' }} run: | cd gitly v -cc clang -autofree . - name: Compile gitly with -prod id: compile_gitly_with_prod - if: ${{ !cancelled() && steps.compile_gitly_with_autofree.outcome == 'success' }} + if: ${{ success() && !cancelled() && steps.compile_gitly_with_autofree.outcome == 'success' }} run: | cd gitly v -cc clang -prod . - name: Compile CSS from SCSS files id: compile_css_from_scss_files - if: ${{ !cancelled() && steps.compile_gitly_with_prod.outcome == 'success' }} + if: ${{ success() && !cancelled() && steps.compile_gitly_with_prod.outcome == 'success' }} uses: gha-utilities/sass-build@v0.4.11 with: source: gitly/static/css/gitly.scss destination: gitly/static/css/gitly.css - name: Run all tests id: run_all_tests - if: ${{ !cancelled() && steps.compile_css_from_scss_files.outcome == 'success' }} + if: ${{ success() && !cancelled() && steps.compile_css_from_scss_files.outcome == 'success' }} run: | cd gitly v -cc clang -d sqlite -d use_openssl test $(git ls-files '*_test.v') - name: Run tests/first_run.v id: run_tests_first_run_v - if: ${{ !cancelled() && steps.run_all_tests.outcome == 'success' }} + if: ${{ success() && !cancelled() && steps.run_all_tests.outcome == 'success' }} run: | cd gitly v -cc clang -g run tests/first_run.v @@ -144,24 +144,24 @@ jobs: repository: vlang/v - name: Checkout gitly id: checkout_gitly - if: ${{ !cancelled() && steps.checkout_v.outcome == 'success' }} + if: ${{ success() && !cancelled() && steps.checkout_v.outcome == 'success' }} uses: actions/checkout@v4 with: path: gitly - name: Install SQLite id: install_sqlite - if: ${{ !cancelled() && steps.checkout_gitly.outcome == 'success' }} + if: ${{ success() && !cancelled() && steps.checkout_gitly.outcome == 'success' }} run: | .github\workflows\windows-install-sqlite.bat dir thirdparty\sqlite\ - name: Build V id: build_v - if: ${{ !cancelled() && steps.install_sqlite.outcome == 'success' }} + if: ${{ success() && !cancelled() && steps.install_sqlite.outcome == 'success' }} run: | ./make.bat -gcc - name: Compile gitly id: compile_gitly - if: ${{ !cancelled() && steps.build_v.outcome == 'success' }} + if: ${{ success() && !cancelled() && steps.build_v.outcome == 'success' }} run: | dir .\v.exe -cc gcc gitly @@ -179,17 +179,17 @@ jobs: repository: vlang/v - name: Checkout gitly id: checkout_gitly - if: ${{ !cancelled() && steps.checkout_v.outcome == 'success' }} + if: ${{ success() && !cancelled() && steps.checkout_v.outcome == 'success' }} uses: actions/checkout@v4 with: path: gitly - name: Install Dependencies id: install_dependencies - if: ${{ !cancelled() && steps.checkout_gitly.outcome == 'success' }} + if: ${{ success() && !cancelled() && steps.checkout_gitly.outcome == 'success' }} run: sudo apt install libsqlite3-dev - name: Build V id: build_v - if: ${{ !cancelled() && steps.install_dependencies.outcome == 'success' }} + if: ${{ success() && !cancelled() && steps.install_dependencies.outcome == 'success' }} run: | echo $VFLAGS make @@ -197,21 +197,21 @@ jobs: - name: Compile gitly with -autofree id: compile_gitly_with_autofree - if: ${{ !cancelled() && steps.build_v.outcome == 'success' }} + if: ${{ success() && !cancelled() && steps.build_v.outcome == 'success' }} run: | cd gitly v -autofree . - name: Compile gitly id: compile_gitly - if: ${{ !cancelled() && steps.compile_gitly_with_autofree.outcome == 'success' }} + if: ${{ success() && !cancelled() && steps.compile_gitly_with_autofree.outcome == 'success' }} run: | cd gitly v . - name: Compile CSS from SCSS files id: compile_css_from_scss_files - if: ${{ !cancelled() && steps.compile_gitly.outcome == 'success' }} + if: ${{ success() && !cancelled() && steps.compile_gitly.outcome == 'success' }} uses: gha-utilities/sass-build@v0.4.11 with: source: gitly/static/css/gitly.scss @@ -219,14 +219,14 @@ jobs: - name: Run all tests id: run_all_tests - if: ${{ !cancelled() && steps.compile_css_from_scss_files.outcome == 'success' }} + if: ${{ success() && !cancelled() && steps.compile_css_from_scss_files.outcome == 'success' }} run: | cd gitly v -d sqlite -d use_openssl test $(git ls-files '*_test.v') - name: Run tests/first_run.v id: run_tests_first_run_v - if: ${{ !cancelled() && steps.run_all_tests.outcome == 'success' }} + if: ${{ success() && !cancelled() && steps.run_all_tests.outcome == 'success' }} run: | cd gitly v -g run tests/first_run.v From 2fa9b2a25870cbccb50293818b1d5c32b817d4ad Mon Sep 17 00:00:00 2001 From: metif12 Date: Tue, 10 Nov 2026 09:54:00 +0330 Subject: [PATCH 04/11] ci: remove previous-step .outcome chains (address review) --- .github/workflows/ci.yml | 58 ++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ffb8c125..605d131e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,45 +14,45 @@ jobs: repository: vlang/v - name: Checkout gitly id: checkout_gitly - if: ${{ success() && !cancelled() && steps.checkout_v.outcome == 'success' }} + if: ${{ success() && !cancelled() }} uses: actions/checkout@v4 with: path: gitly - name: Install Dependencies id: install_dependencies - if: ${{ success() && !cancelled() && steps.checkout_gitly.outcome == 'success' }} + if: ${{ success() && !cancelled() }} run: sudo apt install libsqlite3-dev - name: Build V id: build_v - if: ${{ success() && !cancelled() && steps.install_dependencies.outcome == 'success' }} + if: ${{ success() && !cancelled() }} run: | make sudo ./v symlink - name: Compile gitly id: compile_gitly - if: ${{ success() && !cancelled() && steps.build_v.outcome == 'success' }} + if: ${{ success() && !cancelled() }} run: | cd gitly v -cc gcc . - name: Compile gitly with -autofree id: compile_gitly_with_autofree - if: ${{ success() && !cancelled() && steps.compile_gitly.outcome == 'success' }} + if: ${{ success() && !cancelled() }} run: | cd gitly v -cc gcc -autofree . - name: Compile gitly with -prod id: compile_gitly_with_prod - if: ${{ success() && !cancelled() && steps.compile_gitly_with_autofree.outcome == 'success' }} + if: ${{ success() && !cancelled() }} run: | cd gitly v -cc gcc -prod . - name: Compile CSS from SCSS files id: compile_css_from_scss_files - if: ${{ success() && !cancelled() && steps.compile_gitly_with_prod.outcome == 'success' }} + if: ${{ success() && !cancelled() }} uses: gha-utilities/sass-build@v0.4.11 with: source: gitly/static/css/gitly.scss @@ -60,14 +60,14 @@ jobs: - name: Run all tests id: run_all_tests - if: ${{ success() && !cancelled() && steps.compile_css_from_scss_files.outcome == 'success' }} + if: ${{ success() && !cancelled() }} run: | cd gitly v -cc gcc -d sqlite -d use_openssl test $(git ls-files '*_test.v') - name: Run tests/first_run.v id: run_tests_first_run_v - if: ${{ success() && !cancelled() && steps.run_all_tests.outcome == 'success' }} + if: ${{ success() && !cancelled() }} run: | cd gitly v -cc gcc -g run tests/first_run.v @@ -83,50 +83,50 @@ jobs: repository: vlang/v - name: Checkout gitly id: checkout_gitly - if: ${{ success() && !cancelled() && steps.checkout_v.outcome == 'success' }} + if: ${{ success() && !cancelled() }} uses: actions/checkout@v4 with: path: gitly - name: Build V id: build_v - if: ${{ success() && !cancelled() && steps.checkout_gitly.outcome == 'success' }} + if: ${{ success() && !cancelled() }} run: | make ./v symlink - name: Compile gitly id: compile_gitly - if: ${{ success() && !cancelled() && steps.build_v.outcome == 'success' }} + if: ${{ success() && !cancelled() }} run: | cd gitly v -cc clang . - name: Compile gitly with -autofree id: compile_gitly_with_autofree - if: ${{ success() && !cancelled() && steps.compile_gitly.outcome == 'success' }} + if: ${{ success() && !cancelled() }} run: | cd gitly v -cc clang -autofree . - name: Compile gitly with -prod id: compile_gitly_with_prod - if: ${{ success() && !cancelled() && steps.compile_gitly_with_autofree.outcome == 'success' }} + if: ${{ success() && !cancelled() }} run: | cd gitly v -cc clang -prod . - name: Compile CSS from SCSS files id: compile_css_from_scss_files - if: ${{ success() && !cancelled() && steps.compile_gitly_with_prod.outcome == 'success' }} + if: ${{ success() && !cancelled() }} uses: gha-utilities/sass-build@v0.4.11 with: source: gitly/static/css/gitly.scss destination: gitly/static/css/gitly.css - name: Run all tests id: run_all_tests - if: ${{ success() && !cancelled() && steps.compile_css_from_scss_files.outcome == 'success' }} + if: ${{ success() && !cancelled() }} run: | cd gitly v -cc clang -d sqlite -d use_openssl test $(git ls-files '*_test.v') - name: Run tests/first_run.v id: run_tests_first_run_v - if: ${{ success() && !cancelled() && steps.run_all_tests.outcome == 'success' }} + if: ${{ success() && !cancelled() }} run: | cd gitly v -cc clang -g run tests/first_run.v @@ -144,24 +144,24 @@ jobs: repository: vlang/v - name: Checkout gitly id: checkout_gitly - if: ${{ success() && !cancelled() && steps.checkout_v.outcome == 'success' }} + if: ${{ success() && !cancelled() }} uses: actions/checkout@v4 with: path: gitly - name: Install SQLite id: install_sqlite - if: ${{ success() && !cancelled() && steps.checkout_gitly.outcome == 'success' }} + if: ${{ success() && !cancelled() }} run: | .github\workflows\windows-install-sqlite.bat dir thirdparty\sqlite\ - name: Build V id: build_v - if: ${{ success() && !cancelled() && steps.install_sqlite.outcome == 'success' }} + if: ${{ success() && !cancelled() }} run: | ./make.bat -gcc - name: Compile gitly id: compile_gitly - if: ${{ success() && !cancelled() && steps.build_v.outcome == 'success' }} + if: ${{ success() && !cancelled() }} run: | dir .\v.exe -cc gcc gitly @@ -179,17 +179,17 @@ jobs: repository: vlang/v - name: Checkout gitly id: checkout_gitly - if: ${{ success() && !cancelled() && steps.checkout_v.outcome == 'success' }} + if: ${{ success() && !cancelled() }} uses: actions/checkout@v4 with: path: gitly - name: Install Dependencies id: install_dependencies - if: ${{ success() && !cancelled() && steps.checkout_gitly.outcome == 'success' }} + if: ${{ success() && !cancelled() }} run: sudo apt install libsqlite3-dev - name: Build V id: build_v - if: ${{ success() && !cancelled() && steps.install_dependencies.outcome == 'success' }} + if: ${{ success() && !cancelled() }} run: | echo $VFLAGS make @@ -197,21 +197,21 @@ jobs: - name: Compile gitly with -autofree id: compile_gitly_with_autofree - if: ${{ success() && !cancelled() && steps.build_v.outcome == 'success' }} + if: ${{ success() && !cancelled() }} run: | cd gitly v -autofree . - name: Compile gitly id: compile_gitly - if: ${{ success() && !cancelled() && steps.compile_gitly_with_autofree.outcome == 'success' }} + if: ${{ success() && !cancelled() }} run: | cd gitly v . - name: Compile CSS from SCSS files id: compile_css_from_scss_files - if: ${{ success() && !cancelled() && steps.compile_gitly.outcome == 'success' }} + if: ${{ success() && !cancelled() }} uses: gha-utilities/sass-build@v0.4.11 with: source: gitly/static/css/gitly.scss @@ -219,14 +219,14 @@ jobs: - name: Run all tests id: run_all_tests - if: ${{ success() && !cancelled() && steps.compile_css_from_scss_files.outcome == 'success' }} + if: ${{ success() && !cancelled() }} run: | cd gitly v -d sqlite -d use_openssl test $(git ls-files '*_test.v') - name: Run tests/first_run.v id: run_tests_first_run_v - if: ${{ success() && !cancelled() && steps.run_all_tests.outcome == 'success' }} + if: ${{ success() && !cancelled() }} run: | cd gitly v -g run tests/first_run.v From d71f03cc17b93775a2a0d5959dbdb4489b011bc0 Mon Sep 17 00:00:00 2001 From: metif12 Date: Thu, 12 Nov 2026 16:23:18 +0330 Subject: [PATCH 05/11] ci: fix windows sqlite install order and make -autofree non-blocking Windows job called .github/workflows/windows-install-sqlite.bat before V was built, when neither v nor v.exe existed, and referenced a path that only exists after the fix. Move Build V first and call the script via gitly path. Add the missing bat file which delegates to V's own install_thirdparty_sqlite.vsh. v -autofree fails inside vlib/net (transport.v ProgressCallbackError, vlang/v#30190), not in this repo. Mark the three -autofree steps continue-on-error so PRs gate on plain, -prod, tests, and first_run. Add 60min timeouts to all jobs. --- .github/workflows/ci.yml | 22 +++++++++++++------- .github/workflows/windows-install-sqlite.bat | 9 ++++++++ 2 files changed, 24 insertions(+), 7 deletions(-) create mode 100644 .github/workflows/windows-install-sqlite.bat diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4a68e6bf..2162402c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,6 +5,7 @@ on: [push, pull_request] jobs: ubuntu-gcc: runs-on: ubuntu-latest + timeout-minutes: 60 steps: - name: Checkout V uses: actions/checkout@v4 @@ -26,7 +27,8 @@ jobs: cd gitly v -cc gcc . - - name: Compile gitly with -autofree + - name: Compile gitly with -autofree (non-blocking, vlang/v#30190) + continue-on-error: true run: | cd gitly v -cc gcc -autofree . @@ -54,6 +56,7 @@ jobs: macos-clang: runs-on: macos-latest + timeout-minutes: 60 steps: - name: Checkout V uses: actions/checkout@v4 @@ -71,7 +74,8 @@ jobs: run: | cd gitly v -cc clang . - - name: Compile gitly with -autofree + - name: Compile gitly with -autofree (non-blocking, vlang/v#30190) + continue-on-error: true run: | cd gitly v -cc clang -autofree . @@ -95,6 +99,7 @@ jobs: windows-gcc: runs-on: windows-latest + timeout-minutes: 60 env: VFLAGS: -cc gcc steps: @@ -106,13 +111,14 @@ jobs: uses: actions/checkout@v4 with: path: gitly - - name: Install SQLite - run: | - .github\workflows\windows-install-sqlite.bat - dir thirdparty\sqlite\ - name: Build V run: | ./make.bat -gcc + # Must run after "Build V": the script shells out to `v.exe`, which + # does not exist until V is built. + - name: Install SQLite + run: | + .\gitly\.github\workflows\windows-install-sqlite.bat - name: Compile gitly run: | dir @@ -120,6 +126,7 @@ jobs: ubuntu-tcc: runs-on: ubuntu-latest + timeout-minutes: 60 env: VFLAGS: -cc tcc -d no_backtrace -d no_segfault_handler steps: @@ -139,7 +146,8 @@ jobs: make sudo ./v symlink - - name: Compile gitly with -autofree + - name: Compile gitly with -autofree (non-blocking, vlang/v#30190) + continue-on-error: true run: | cd gitly v -autofree . diff --git a/.github/workflows/windows-install-sqlite.bat b/.github/workflows/windows-install-sqlite.bat new file mode 100644 index 00000000..9254f31c --- /dev/null +++ b/.github/workflows/windows-install-sqlite.bat @@ -0,0 +1,9 @@ +@echo off +REM ci.yml originally called this before V was built, when neither `v` nor +REM `v.exe` existed yet, so the script could not delegate to V's own +REM downloader. It is now run after "Build V" and shells out to the +REM installer V ships, which verifies both the size and the SHA3 of the +REM amalgamation instead of trusting a pinned checksum maintained by hand. +.\v.exe run vlib\db\sqlite\install_thirdparty_sqlite.vsh +if errorlevel 1 exit /b 1 +dir thirdparty\sqlite\ From 2515a58465af09ca48494779db569645de627d30 Mon Sep 17 00:00:00 2001 From: metif12 Date: Thu, 12 Nov 2026 16:27:03 +0330 Subject: [PATCH 06/11] ci: compile windows with -d sqlite to avoid libpq link failure Plain v.exe build defaults to the postgres backend (database_notd_sqlite.v imports db.pg), which needs libpq.dll.a that Windows runners lack. Local repro: v -cc gcc -o gitly_check.exe . fails at link with missing C:/.../thirdparty/pg/win64/mingw/libpq.dll.a. Ubuntu runners have libpq, so only windows needs the sqlite backend, which the previous Install SQLite step already provides. --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2162402c..8fe59809 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -122,7 +122,7 @@ jobs: - name: Compile gitly run: | dir - .\v.exe -cc gcc gitly + .\v.exe -cc gcc -d sqlite gitly ubuntu-tcc: runs-on: ubuntu-latest From e35675d880f9aa4d53b180b7f7f29c1966fcfcf4 Mon Sep 17 00:00:00 2001 From: metif12 Date: Thu, 12 Nov 2026 16:44:15 +0330 Subject: [PATCH 07/11] fix: replace deprecated orm attribute with sql for -prod --- repo/repo.v | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/repo/repo.v b/repo/repo.v index 02bc5703..27d710bd 100644 --- a/repo/repo.v +++ b/repo/repo.v @@ -29,12 +29,12 @@ mut: primary_branch string webhook_secret string tags_count int - nr_open_issues int @[orm: 'open_issues_count'] - nr_open_prs int @[orm: 'open_prs_count'] - nr_releases int @[orm: 'releases_count'] - nr_branches int @[orm: 'branches_count'] + nr_open_issues int @[sql: 'open_issues_count'] + nr_open_prs int @[sql: 'open_prs_count'] + nr_releases int @[sql: 'releases_count'] + nr_branches int @[sql: 'branches_count'] nr_tags int - nr_stars int @[orm: 'stars_count'] + nr_stars int @[sql: 'stars_count'] lang_stats []LangStat @[skip] created_at int nr_contributors int From b39ffad8c9f95a0fb050369dcf402a2ddb6f279c Mon Sep 17 00:00:00 2001 From: metif12 Date: Thu, 12 Nov 2026 16:45:46 +0330 Subject: [PATCH 08/11] ci: windows cmd shell path fix --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index efb827fe..c4de6b54 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -154,14 +154,14 @@ jobs: id: build_v if: ${{ success() && !cancelled() }} run: | - ./make.bat -gcc + make.bat -gcc # Must run after "Build V": the script shells out to `v.exe`, which # does not exist until V is built. - name: Install SQLite id: install_sqlite if: ${{ success() && !cancelled() }} run: | - .\gitly\.github\workflows\windows-install-sqlite.bat + gitly\.github\workflows\windows-install-sqlite.bat - name: Compile gitly id: compile_gitly if: ${{ success() && !cancelled() }} From 11d02b7fbb2ec5774d0b28a1a0f8eb0a62f2f7fd Mon Sep 17 00:00:00 2001 From: metif12 Date: Thu, 12 Nov 2026 16:46:03 +0330 Subject: [PATCH 09/11] ci: run windows build/install in cmd shell --- .github/workflows/ci.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c4de6b54..a88bfbea 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,6 +25,7 @@ jobs: - name: Build V id: build_v if: ${{ success() && !cancelled() }} + shell: cmd run: | make sudo ./v symlink @@ -91,6 +92,7 @@ jobs: - name: Build V id: build_v if: ${{ success() && !cancelled() }} + shell: cmd run: | make ./v symlink @@ -153,6 +155,7 @@ jobs: < - name: Build V id: build_v if: ${{ success() && !cancelled() }} + shell: cmd run: | make.bat -gcc # Must run after "Build V": the script shells out to `v.exe`, which @@ -160,6 +163,7 @@ jobs: - name: Install SQLite id: install_sqlite if: ${{ success() && !cancelled() }} + shell: cmd run: | gitly\.github\workflows\windows-install-sqlite.bat - name: Compile gitly @@ -193,6 +197,7 @@ jobs: - name: Build V id: build_v if: ${{ success() && !cancelled() }} + shell: cmd run: | echo $VFLAGS make From ba9888c1207381def8db965383bf37fbf843697f Mon Sep 17 00:00:00 2001 From: metif12 Date: Thu, 12 Nov 2026 16:46:31 +0330 Subject: [PATCH 10/11] ci: keep cmd shell only on windows --- .github/workflows/ci.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a88bfbea..6956af59 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,7 +25,6 @@ jobs: - name: Build V id: build_v if: ${{ success() && !cancelled() }} - shell: cmd run: | make sudo ./v symlink @@ -92,7 +91,6 @@ jobs: - name: Build V id: build_v if: ${{ success() && !cancelled() }} - shell: cmd run: | make ./v symlink From 6a4f3063713942661a8d3e798c7a22d65ceff0de Mon Sep 17 00:00:00 2001 From: metif12 Date: Thu, 12 Nov 2026 16:47:28 +0330 Subject: [PATCH 11/11] ci: fix stray markers, cmd shell windows only --- .github/workflows/ci.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6956af59..ab271658 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -36,7 +36,7 @@ jobs: cd gitly v -cc gcc . -< - name: Compile gitly with -autofree (non-blocking, vlang/v#30190) + - name: Compile gitly with -autofree (non-blocking, vlang/v#30190) id: compile_gitly_with_autofree if: ${{ success() && !cancelled() }} continue-on-error: true @@ -100,7 +100,7 @@ jobs: run: | cd gitly v -cc clang . -< - name: Compile gitly with -autofree (non-blocking, vlang/v#30190) + - name: Compile gitly with -autofree (non-blocking, vlang/v#30190) id: compile_gitly_with_autofree if: ${{ success() && !cancelled() }} continue-on-error: true @@ -150,7 +150,7 @@ jobs: uses: actions/checkout@v4 with: path: gitly -< - name: Build V + - name: Build V id: build_v if: ${{ success() && !cancelled() }} shell: cmd @@ -195,13 +195,12 @@ jobs: - name: Build V id: build_v if: ${{ success() && !cancelled() }} - shell: cmd run: | echo $VFLAGS make sudo ./v symlink -< - name: Compile gitly with -autofree (non-blocking, vlang/v#30190) + - name: Compile gitly with -autofree (non-blocking, vlang/v#30190) id: compile_gitly_with_autofree if: ${{ success() && !cancelled() }} continue-on-error: true