diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d77b54d0..1ff2052c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -17,69 +17,61 @@ jobs: name: Test with ${{ matrix.go-version }} on ${{ matrix.vm-os }} runs-on: ${{ matrix.vm-os }} env: - CI_REPORT: ${{ matrix.vm-os == 'ubuntu-20.04' && startsWith(matrix.go-version, '1.18.') }} + CI_REPORT: ${{ matrix.vm-os == 'ubuntu-22.04' && matrix.go-version == '1.18.x' }} strategy: max-parallel: 10 fail-fast: false matrix: vm-os: [ - ubuntu-20.04, - macos-13, + ubuntu-22.04, macos-14, windows-2022 ] go-version: [ 1.18.x, - 1.19.x, - 1.20.x, - 1.21.x, - 1.22.x, - 1.23.x, + 1.25.x, ] permissions: contents: read # Steps to execute steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v5 - name: Set up Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v6 with: go-version: ${{ matrix.go-version }} cache: true - name: Go Build run: | - export - git status go version go mod download - make --version - name: Test run: | make ci - make build + # The coverage GATE is the codecov/project and codecov/patch commit + # statuses set by the Codecov app after this upload; continue-on-error + # here only tolerates upload-channel outages, it does not bypass the + # gate. - name: Upload Coverage Reports to Codecov if: ${{ fromJSON(env.CI_REPORT) }} - uses: codecov/codecov-action@v3 + continue-on-error: true + uses: codecov/codecov-action@v5 with: token: ${{ secrets.CODECOV_TOKEN }} files: coverage.txt - name: Upload Coverage Reports to Codacy if: ${{ fromJSON(env.CI_REPORT) }} + continue-on-error: true env: CODACY_PROJECT_TOKEN: ${{ secrets.CODACY_PROJECT_TOKEN }} run: bash <(curl -Ls https://coverage.codacy.com/get.sh) report --force-coverage-parser go -r coverage.txt - name: Analyze - if: ${{ runner.os == 'macOS' || runner.os == 'Linux' }} + if: ${{ runner.os == 'Linux' }} run: | # Setup - if [[ ${{ runner.os }} == 'Linux' ]]; then - wget -cqL https://github.com/XAMPPRocky/tokei/releases/download/v12.1.2/tokei-i686-unknown-linux-musl.tar.gz -O tokei.tgz - wget -cqL https://github.com/mgechev/revive/releases/download/v1.3.7/revive_linux_amd64.tar.gz -O revive.tgz - elif [[ ${{ runner.os }} == 'macOS' ]]; then - wget -cqL https://github.com/XAMPPRocky/tokei/releases/download/v12.1.2/tokei-x86_64-apple-darwin.tar.gz -O tokei.tgz - wget -cqL https://github.com/mgechev/revive/releases/download/v1.3.7/revive_darwin_amd64.tar.gz -O revive.tgz - fi + wget -cqL https://github.com/XAMPPRocky/tokei/releases/download/v12.1.2/tokei-i686-unknown-linux-musl.tar.gz -O tokei.tgz + wget -cqL https://github.com/mgechev/revive/releases/download/v1.3.7/revive_linux_amd64.tar.gz -O revive.tgz tar zxf tokei.tgz tokei && chmod +x tokei && $SUDO mv tokei /usr/local/bin && rm tokei.tgz tar zxf revive.tgz revive && chmod +x revive && $SUDO mv revive /usr/local/bin && rm revive.tgz wget -cqL https://raw.githubusercontent.com/1set/meta/master/revive.toml -O revive.toml @@ -96,15 +88,23 @@ jobs: printf '\n```\n' >> $GITHUB_STEP_SUMMARY revive -config revive.toml -formatter friendly ./... >> $GITHUB_STEP_SUMMARY printf '```\n\n' >> $GITHUB_STEP_SUMMARY - # --- file size - echo "## File Size" >> $GITHUB_STEP_SUMMARY - printf '\n```bash\n' >> $GITHUB_STEP_SUMMARY - export CMDDIR=cmd/starlet - ls -laSh "$CMDDIR" >> $GITHUB_STEP_SUMMARY - printf '```\n\n```bash\n' >> $GITHUB_STEP_SUMMARY - if [[ ${{ runner.os }} == 'Linux' ]]; then - find "$CMDDIR" -maxdepth 1 -type f -size +524288c | xargs -I {} stat --format="%n %s" {} | awk '{printf "%s\t\t%sB\n", $1, $2}' >> $GITHUB_STEP_SUMMARY - elif [[ ${{ runner.os }} == 'macOS' ]]; then - find "$CMDDIR" -maxdepth 1 -type f -size +524288c | xargs -I {} stat -f "%N %z" {} | awk '{printf "%s\t\t%sB\n", $1, $2}' >> $GITHUB_STEP_SUMMARY - fi - printf '```\n\n' >> $GITHUB_STEP_SUMMARY + + # cmd/starlet is a separate Go module with its own (older) pins and extra + # third-party dependencies; build it as a non-gating signal so a CLI-side + # breakage is visible without blocking library PRs. + cli: + name: Build CLI submodule (non-gating) + runs-on: ubuntu-22.04 + continue-on-error: true + permissions: + contents: read + steps: + - uses: actions/checkout@v5 + - name: Set up Go + uses: actions/setup-go@v6 + with: + go-version: 1.18.x + cache-dependency-path: cmd/starlet/go.sum + - name: Build and smoke-run + run: | + make -C cmd/starlet test diff --git a/Makefile b/Makefile index fddef81c..7a719fae 100644 --- a/Makefile +++ b/Makefile @@ -38,7 +38,6 @@ default: ci: $(GOTEST) -v -race -cover -covermode=atomic -coverprofile=coverage.txt -count 1 ./... $(GOTEST) -v -parallel=4 -run="none" -benchtime="2s" -benchmem -bench=. - make -C cmd/starlet test build: make -C cmd/starlet build diff --git a/dataconv/interface.go b/dataconv/interface.go index df9a8a5b..1c45a9f9 100644 --- a/dataconv/interface.go +++ b/dataconv/interface.go @@ -4,13 +4,12 @@ // // For data type conversion, it provides functions to convert between Starlark and Go types: // -// +---------+ Marshal +------------+ MarshalStarlarkJSON +----------+ -// | | ----------> | | ----------------------> | | -// | Go | | Starlark | | JSON | -// | Value | <---------- | Value | <---------------------- | String | -// | | Unmarshal | | UnmarshalStarlarkJSON | | -// +---------+ +------------+ +----------+ -// +// +---------+ Marshal +------------+ MarshalStarlarkJSON +----------+ +// | | ----------> | | ----------------------> | | +// | Go | | Starlark | | JSON | +// | Value | <---------- | Value | <---------------------- | String | +// | | Unmarshal | | UnmarshalStarlarkJSON | | +// +---------+ +------------+ +----------+ package dataconv import "go.starlark.net/starlark" diff --git a/internal/replacecr/replace_cr.go b/internal/replacecr/replace_cr.go index 57a06766..66b40fea 100644 --- a/internal/replacecr/replace_cr.go +++ b/internal/replacecr/replace_cr.go @@ -11,7 +11,9 @@ import ( // for instances of lonely \r replacing them with \r\n before returning to the end consumer // lots of files in the wild will come without "proper" line breaks, which irritates go's // standard csv package. This'll fix by wrapping the reader passed to csv.NewReader: -// rdr, err := csv.NewReader(replacecr.Reader(r)) +// +// rdr, err := csv.NewReader(replacecr.Reader(r)) +// // because Reader adds '\n' characters, the number of bytes reported from the underlying // reader can/will differ from what the underlyng reader would return // if read from directly. This can cause issues with checksums and byte counts. diff --git a/lib/http/server.go b/lib/http/server.go index 88df4439..569853fb 100644 --- a/lib/http/server.go +++ b/lib/http/server.go @@ -29,12 +29,12 @@ var ( // - JSON body support simplifies working with JSON payloads directly in scripts. // // Usage Pattern: -// 1. Convert an incoming http.Request to ExportedServerRequest with NewExportedServerRequest for access in Go. -// 2. Modify the ExportedServerRequest properties as needed in Go before handing off to Starlark. -// 3. Use the Struct method to convert the ExportedServerRequest to a Starlark struct, passing it to Starlark scripts -// for read-only access. This step allows scripts to inspect the request's properties. -// 4. Since the Starlark struct is read-only, modifications to the request must be performed in Go, either before -// or after script execution. +// 1. Convert an incoming http.Request to ExportedServerRequest with NewExportedServerRequest for access in Go. +// 2. Modify the ExportedServerRequest properties as needed in Go before handing off to Starlark. +// 3. Use the Struct method to convert the ExportedServerRequest to a Starlark struct, passing it to Starlark scripts +// for read-only access. This step allows scripts to inspect the request's properties. +// 4. Since the Starlark struct is read-only, modifications to the request must be performed in Go, either before +// or after script execution. // // This design prioritizes ease of use, security, and performance, facilitating dynamic and complex request processing // logic through Go and Starlark. It ensures the integrity of the HTTP request handling by preventing unauthorized @@ -169,12 +169,12 @@ func NewServerResponse() *ServerResponse { // - Setting the response body with support for various data types (e.g., binary, text, HTML, JSON). // // Usage Pattern: -// 1. Create a ServerResponse instance using NewServerResponse(). -// 2. Utilize the Struct() method to obtain a Starlark struct that exposes ServerResponse functionalities to Starlark scripts. -// 3. In the Starlark script, utilize provided methods (e.g., set_status, add_header, set_content_type) to prepare the response. -// 4. Back in Go, the ServerResponse instance can directly write its content to an http.ResponseWriter using its Write() method. -// Alternatively, you can call the Export() method to convert the ServerResponse into an ExportedServerResponse for modification, -// which is then capable of being written to an http.ResponseWriter using its Write() method. +// 1. Create a ServerResponse instance using NewServerResponse(). +// 2. Utilize the Struct() method to obtain a Starlark struct that exposes ServerResponse functionalities to Starlark scripts. +// 3. In the Starlark script, utilize provided methods (e.g., set_status, add_header, set_content_type) to prepare the response. +// 4. Back in Go, the ServerResponse instance can directly write its content to an http.ResponseWriter using its Write() method. +// Alternatively, you can call the Export() method to convert the ServerResponse into an ExportedServerResponse for modification, +// which is then capable of being written to an http.ResponseWriter using its Write() method. // // Internally, ServerResponse uses a private contentDataType enum to manage the intended type of the response data, // allowing for automatic adjustment of the Content-Type header based on the set data type by the Starlark script. diff --git a/run_test.go b/run_test.go index f9493ef4..6421a5c4 100644 --- a/run_test.go +++ b/run_test.go @@ -1529,7 +1529,8 @@ func Test_Machine_Run_With_Timeout(t *testing.T) { // second run with timeout, but context is not handled in builtin sleep m.SetScript("time.star", []byte(`c = 3; sleep_go(itn); d = 4`), nil) ts = time.Now() - ctx, _ := context.WithTimeout(context.Background(), interval/2) + ctx, cancel := context.WithTimeout(context.Background(), interval/2) + defer cancel() out, err = m.RunWithContext(ctx, nil) expectSameDuration(t, time.Since(ts), interval) expectErr(t, err, "starlark: exec: Starlark computation cancelled: context cancelled") @@ -1609,7 +1610,8 @@ sleep(1) t = 4 `), nil) ts = time.Now() - ctx, _ := context.WithTimeout(context.Background(), 500*time.Millisecond) + ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond) + defer cancel() out, err = m.RunWithContext(ctx, nil) expectSameDuration(t, time.Since(ts), 500*time.Millisecond) expectErr(t, err, "starlark: exec: context deadline exceeded") @@ -1622,7 +1624,8 @@ sleep(0.5) t = 4 `), nil) ts = time.Now() - ctx, _ = context.WithTimeout(context.Background(), 800*time.Millisecond) // TODO! occasionally, this test fails with 500ms timeout + ctx, cancel2 := context.WithTimeout(context.Background(), 800*time.Millisecond) // TODO! occasionally, this test fails with 500ms timeout + defer cancel2() out, err = m.RunWithContext(ctx, nil) expectSameDuration(t, time.Since(ts), 500*time.Millisecond) if err != nil {