Thomas looked strong throughout the stage as Team Sky controlled the final climb, closing down attacks by Nairo Quintana (Movistar), Vincenzo Nibali (Bahrain-Merida), and Romain Bardet (Ag2r La Mondiale).
Accelerations by Thomas, Bardet, and Chris Froome (Team Sky) whittled the group down to just those three riders plus Tom Dumoulin (Team Sunweb) and, intermittently, Mikel Landa (Movistar) for the final four kilometres.
All five of those men launched attacks in a cagey final few kilometres, but none were able to open a gap as they approach the finish in the ski resort of Alpe d’Huez.
With the stage to be decided in a group sprint Landa accelerated with 700m to go, but was quickly closed down by Thomas, who then made sure he was first into the left-hand bend before the final 200m uphill to the finish.
And from there Thomas only extended his lead, as he sprinted clear of Dumoulin in second, Bardet in third, and Froome in fourth to take his second stage win in as many days and extend his lead at the top of the general classification to 1-39.
How it happened
The opening kilometres of stage 12 of the 2018 Tour de France saw fast and frantic racing as there were no shortage of riders trying to get in the break on the 27km run towards the first climb.
Despite constant attacks it was not until a couple of kilometres up the Col de la Madeleine that a large group was able to get away, with Andrey Amador (Movistar) being instrumental in pulling the group clear and Alejandro Valverde also in the move.
However the presence of Movistar didn’t please the rest of the breakaway riders who were hunting for a stage win, with Serge Pauwels (Dimension Data) and Pierre Rolland (EF Education First-Drapac) attacking to try and split the group.
After those attacks proved unsuccessful, the racing settled down with a group of around 20 riders at the front two minutes ahead of the peloton. Alongside Amador, Valverde, Pauwels, and Rolland were the likes of Warren Barguil (Fortuneo-Samsic), Julian Alaphilippe (Quick-Step Floors), Ilnur Zakarin (Katusha-Alpecin), Tejay van Garderen (BMC Racing), Pierre Latour (Ag2r La Mondiale) and Steven Kruijswijk (LottoNL-Jumbo).
Meanwhile Team Sky took up their customary position at the head of the peloton, although with Wout Poels having to work earlier in the stage than the team may have liked as Luke Rowe was dropped by the fast pace.
Unsurprisingly maximum points at the top of the climb went to Alaphilippe who extended his lead in the mountains classification, leading the break over the Col de la Madeleine with a lead of 3-26 over the peloton.
The descent from the climb passed without incident, before Pierre Rolland made the unpopular move of attacking through the feed zone to go solo onto the second category Lacets de Montvernier and held that lead over the climb and onto the Col de la Croix de Fer.
From the very start of this monstrous 29km climb the cracks started to show in the break as Alaphilippe and others dropped back to the bunch, while Kruijswijk, Valverde, and Barguil rode across to join Rolland at the front of the race with a gap of 4-30 to the peloton to put Kruijswijk into the virtual yellow jersey.
Those four riders tackled the start of the climb together, before being joined by Nieve, Amador, Zakarin, Rafal Majka (Bora-Hansgrohe) Daniel Martinez (EF Education First-Drapac), Gorka Izagirre (Bahrain-Merida), and Robert Gesink (LottoNL-Jumbo) to form an 11-strong lead group.
That group worked well together for a few kilometres, but the pace clearly wasn’t enough for Kruijswijk who attacked 17km from the top of the climb with no one able to follow, opening the gap back to the peloton out to six minutes.
With five kilometres to go to the summit Ag2r La Mondiale took up the pace-setting on the front with Oliver Naesen working for Romain Bardet before Marc Soler (Movistar) took over with Mikel Landa in his wheel as the road ramped up towards the summit.
That tempo did nothing to pull back Kruijswijk, who crossed the Col de la Croix de Fer with a lead of six minutes, while Team Sky were reduced to just two domestiques – Michal Kwiatkowski and Egan Bernal – alongside Chris Froome and Geraint Thomas while Jonathan Castroviejo struggled to cling on at the back of the group.
However with a straightforward descent followed by flat valley roads, Kruiswijk’s lead was chipped away at by the yellow jersey group with Castroviejo driving the pace, and as the LottoNL-Jumbo rider swung left onto the famous climb his lead was down to 4-15.
Michal Kwiatkowski led the main contenders onto the climb, last just a kilometre before pulling off and handing over to Egan Bernal, the young Colombian leading up Alpe d’Huez and setting a steady tempo with Thomas and Froome in his wheel.
Bernal looked calm at the front but his pace was enough to cause damage at the back of the group, with Valverde, Zakarin, and Bob Jungels (Quick-Step Floors) while Dan Martin (UAE Team Emirates) looked precarious at the back and found himself distanced with 11km still to ride.
Despite the damage at the back of the group, the pace obviously wasn’t fast enough for Vincenzo Nibali (Bahrain-Merida) who attacked with 10.5km to go. The Italian was able to open a gap, but Bernal remaining calm and showed impressive maturity as he slowly pulled him back over the next 500m.
No sooner had Nibali been pulled back, than Nairo Quintana (Movistar) made his move, but once again Bernal had things under control and reeled in his compatriot with Thomas and Froome still looking comfortable in his wheel.
Those attacks were also bad news for Kruijswijk, who saw his lead cut down to 2-30 with eight kilometres to go, meaning that he was no longer the virtual leader of the race but still looked strong and on course for the stage win.
The ease with which Bernal closed down those attacks seemed to deter further moves as Nibali, Quintana, Tom Dumoulin (Team Sunweb), Primoz Roglic (LottoNL-Jumbo), and Mikel Landa (Movistar) sat in while Jakob Fuglsang (Astana) yo-yoed off the back.
After a kilometre with a lack of action, Bernal was tested again as Landa attacked on the left-hand side of the road with Bardet on his wheel. And this time Bernal started to show a little weakness as while Landa was soon brought back Bardet was able to open a gap.
The Frenchman’s move was the strongest attack so far, opening a lead of around 10 seconds, but as Bernal continued to work on the front of the yellow jersey group Quintana was floundering, dropping off the back of the group and quickly seeing the race disappear up the road.
With six kilometres to go Kruiswijk’s lead was down to 1-38 but starting to fall quicker and quicker, with Bardet lingering just 10 seconds off the front of the GC group and working hard to very slowly open a gap
Kruiswijk was certainly weakening as he began to get out of the saddle with five kilometres with Bardet closing in, but back in the GC group Bernal’s work was over to leave Geraint Thomas, wearing the yellow jersey, setting the pace on the front with Froome in his wheel.
And Thomas’s pace was fearsome from the start as the Welshman made light work of the gap to Bardet to close the gap to Frenchman in just a few hundred metres and starting to think of the stage win with Kruijswijk coming into his sights.
As soon as Bardet was caught Froome attacked and dropped the Frenchman while Thomas stuck to Dumoulin’s wheel in the chase. However there was drama in the group behind as Vincenzo Nibali found himself on the floor and in some discomfort.
With 3.5km Kruijswijk was caught and passed by Froome, but Dumoulin was going deep to bridge back across with Thomas and Bardet in close attendance and the games began as all four riders looked at each other.
That easing off of the pace allowed Mikel Landa to get back in, but no sooner had the Spaniard regained contact than Bardet was on the attack. Froome was the first to respond, accelerating with Dumoulin straight onto the wheel with Thomas behind, and all four riders coming back together.
Dumoulin had been slow to respond to Froome’s acceleration, but the Dutchman was the next to go with Thomas marking while Froome slowly made his was back with two kilometres remaining.
Entering the final kilometre and four riders became five as Landa regained contact while Nibali and Roglic worked hard to also get back on.
With 700m Landa launched his bid for glory with Thomas the first to react and riding wide through the final left-hand bend onto the final straight.
Carrying more speed than all of his rivals and already holding a gap, there was no stopping Thomas from there as he opened a gap in the final 150m to cross the line and punch the air in celebration for the second day in a row.
Thomas’s acceleration was so impressive that he was able to open a two-second gap to Tom Dumoulin in second, while Bardet and Froome were another second further back in third and fourth.
That result means that Thomas was able to extend his lead at the top of the general classification by 14 seconds, and now leads team-mate Chris Froome by 1-39, with Tom Dumoulin in third place at 1-50.
Despite his crash, Vincenzo Nibali was able to recover to finish seventh on the stage, conceding just 13 seconds, and now sits 2-37 behind Thomas just ahead of Roglič and Bardet.
Tour de France 2018, stage 12: Bourg-St-Maurice to Alpe d’Huez, 175.5km
1. Geraint Thomas (GBr) Team Sky, in 5-18-37
2. Tom Dumoulin (Ned) Team Sunweb, at 2 secs
3. Romain Bardet (Fra) AG2R La Mondiale, at 3 secs
4. Chris Froome (GBr) Team Sky, at same time
5. Mikel Landa (Esp) Movistar, at 7 secs
6. Primož Roglič (Slo) LottoNL-Jumbo, at 13 secs
7. Vincenzo Nibali (Ita) Bahrain-Merida, at same time
8. Jakob Fuglsang (Den) Astana Pro Team, at 42 secs
9. Nairo Quintana (Col) Movistar Team, at 47 secs
10. Steven Kruijswijk (Ned) LottoNL-Jumbo, at 53 secs
General classification after stage 12
1. Geraint Thomas (GBr) Team Sky, in 49-24-43
2. Chris Froome (GBr) Team Sky, at 1-39
3. Tom Dumoulin (Ned) Team Sunweb, at 1-30
4. Vincenzo Nibali (Ita) Bahrain-Merida, at 2-37
5. Primož Roglič (Slo) LottoNL-Jumbo, at 2-47
6. Romain Bardet (Fra) Ag2r La Mondiale, at 3-07
7. Mikel Landa (Esp) Movistar, at 3-13
8. Steven Kruijswijk (Ned) LottoNL-Jumbo, at 3-43
9. Nairo Quintana (Col) Movistar, at 4-13
10. Daniel Martin (Irl) UAE Team Emirates, at 5-11