This is a fairly straitforward gaps and islands problem. Here is a solution. There may also be a solution with LAG, but I don't have access to a SQL 2012 environment right now to test it.
I've set up your table using a TABLE VALUE CONSTRUCTOR. You'll want to replace that with your actual table.
WITH shift_groups AS
(
SELECT *,
grp = ROW_NUMBER() OVER(PARTITION BY [name] ORDER BY dt, shift_type)
- ROW_NUMBER() OVER(PARTITION BY [name], shift_type ORDER BY dt)
FROM
(
VALUES
('Graham', 'Late', '22/10/2017')
, ('Graham', 'Late', '29/10/2017')
, ('Graham', 'Late', '05/11/2017')
, ('Graham', 'Morning', '12/11/2017')
, ('Graham', 'Afternoon', '19/11/2017')
, ('Graham', 'Afternoon', '26/11/2017')
, ('Graham', 'Afternoon', '03/12/2017')
, ('Graham', 'Late', '10/12/2017')
, ('Graham', 'Late', '17/12/2017')
) m([name], shift_type, sunday_shift_date)
CROSS APPLY (VALUES(CONVERT(DATE, sunday_shift_date, 103))) dt(dt)
)
SELECT [name], shift_type, MIN(dt), MAX(dt)
FROM shift_groups
GROUP BY [name], shift_type, grp
ORDER BY [name], MIN(dt)
Drew
J. Drew Allen
Business Intelligence Analyst
Philadelphia, PA