The skybox should be drawn after all lighting has been done. It's done exactly the same way as in a forward-shaded renderer; it shouldn't go into the G-buffer at all, and the lighting shaders shouldn't need to know anything about it.
I don't think there's any need to fiddle around with the viewport depth range or stencil either. If you use a projection matrix with an infinite far plane, you can just draw it after everything else, using a vertex shader that sets w = 0 before transforming by the view and projection matrices.
Alternatively, if it's just a texture and you don't need to draw actual geometry, you could do it as a postprocess - a full-screen pass, where the vertex shader sets z = w = 1 to draw the full-screen pass at the far plane. Here's the skybox code I use, which takes this approach:
TextureCube<float3> g_texSkybox;
void vsMain(in Vertex i_vtx, out float3 o_vecView : VIEW, out float4 o_posClip : SV_Position)
{
// Set z = 1 to draw skybox at the back of the depth range
o_posClip = float4(i_vtx.m_pos.xy, 1.0, 1.0);
float4 vecView = mul(o_posClip, g_matClipToWorldNoTranslation);
o_vecView = vecView.xyz / vecView.w;
}
float3 psMain(in float3 i_vecView : VIEW) : SV_Target
{
return g_texSkybox.Sample(g_ssTrilinearRepeat, i_vecView);
}
Here g_matClipToWorldNoTranslation
is the inverse projection matrix, multiplied by the inverse of the rotation part of the view matrix. It converts a point in clip space to the corresponding direction in world space.