Currently, if a pull request has more than one commit, previous commits may fail to compile, or may fail the tests. This is problematic, because it breaks git-bisect, or worse.
Fix this by adding a CI task for this.
Currently, if a pull request has more than one commit, previous commits may fail to compile, or may fail the tests. This is problematic, because it breaks git-bisect, or worse.
Fix this by adding a CI task for this.
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.
See the guideline for information on the review process.
If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.
Concept ACK
Maybe a self-hosted worker with a longer timeout would be better?
Probably but I am wondering a bit if these task could end up clogging our self-hosted worker queue and hinder other jobs from running in their regular time?
Probably but I am wondering a bit if these task could end up clogging our self-hosted worker queue and hinder other jobs from running in their regular time?
Right, that is another reason for self-hosted runners, because it is possible to assign a label to them, so that they are task-specific, and not interfere with other tasks. On GHA “free” runners will stop being spun up after n total parallel running tasks.
often without also running the functional tests that take longer to run
That said, what my build+test checks most often find is a failing build before running any tests. So if infra resources are limited, just build (or build + units) might still catch most of the issues.
Concept ACK.
Currently, if a pull request has more than one commit, previous commits may fail to compile, or may fail the tests. This is problematic, because it breaks git-bisect, or worse.
I’ve encountered such cases during my reviews.
On GHA “free” runners will stop being spun up after n total parallel running tasks.
Sure, but as I said, we can use self-hosted runners if and when there is a need. This check will take a few seconds on pulls with one commit (I can reduce this, if needed), which should be the most common type of pull request. Also, there is a limit of 6 hours, so this should be fine as well, unless many pull requests with many commits are pushed to at the same time, in which case there likely is a backlog either way.
35+ with:
36+ ref: ${{ github.event.pull_request.head.sha }}
37+ fetch-depth: '8' # Two more than $MAX_COUNT
38+ - run: git checkout HEAD~ # Skip the top commit, because it is already checked by the other tasks.
39+ - run: sudo apt install ccache build-essential libtool autotools-dev automake pkg-config bsdmainutils python3-zmq libevent-dev libboost-dev libsqlite3-dev libdb++-dev systemtap-sdt-dev libminiupnpc-dev libnatpmp-dev libqt5gui5 libqt5core5a libqt5dbus5 qttools5-dev qttools5-dev-tools qtwayland5 libqrencode-dev -y
40+ - run: EDITOR=true git rebase --interactive --exec "./autogen.sh && CC=clang CXX=clang++ ./configure && make clean && make -j $(nproc) check && ./test/functional/test_runner.py -j $(( $(nproc) * 2 ))" "$( git log '^'$( git log --merges -1 --format='%H' ) HEAD --format='%H' ${MAX_COUNT} | tail -1 )~1"
-Wthread-safety
?
It is jammy clang.
It doesn’t catch compile warnings, I think. Only compile errors.
Right, it is configured without --enable-werror
.
Why did you choose clang over gcc then?
Why did you chose clang over gcc then?
Clang is generally faster and uses less memory
Approach ACK fac02205ff59467dd061429e469d4fd07fcc5ed5.
What is the way to figure out which commit failed?
What is the way to figure out which commit failed?
Compile each commit locally, I guess? See the existing docs on how to do that.
What is the way to figure out which commit failed?
Compile each commit locally, I guess? See the existing docs on how to do that.
Yes, it is what is expected from a developer in first place before they push their branch.
But if we add a CI task that tests every commit, it is reasonable, at least for me, to expect it prints a commit hash being tested somewhere.
--interactive
flag. Should be trivial to re-ACK.
29+ if: github.event_name == 'pull_request'
30+ timeout-minutes: 360 # Use maximum time, see https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idtimeout-minutes. Assuming a worst case time of 1 hour per commit, this leads to a --max-count=6 below.
31+ env:
32+ MAX_COUNT: '--max-count=6'
33+ steps:
34+ - uses: actions/checkout@v3
Ah sorry, I forgot it was already merged.
I don’t think v3 or v4 are any different, so I’ll follow-up with this style nit later.
40 - run: git checkout HEAD~ # Skip the top commit, because it is already checked by the other tasks.
41- - run: sudo apt install ccache build-essential libtool autotools-dev automake pkg-config bsdmainutils python3-zmq libevent-dev libboost-dev libsqlite3-dev libdb++-dev systemtap-sdt-dev libminiupnpc-dev libnatpmp-dev libqt5gui5 libqt5core5a libqt5dbus5 qttools5-dev qttools5-dev-tools qtwayland5 libqrencode-dev -y
42- - run: EDITOR=true git rebase --interactive --exec "./autogen.sh && CC=clang CXX=clang++ ./configure && make clean && make -j $(nproc) check && ./test/functional/test_runner.py -j $(( $(nproc) * 2 ))" $( git log --merges -1 --format='%H' )
43+ - run: sudo apt install clang ccache build-essential libtool autotools-dev automake pkg-config bsdmainutils python3-zmq libevent-dev libboost-dev libsqlite3-dev libdb++-dev systemtap-sdt-dev libminiupnpc-dev libnatpmp-dev libqt5gui5 libqt5core5a libqt5dbus5 qttools5-dev qttools5-dev-tools qtwayland5 libqrencode-dev -y
44+ # Use clang++, because it is a bit faster and uses less memory than g++
45+ - run: git rebase --exec "echo Running test-one-commit on \$( git log -1 ) && ./autogen.sh && CC=clang CXX=clang++ ./configure && make clean && make -j $(nproc) check && ./test/functional/test_runner.py -j $(( $(nproc) * 2 ))" "$( git log '^'$( git log --merges -1 --format='%H' ) HEAD --format='%H' ${MAX_COUNT} | tail -1 )~1"
fa5356cd49facf195447f0f5921dce1fa53cb25d
Why don’t combine unrelated to MAX_COUNT
changes into the previous commit?
Per https://github.com/bitcoin/bitcoin/actions/runs/6075652138/job/16482267917?pr=28279
0Running test-one-commit on commit fafcd2e9ef1209d614de5763a2733098537919dd Author: MarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz> Date: Wed Aug 16 16:40:42 2023 +0200 ci: Add test-each-commit task
ACK fa5356cd49facf195447f0f5921dce1fa53cb25d
Modulo one question in #28279 (review).
Looks like this is currently failing for new PRs: https://github.com/bitcoin/bitcoin/actions/runs/6184007676/job/16786866270?pr=28476
0Run git rebase --exec "echo Running test-one-commit on \$( git log -1 ) && ./autogen.sh && CC=clang CXX=clang++ ./configure && make clean && make -j $(nproc) check && ./test/functional/test_runner.py -j $(( $(nproc) * 2 ))" "$( git log '^'$( git log --merges -1 --format='%H' ) HEAD --format='%H' ${MAX_COUNT} | tail -1 )~1"
1fatal: invalid upstream '~1'
2Error: Process completed with exit code 128.
I guess the issue is that ( git log '^'$( git log --merges -1 --format='%H' ) HEAD --format='%H' ${MAX_COUNT} | tail -1 )
prints nothing for some reason when there is only one commit in the pull request?
Not sure why, because locally it works:
0$ git --version
1git version 2.41.0
2$ git log -1 --format='%H'
33c99f66f8a10aa4dfc1e85c3a240cc144442eac7
4$ ( git log '^'$( git log --merges -1 --format='%H' ) HEAD --format='%H' ${MAX_COUNT} | tail -1 )
53c99f66f8a10aa4dfc1e85c3a240cc144442eac7