What is the real reason that Bubble Sort runs at O(n) in best case?
Understanding how Bubble Sort works is of course really the key here.

The main part for unraveling this is that Bubble Sort goes back to the start if it ever performs a swap. If it never performs a swap, it runs along the array once, comparing each element to the one after it, and thus performing $O(n)$ comparisons.

So both sources are correct. The comparisons are counted in the complexity, you just do more of them (and some other things) if you need to swap stuff.

The reason this doesn't work for something like Selection Sort is that Selection Sort looks for the next element to place at the end of the sorted section in each pass. It doesn't know where that element is, and moreover, it always "moves" something (even if it's a trivial move), and whether you made a trivial move doesn't affect whether you will next time either (whereas in Bubble Sort, if you don't move anything, you know you never will).

You could add a check at the start to see if the array is already sorted of course.

Other sorting algorithms can benefit from similar cases to that in Bubble Sort though; Insertion Sort for example has best case $O(n)$ behaviour as well.