Skip to content

Commit c0f602d

Browse files
committed
Merge branch 'main' into lilac/e2e-button-checks
2 parents 61ceea8 + 9041646 commit c0f602d

File tree

133 files changed

+1738
-768
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

133 files changed

+1738
-768
lines changed

.github/actions/setup-tf/action.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ runs:
77
- name: Install Terraform
88
uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2
99
with:
10-
terraform_version: 1.10.5
10+
terraform_version: 1.11.0
1111
terraform_wrapper: false

.github/workflows/ci.yaml

+4-4
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ jobs:
178178
echo "LINT_CACHE_DIR=$dir" >> $GITHUB_ENV
179179
180180
- name: golangci-lint cache
181-
uses: actions/cache@0c907a75c2c80ebcb7f088228285e798b750cf8f # v4.2.1
181+
uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf # v4.2.2
182182
with:
183183
path: |
184184
${{ env.LINT_CACHE_DIR }}
@@ -188,7 +188,7 @@ jobs:
188188
189189
# Check for any typos
190190
- name: Check for typos
191-
uses: crate-ci/typos@212923e4ff05b7fc2294a204405eec047b807138 # v1.29.9
191+
uses: crate-ci/typos@db35ee91e80fbb447f33b0e5fbddb24d2a1a884f # v1.29.10
192192
with:
193193
config: .github/workflows/typos.toml
194194

@@ -1092,7 +1092,7 @@ jobs:
10921092
uses: google-github-actions/setup-gcloud@77e7a554d41e2ee56fc945c52dfd3f33d12def9a # v2.1.4
10931093

10941094
- name: Download dylibs
1095-
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
1095+
uses: actions/download-artifact@cc203385981b70ca67e1cc392babf9cc229d5806 # v4.1.9
10961096
with:
10971097
name: dylibs
10981098
path: ./build
@@ -1236,7 +1236,7 @@ jobs:
12361236
version: "2.5.1"
12371237

12381238
- name: Get Cluster Credentials
1239-
uses: google-github-actions/get-gke-credentials@7a108e64ed8546fe38316b4086e91da13f4785e1 # v2.3.1
1239+
uses: google-github-actions/get-gke-credentials@d0cee45012069b163a631894b98904a9e6723729 # v2.3.3
12401240
with:
12411241
cluster_name: dogfood-v2
12421242
location: us-central1-a

.github/workflows/dogfood.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ jobs:
5353
uses: depot/setup-action@b0b1ea4f69e92ebf5dea3f8713a1b0c37b2126a5 # v1.6.0
5454

5555
- name: Set up Docker Buildx
56-
uses: docker/setup-buildx-action@f7ce87c1d6bead3e36075b2ce75da1f6cc28aaca # v3.9.0
56+
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
5757

5858
- name: Login to DockerHub
5959
if: github.ref == 'refs/heads/main'

.github/workflows/nightly-gauntlet.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ jobs:
2020
# even if some of the preceding steps are slow.
2121
timeout-minutes: 25
2222
strategy:
23+
fail-fast: false
2324
matrix:
2425
os:
2526
- macos-latest

.github/workflows/release.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ jobs:
286286
uses: google-github-actions/setup-gcloud@77e7a554d41e2ee56fc945c52dfd3f33d12def9a # v2.1.4
287287

288288
- name: Download dylibs
289-
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
289+
uses: actions/download-artifact@cc203385981b70ca67e1cc392babf9cc229d5806 # v4.1.9
290290
with:
291291
name: dylibs
292292
path: ./build

cli/dotfiles.go

+17-18
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"os"
88
"os/exec"
99
"path/filepath"
10+
"runtime"
1011
"strings"
1112
"time"
1213

@@ -41,16 +42,7 @@ func (r *RootCmd) dotfiles() *serpent.Command {
4142
dotfilesDir = filepath.Join(cfgDir, dotfilesRepoDir)
4243
// This follows the same pattern outlined by others in the market:
4344
// https://github.com/coder/coder/pull/1696#issue-1245742312
44-
installScriptSet = []string{
45-
"install.sh",
46-
"install",
47-
"bootstrap.sh",
48-
"bootstrap",
49-
"script/bootstrap",
50-
"setup.sh",
51-
"setup",
52-
"script/setup",
53-
}
45+
installScriptSet = installScriptFiles()
5446
)
5547

