diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4e2c00a..d450f4a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,22 +9,43 @@ jobs: release: name: Release runs-on: ubuntu-latest + if: github.event_name == 'push' && github.ref == 'refs/heads/master' permissions: contents: write + packages: write steps: - name: Checkout Repo uses: actions/checkout@v4 with: fetch-depth: 0 + - name: Setup Go uses: actions/setup-go@v5 with: go-version: "1.22.x" + + - name: Build + run: go build ./... + - name: Run Semantic Release uses: go-semantic-release/action@v1 + id: semrel with: github-token: ${{ secrets.GITHUB_TOKEN }} + changelog-file: CHANGELOG.md + update-file: go.mod + changelog-generator-opt: "emojis=true" + + - name: Publish to GitHub + if: steps.semrel.outputs.version != '' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + echo "module github.com/Nicconike/goautomate" > go.mod + go list -m github.com/Nicconike/goautomate@${{ steps.semrel.outputs.version }} + GOPROXY=proxy.golang.org go list -m github.com/Nicconike/goautomate@${{ steps.semrel.outputs.version }} + - name: Index package on pkg.go.dev + if: steps.semrel.outputs.version != '' run: | - VERSION=$(git describe --tags --abbrev=0) - GOPROXY=proxy.golang.org go list -m github.com/Nicconike/goautomate@$VERSION + GOPROXY=proxy.golang.org go list -m github.com/Nicconike/goautomate@${{ steps.semrel.outputs.version }} diff --git a/pkg/downloader.go b/pkg/downloader.go index 6cdd186..390dc8c 100644 --- a/pkg/downloader.go +++ b/pkg/downloader.go @@ -12,6 +12,7 @@ import ( "github.com/schollz/progressbar/v3" ) +var NewProgressBar = progressbar.NewOptions64 var DownloadURLFormat = "https://dl.google.com/go/go%s.%s-%s.%s" var validPlatforms = map[string][]string{ "windows": {"386", "amd64"}, diff --git a/tests/unit/downloader_test.go b/tests/unit/downloader_test.go index 14a5b62..6dca9b9 100644 --- a/tests/unit/downloader_test.go +++ b/tests/unit/downloader_test.go @@ -11,9 +11,17 @@ import ( "time" "github.com/Nicconike/goautomate/pkg" + "github.com/schollz/progressbar/v3" ) func TestDownloadGo(t *testing.T) { + // Mock the progress bar + oldNewProgressBar := pkg.NewProgressBar + pkg.NewProgressBar = func(int64, ...progressbar.Option) *progressbar.ProgressBar { + return progressbar.NewOptions64(0, progressbar.OptionSetWriter(io.Discard)) + } + defer func() { pkg.NewProgressBar = oldNewProgressBar }() + tests := []struct { name string version string @@ -55,7 +63,7 @@ func TestDownloadGo(t *testing.T) { version: "1.16.5", targetOS: "linux", arch: "amd64", - serverResp: "pkg Server Error", + serverResp: "Internal Server Error", statusCode: http.StatusInternalServerError, expectError: true, }, @@ -65,69 +73,68 @@ func TestDownloadGo(t *testing.T) { t.Run(tt.name, func(t *testing.T) { // Create a test server server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - t.Logf("Test server received request for URL: %s", r.URL.String()) + time.Sleep(50 * time.Millisecond) + data := make([]byte, 1024) + w.Header().Set("Content-Length", fmt.Sprintf("%d", len(data))) w.WriteHeader(tt.statusCode) - w.Write([]byte(tt.serverResp)) + w.Write(data) })) defer server.Close() - t.Logf("Test server started at %s", server.URL) - // Override the download URL for testing originalURL := pkg.DownloadURLFormat pkg.DownloadURLFormat = server.URL + "/go%s.%s-%s.%s" defer func() { pkg.DownloadURLFormat = originalURL }() - // Redirect log output - oldOutput := os.Stdout - r, w, _ := os.Pipe() - os.Stdout = w - - // Use a channel to signal when the download is complete - done := make(chan bool) - var err error - + // Run the download function with a timeout + errChan := make(chan error, 1) go func() { - t.Log("Calling DownloadGo function") - err = pkg.DownloadGo(tt.version, tt.targetOS, tt.arch) - t.Log("DownloadGo function returned") - close(done) + errChan <- pkg.DownloadGo(tt.version, tt.targetOS, tt.arch) }() - // Wait for the download to complete or timeout + var err error select { - case <-done: - t.Log("Download completed") - case <-time.After(30 * time.Second): - t.Fatal("Test timed out after 30 seconds") + case err = <-errChan: + case <-time.After(5 * time.Second): + t.Fatal("DownloadGo timed out") } - // Restore log output - w.Close() - os.Stdout = oldOutput - logOutput, _ := io.ReadAll(r) - + // Check for expected error if (err != nil) != tt.expectError { t.Errorf("DownloadGo() error = %v, expectError %v", err, tt.expectError) return } + // For successful downloads, check if file was created and then remove it if !tt.expectError { filename := fmt.Sprintf("go%s.%s-%s.tar.gz", tt.version, tt.targetOS, tt.arch) + if tt.targetOS == "windows" { + filename = fmt.Sprintf("go%s.%s-%s.zip", tt.version, tt.targetOS, tt.arch) + } if _, err := os.Stat(filename); os.IsNotExist(err) { t.Errorf("Expected file %s to be created, but it doesn't exist", filename) } else { - os.Remove(filename) // Clean up the file after test + os.Remove(filename) } + } - if !contains(string(logOutput), "Successfully downloaded") { - t.Errorf("Expected log output to contain 'Successfully downloaded', but got: %s", logOutput) + // Check for specific error messages + if tt.expectError { + switch { + case tt.targetOS == "unsupported": + if !strings.Contains(err.Error(), "unsupported operating system") { + t.Errorf("Expected 'unsupported operating system' error, got: %v", err) + } + case tt.arch == "unsupported": + if !strings.Contains(err.Error(), "unsupported architecture") { + t.Errorf("Expected 'unsupported architecture' error, got: %v", err) + } + case tt.statusCode == http.StatusInternalServerError: + if !strings.Contains(err.Error(), "unexpected status code: 500") { + t.Errorf("Expected 'unexpected status code: 500' error, got: %v", err) + } } } }) } } - -func contains(s, substr string) bool { - return strings.Contains(s, substr) -}