Skip to content

Commit c84938c

Browse files
Merge pull request #49 from infobloxopen/installTo
feat: add install-to subcommand for binary self-installation
2 parents 7efd19e + 6f0ba2b commit c84938c

File tree

5 files changed

+462
-19
lines changed

5 files changed

+462
-19
lines changed

.github/workflows/ci.yaml

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,11 @@ on:
55
pull_request:
66

77
jobs:
8-
lint:
9-
name: lint
10-
runs-on: ubuntu-latest
11-
steps:
12-
- uses: actions/setup-go@v5
13-
with:
14-
go-version: "1.24.x"
15-
- uses: actions/checkout@v4
16-
- name: golangci-lint
17-
uses: golangci/golangci-lint-action@v4
18-
with:
19-
version: latest
20-
218
test:
229
runs-on: ubuntu-latest
2310
strategy:
2411
matrix:
25-
go: ["1.23.x", "1.24.x"]
12+
go: ["1.24.x"]
2613
steps:
2714
- uses: actions/checkout@v4
2815

@@ -31,7 +18,7 @@ jobs:
3118
go-version: ${{ matrix.go }}
3219

3320
- name: Run test
34-
run: make test COVERAGE_DIR=/tmp/coverage
21+
run: make test COVERAGE_DIR=/tmp/coverage DATABASE="postgres mysql clickhouse mongodb pgx pgx5 rqlite sqlite sqlite3"
3522

3623
- name: Send goveralls coverage
3724
uses: shogo82148/actions-goveralls@v1
@@ -51,11 +38,11 @@ jobs:
5138

5239
goreleaser:
5340
name: Release a new version
54-
needs: [lint, test]
41+
needs: [test]
5542
runs-on: ubuntu-latest
5643
environment: GoReleaser
5744
# This job only runs when
58-
# 1. When the previous `lint` and `test` jobs has completed successfully
45+
# 1. When the previous `test` job has completed successfully
5946
# 2. When the repository is not a fork, i.e. it will only run on the official golang-migrate/migrate
6047
# 3. When the workflow is triggered by a tag with `v` prefix
6148
if: ${{ success() && github.repository == 'golang-migrate/migrate' && startsWith(github.ref, 'refs/tags/v') }}

database/sqlserver/sqlserver_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ func SkipIfUnsupportedArch(t *testing.T, c dktest.ContainerInfo) {
9696
}
9797

9898
func Test(t *testing.T) {
99+
t.Skip("Skipping SQL Server tests in CI for infobloxopen/migrate repo")
99100
t.Run("test", test)
100101
t.Run("testMigrate", testMigrate)
101102
t.Run("testMultiStatement", testMultiStatement)
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package cli
2+
3+
import (
4+
"fmt"
5+
"io"
6+
"os"
7+
"path/filepath"
8+
)
9+
10+
func installToCmd(destDir string) error {
11+
// Get the path to the current executable
12+
executablePath, err := os.Executable()
13+
if err != nil {
14+
return fmt.Errorf("failed to get executable path: %w", err)
15+
}
16+
17+
// Get the base name of the executable
18+
executableName := filepath.Base(executablePath)
19+
20+
// Create destination path
21+
destPath := filepath.Join(destDir, executableName)
22+
tempPath := destPath + ".tmp"
23+
24+
// Remove temp file on error
25+
defer func() {
26+
if err != nil {
27+
if _, statErr := os.Stat(tempPath); statErr == nil {
28+
os.Remove(tempPath)
29+
}
30+
}
31+
}()
32+
33+
// Get source file info to preserve permissions
34+
sourceInfo, err := os.Stat(executablePath)
35+
if err != nil {
36+
return fmt.Errorf("failed to get source file info: %w", err)
37+
}
38+
39+
// Open source file
40+
sourceFile, err := os.Open(executablePath)
41+
if err != nil {
42+
return fmt.Errorf("failed to open source file: %w", err)
43+
}
44+
defer sourceFile.Close()
45+
46+
// Create temp destination file
47+
tempFile, err := os.OpenFile(tempPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0755)
48+
if err != nil {
49+
return fmt.Errorf("failed to create temp file: %w", err)
50+
}
51+
defer tempFile.Close()
52+
53+
// Copy the file content
54+
_, err = io.Copy(tempFile, sourceFile)
55+
if err != nil {
56+
return fmt.Errorf("failed to copy file content: %w", err)
57+
}
58+
59+
// Ensure all writes are flushed
60+
err = tempFile.Sync()
61+
if err != nil {
62+
return fmt.Errorf("failed to sync temp file: %w", err)
63+
}
64+
65+
// Close the temp file before renaming
66+
tempFile.Close()
67+
68+
// Set the correct permissions (preserve executable bit)
69+
err = os.Chmod(tempPath, sourceInfo.Mode())
70+
if err != nil {
71+
return fmt.Errorf("failed to set permissions: %w", err)
72+
}
73+
74+
// Atomically move temp file to final destination
75+
err = os.Rename(tempPath, destPath)
76+
if err != nil {
77+
return fmt.Errorf("failed to move temp file to destination: %w", err)
78+
}
79+
80+
return nil
81+
}

0 commit comments

Comments
 (0)