5648
if cfg == "" {
@@ -195,21 +187,28 @@ func (r *RootCmd) dotfiles() *serpent.Command {
195187

196188
_, _ = fmt.Fprintf(inv.Stdout, "Running %s...\n", script)
197189

198-
// Check if the script is executable and notify on error
199190
scriptPath := filepath.Join(dotfilesDir, script)
200-
fi, err := os.Stat(scriptPath)
201-
if err != nil {
202-
return xerrors.Errorf("stat %s: %w", scriptPath, err)
203-
}
204191

205-
if fi.Mode()&0o111 == 0 {
206-
return xerrors.Errorf("script %q does not have execute permissions", script)
192+
// Permissions checks will always fail on Windows, since it doesn't have
193+
// conventional Unix file system permissions.
194+
if runtime.GOOS != "windows" {
195+
// Check if the script is executable and notify on error
196+
fi, err := os.Stat(scriptPath)
197+
if err != nil {
198+
return xerrors.Errorf("stat %s: %w", scriptPath, err)
199+
}
200+
if fi.Mode()&0o111 == 0 {
201+
return xerrors.Errorf("script %q does not have execute permissions", script)
202+
}
207203
}
208204

209205
// it is safe to use a variable command here because it's from
210206
// a filtered list of pre-approved install scripts
211207
// nolint:gosec
212-
scriptCmd := exec.CommandContext(inv.Context(), filepath.Join(dotfilesDir, script))
208+
scriptCmd := exec.CommandContext(inv.Context(), scriptPath)
209+
if runtime.GOOS == "windows" {
210+
scriptCmd = exec.CommandContext(inv.Context(), "powershell", "-NoLogo", scriptPath)
211+
}
213212
scriptCmd.Dir = dotfilesDir
214213
scriptCmd.Stdout = inv.Stdout
215214
scriptCmd.Stderr = inv.Stderr

cli/dotfiles_other.go

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//go:build !windows
2+
3+
package cli
4+
5+
func installScriptFiles() []string {
6+
return []string{
7+
"install.sh",
8+
"install",
9+
"bootstrap.sh",
10+
"bootstrap",
11+
"setup.sh",
12+
"setup",
13+
"script/install.sh",
14+
"script/install",
15+
"script/bootstrap.sh",
16+
"script/bootstrap",
17+
"script/setup.sh",
18+
"script/setup",
19+
}
20+
}

cli/dotfiles_test.go

+76-38
Original file line numberDiff line numberDiff line change
@@ -116,11 +116,65 @@ func TestDotfiles(t *testing.T) {
116116
require.NoError(t, staterr)
117117
require.True(t, stat.IsDir())
118118
})
119+
t.Run("SymlinkBackup", func(t *testing.T) {
120+
t.Parallel()
121+
_, root := clitest.New(t)
122+
testRepo := testGitRepo(t, root)
123+
124+
// nolint:gosec
125+
err := os.WriteFile(filepath.Join(testRepo, ".bashrc"), []byte("wow"), 0o750)
126+
require.NoError(t, err)
127+
128+
// add a conflicting file at destination
129+
// nolint:gosec
130+
err = os.WriteFile(filepath.Join(string(root), ".bashrc"), []byte("backup"), 0o750)
131+
require.NoError(t, err)
132+
133+
c := exec.Command("git", "add", ".bashrc")
134+
c.Dir = testRepo
135+
err = c.Run()
136+
require.NoError(t, err)
137+
138+
c = exec.Command("git", "commit", "-m", `"add .bashrc"`)
139+
c.Dir = testRepo
140+
out, err := c.CombinedOutput()
141+
require.NoError(t, err, string(out))
142+
143+
inv, _ := clitest.New(t, "dotfiles", "--global-config", string(root), "--symlink-dir", string(root), "-y", testRepo)
144+
err = inv.Run()
145+
require.NoError(t, err)
146+
147+
b, err := os.ReadFile(filepath.Join(string(root), ".bashrc"))
148+
require.NoError(t, err)
149+
require.Equal(t, string(b), "wow")
150+
151+
// check for backup file
152+
b, err = os.ReadFile(filepath.Join(string(root), ".bashrc.bak"))
153+
require.NoError(t, err)
154+
require.Equal(t, string(b), "backup")
155+
156+
// check for idempotency
157+
inv, _ = clitest.New(t, "dotfiles", "--global-config", string(root), "--symlink-dir", string(root), "-y", testRepo)
158+
err = inv.Run()
159+
require.NoError(t, err)
160+
b, err = os.ReadFile(filepath.Join(string(root), ".bashrc"))
161+
require.NoError(t, err)
162+
require.Equal(t, string(b), "wow")
163+
b, err = os.ReadFile(filepath.Join(string(root), ".bashrc.bak"))
164+
require.NoError(t, err)
165+
require.Equal(t, string(b), "backup")
166+
})
167+
}
168+
169+
func TestDotfilesInstallScriptUnix(t *testing.T) {
170+
t.Parallel()
171+
172+
if runtime.GOOS == "windows" {
173+
t.Skip()
174+
}
175+
119176
t.Run("InstallScript", func(t *testing.T) {
120177
t.Parallel()
121-
if runtime.GOOS == "windows" {
122-
t.Skip("install scripts on windows require sh and aren't very practical")
123-
}
124178
_, root := clitest.New(t)
125179
testRepo := testGitRepo(t, root)
126180

@@ -149,9 +203,6 @@ func TestDotfiles(t *testing.T) {
149203

150204
t.Run("NestedInstallScript", func(t *testing.T) {
151205
t.Parallel()
152-
if runtime.GOOS == "windows" {
153-
t.Skip("install scripts on windows require sh and aren't very practical")
154-
}
155206
_, root := clitest.New(t)
156207
testRepo := testGitRepo(t, root)
157208

@@ -183,9 +234,6 @@ func TestDotfiles(t *testing.T) {
183234

184235
t.Run("InstallScriptChangeBranch", func(t *testing.T) {
185236
t.Parallel()
186-
if runtime.GOOS == "windows" {
187-
t.Skip("install scripts on windows require sh and aren't very practical")
188-
}
189237
_, root := clitest.New(t)
190238
testRepo := testGitRepo(t, root)
191239

@@ -227,53 +275,43 @@ func TestDotfiles(t *testing.T) {
227275
require.NoError(t, err)
228276
require.Equal(t, string(b), "wow\n")
229277
})
230-
t.Run("SymlinkBackup", func(t *testing.T) {
278+
}
279+
280+
func TestDotfilesInstallScriptWindows(t *testing.T) {
281+
t.Parallel()
282+
283+
if runtime.GOOS != "windows" {
284+
t.Skip()
285+
}
286+
287+
t.Run("InstallScript", func(t *testing.T) {
231288
t.Parallel()
232289
_, root := clitest.New(t)
233290
testRepo := testGitRepo(t, root)
234291

235292
// nolint:gosec
236-
err := os.WriteFile(filepath.Join(testRepo, ".bashrc"), []byte("wow"), 0o750)
293+
err := os.WriteFile(filepath.Join(testRepo, "install.ps1"), []byte("echo \"hello, computer!\" > "+filepath.Join(string(root), "greeting.txt")), 0o750)
237294
require.NoError(t, err)
238295

239-
// add a conflicting file at destination
240-
// nolint:gosec
241-
err = os.WriteFile(filepath.Join(string(root), ".bashrc"), []byte("backup"), 0o750)
242-
require.NoError(t, err)
243-
244-
c := exec.Command("git", "add", ".bashrc")
296+
c := exec.Command("git", "add", "install.ps1")
245297
c.Dir = testRepo
246298
err = c.Run()
247299
require.NoError(t, err)
248300

249-
c = exec.Command("git", "commit", "-m", `"add .bashrc"`)
301+
c = exec.Command("git", "commit", "-m", `"add install.ps1"`)
250302
c.Dir = testRepo
251-
out, err := c.CombinedOutput()
252-
require.NoError(t, err, string(out))
303+
err = c.Run()
304+
require.NoError(t, err)
253305

254306
inv, _ := clitest.New(t, "dotfiles", "--global-config", string(root), "--symlink-dir", string(root), "-y", testRepo)
255307
err = inv.Run()
256308
require.NoError(t, err)
257309

258-
b, err := os.ReadFile(filepath.Join(string(root), ".bashrc"))
259-
require.NoError(t, err)
260-
require.Equal(t, string(b), "wow")
261-
262-
// check for backup file
263-
b, err = os.ReadFile(filepath.Join(string(root), ".bashrc.bak"))
310+
b, err := os.ReadFile(filepath.Join(string(root), "greeting.txt"))
264311
require.NoError(t, err)
265-
require.Equal(t, string(b), "backup")
266-
267-
// check for idempotency
268-
inv, _ = clitest.New(t, "dotfiles", "--global-config", string(root), "--symlink-dir", string(root), "-y", testRepo)
269-
err = inv.Run()
270-
require.NoError(t, err)
271-
b, err = os.ReadFile(filepath.Join(string(root), ".bashrc"))
272-
require.NoError(t, err)
273-
require.Equal(t, string(b), "wow")
274-
b, err = os.ReadFile(filepath.Join(string(root), ".bashrc.bak"))
275-
require.NoError(t, err)
276-
require.Equal(t, string(b), "backup")
312+
// If you squint, it does in fact say "hello, computer!" in here, but in
313+
// UTF-16 and with a byte-order-marker at the beginning. Windows!
314+
require.Equal(t, b, []byte("\xff\xfeh\x00e\x00l\x00l\x00o\x00,\x00 \x00c\x00o\x00m\x00p\x00u\x00t\x00e\x00r\x00!\x00\r\x00\n\x00"))
277315
})
278316
}
279317

cli/dotfiles_windows.go

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package cli
2+
3+
func installScriptFiles() []string {
4+
return []string{
5+
"install.ps1",
6+
"bootstrap.ps1",
7+
"setup.ps1",
8+
"script/install.ps1",
9+
"script/bootstrap.ps1",
10+
"script/setup.ps1",
11+
}
12+
}

0 commit comments

Comments
 (0)