From 461b66803717fa96453f29cacc6f6174717dca04 Mon Sep 17 00:00:00 2001 From: Alessio Perugini Date: Tue, 12 Aug 2025 14:02:18 +0200 Subject: [PATCH 1/2] commands: use the new endpoint to detect boards (#2974) * commands: use the new endpoint to detect boards * commands: change cacheKey * commands: push always on top the `arduino` vendor --- commands/service_board_identify.go | 41 +++++++++++------ commands/service_board_identify_test.go | 59 ++++++++++++++++++++----- 2 files changed, 75 insertions(+), 25 deletions(-) diff --git a/commands/service_board_identify.go b/commands/service_board_identify.go index 787de81cee3..fd3fcee300c 100644 --- a/commands/service_board_identify.go +++ b/commands/service_board_identify.go @@ -23,6 +23,7 @@ import ( "io" "net/http" "regexp" + "slices" "sort" "strings" "time" @@ -130,14 +131,14 @@ func identifyViaCloudAPI(ctx context.Context, props *properties.Map, settings *c } var ( - vidPidURL = "https://builder.arduino.cc/v3/boards/byVidPid" + vidPidURL = "https://api2.arduino.cc/boards/v1/boards" validVidPid = regexp.MustCompile(`0[xX][a-fA-F\d]{4}`) ) func cachedAPIByVidPid(ctx context.Context, vid, pid string, settings *configuration.Settings) ([]*rpc.BoardListItem, error) { var resp []*rpc.BoardListItem - cacheKey := fmt.Sprintf("cache.builder-api.v3/boards/byvid/pid/%s/%s", vid, pid) + cacheKey := fmt.Sprintf("cache.api2.arduino.cc/boards/v1/boards?vid-pid=%s-%s", vid, pid) if cachedResp := inventory.Store.GetString(cacheKey + ".data"); cachedResp != "" { ts := inventory.Store.GetTime(cacheKey + ".ts") if time.Since(ts) < time.Hour*24 { @@ -169,7 +170,7 @@ func apiByVidPid(ctx context.Context, vid, pid string, settings *configuration.S return nil, errors.New(i18n.Tr("Invalid pid value: '%s'", pid)) } - url := fmt.Sprintf("%s/%s/%s", vidPidURL, vid, pid) + url := fmt.Sprintf("%s?vid-pid=%s-%s", vidPidURL, vid, pid) req, _ := http.NewRequest("GET", url, nil) req.Header.Set("Content-Type", "application/json") @@ -198,20 +199,32 @@ func apiByVidPid(ctx context.Context, vid, pid string, settings *configuration.S return nil, err } - var dat map[string]interface{} + type boardsResponse struct { + Items []struct { + Name string `json:"name"` + FQBN string `json:"fqbn"` + } `json:"items"` + } + var dat boardsResponse if err := json.Unmarshal(resp, &dat); err != nil { return nil, fmt.Errorf("%s: %w", i18n.Tr("error processing response from server"), err) } - name, nameFound := dat["name"].(string) - fqbn, fbqnFound := dat["fqbn"].(string) - if !nameFound || !fbqnFound { - return nil, errors.New(i18n.Tr("wrong format in server response")) + + response := make([]*rpc.BoardListItem, len(dat.Items)) + for i, v := range dat.Items { + if v.Name == "" || v.FQBN == "" { + return nil, errors.New(i18n.Tr("wrong format in server response")) + } + response[i] = &rpc.BoardListItem{Name: v.Name, Fqbn: v.FQBN} } - return []*rpc.BoardListItem{ - { - Name: name, - Fqbn: fqbn, - }, - }, nil + // In case multiple platform matches the same vid-pid we put on top + // the arduino ones + slices.SortFunc(response, func(a, b *rpc.BoardListItem) int { + if strings.HasPrefix(a.Fqbn, "arduino") { + return -1 + } + return 0 + }) + return response, nil } diff --git a/commands/service_board_identify_test.go b/commands/service_board_identify_test.go index 31687359885..28561b19cf8 100644 --- a/commands/service_board_identify_test.go +++ b/commands/service_board_identify_test.go @@ -35,13 +35,15 @@ func TestGetByVidPid(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, ` { - "architecture": "samd", - "fqbn": "arduino:samd:mkr1000", - "href": "/v3/boards/arduino:samd:mkr1000", - "id": "mkr1000", - "name": "Arduino/Genuino MKR1000", - "package": "arduino", - "plan": "create-free" + "items": [ + { + "fqbn": "arduino:avr:uno", + "vendor": "arduino", + "architecture": "avr", + "board_id": "uno", + "name": "Arduino Uno" + } + ] } `) })) @@ -49,11 +51,11 @@ func TestGetByVidPid(t *testing.T) { vidPidURL = ts.URL settings := configuration.NewSettings() - res, err := apiByVidPid(context.Background(), "0xf420", "0XF069", settings) + res, err := apiByVidPid(context.Background(), "0x2341", "0x0043", settings) require.Nil(t, err) require.Len(t, res, 1) - require.Equal(t, "Arduino/Genuino MKR1000", res[0].GetName()) - require.Equal(t, "arduino:samd:mkr1000", res[0].GetFqbn()) + require.Equal(t, "Arduino Uno", res[0].GetName()) + require.Equal(t, "arduino:avr:uno", res[0].GetFqbn()) // wrong vid (too long), wrong pid (not an hex value) @@ -61,6 +63,41 @@ func TestGetByVidPid(t *testing.T) { require.NotNil(t, err) } +func TestGetByVidPidPutArduinoOnTop(t *testing.T) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintln(w, ` +{ + "items": [ + { + "fqbn": "esp32:esp32:nano_nora", + "vendor": "esp32", + "architecture": "esp32", + "board_id": "nano_nora", + "name": "Arduino Nano ESP32" + }, + { + "fqbn": "arduino:esp32:nano_nora", + "vendor": "arduino", + "architecture": "esp32", + "board_id": "nano_nora", + "name": "Arduino Nano ESP32" + } + ] +} + `) + })) + defer ts.Close() + + vidPidURL = ts.URL + settings := configuration.NewSettings() + res, err := apiByVidPid(context.Background(), "0x2341", "0x0070", settings) + require.Nil(t, err) + require.Len(t, res, 2) + require.Equal(t, "Arduino Nano ESP32", res[0].GetName()) + require.Equal(t, "arduino:esp32:nano_nora", res[0].GetFqbn()) + require.Equal(t, "esp32:esp32:nano_nora", res[1].GetFqbn()) +} + func TestGetByVidPidNotFound(t *testing.T) { settings := configuration.NewSettings() @@ -95,7 +132,7 @@ func TestGetByVidPidMalformedResponse(t *testing.T) { settings := configuration.NewSettings() ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - fmt.Fprintln(w, "{}") + fmt.Fprintln(w, `{"items":[{}]}`) })) defer ts.Close() From eb4e2ca773737f8d9ee30437f650b30c13b1dbf5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Aug 2025 18:06:57 -0700 Subject: [PATCH 2/2] [skip changelog] Bump actions/checkout from 4 to 5 (#2976) Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/check-easyjson.yml | 2 +- .github/workflows/check-go-dependencies-task.yml | 4 ++-- .github/workflows/check-go-task.yml | 12 ++++++------ .github/workflows/check-i18n-task.yml | 2 +- .github/workflows/check-license.yml | 2 +- .github/workflows/check-markdown-task.yml | 4 ++-- .github/workflows/check-mkdocs-task.yml | 2 +- .github/workflows/check-prettier-formatting-task.yml | 2 +- .github/workflows/check-protobuf-task.yml | 4 ++-- .../deploy-cobra-mkdocs-versioned-poetry.yml | 2 +- .github/workflows/i18n-nightly-push.yaml | 2 +- .github/workflows/i18n-weekly-pull.yaml | 2 +- .github/workflows/publish-go-nightly-task.yml | 8 ++++---- .github/workflows/publish-go-tester-task.yml | 2 +- .github/workflows/release-go-task.yml | 8 ++++---- .github/workflows/release-proto-files.yml | 2 +- .github/workflows/sync-labels.yml | 4 ++-- .github/workflows/test-go-task.yml | 8 ++++---- 18 files changed, 36 insertions(+), 36 deletions(-) diff --git a/.github/workflows/check-easyjson.yml b/.github/workflows/check-easyjson.yml index 419f736256a..620037197b0 100644 --- a/.github/workflows/check-easyjson.yml +++ b/.github/workflows/check-easyjson.yml @@ -29,7 +29,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Install Go uses: actions/setup-go@v5 diff --git a/.github/workflows/check-go-dependencies-task.yml b/.github/workflows/check-go-dependencies-task.yml index c3d31664168..a9a0afaca60 100644 --- a/.github/workflows/check-go-dependencies-task.yml +++ b/.github/workflows/check-go-dependencies-task.yml @@ -65,7 +65,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: submodules: recursive @@ -116,7 +116,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: submodules: recursive diff --git a/.github/workflows/check-go-task.yml b/.github/workflows/check-go-task.yml index 360c450de35..dc70c07815c 100644 --- a/.github/workflows/check-go-task.yml +++ b/.github/workflows/check-go-task.yml @@ -64,7 +64,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Install Go uses: actions/setup-go@v5 @@ -100,7 +100,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Install Go uses: actions/setup-go@v5 @@ -138,7 +138,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Install Go uses: actions/setup-go@v5 @@ -174,7 +174,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Install Go uses: actions/setup-go@v5 @@ -203,7 +203,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Install Go uses: actions/setup-go@v5 @@ -241,7 +241,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Install Go uses: actions/setup-go@v5 diff --git a/.github/workflows/check-i18n-task.yml b/.github/workflows/check-i18n-task.yml index 0e000fe13b9..ea01c3fad0e 100644 --- a/.github/workflows/check-i18n-task.yml +++ b/.github/workflows/check-i18n-task.yml @@ -19,7 +19,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Install Go uses: actions/setup-go@v5 diff --git a/.github/workflows/check-license.yml b/.github/workflows/check-license.yml index 6b81349a416..7ec1fbc632a 100644 --- a/.github/workflows/check-license.yml +++ b/.github/workflows/check-license.yml @@ -34,7 +34,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Install Ruby uses: ruby/setup-ruby@v1 diff --git a/.github/workflows/check-markdown-task.yml b/.github/workflows/check-markdown-task.yml index 02ae36cb159..4bd7fd4e13f 100644 --- a/.github/workflows/check-markdown-task.yml +++ b/.github/workflows/check-markdown-task.yml @@ -75,7 +75,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Setup Node.js uses: actions/setup-node@v4 @@ -101,7 +101,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Setup Node.js uses: actions/setup-node@v4 diff --git a/.github/workflows/check-mkdocs-task.yml b/.github/workflows/check-mkdocs-task.yml index 18680faab36..d7646201306 100644 --- a/.github/workflows/check-mkdocs-task.yml +++ b/.github/workflows/check-mkdocs-task.yml @@ -34,7 +34,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Install Go uses: actions/setup-go@v5 diff --git a/.github/workflows/check-prettier-formatting-task.yml b/.github/workflows/check-prettier-formatting-task.yml index 5bb45e35d55..459682c8182 100644 --- a/.github/workflows/check-prettier-formatting-task.yml +++ b/.github/workflows/check-prettier-formatting-task.yml @@ -204,7 +204,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Install Task uses: arduino/setup-task@v2 diff --git a/.github/workflows/check-protobuf-task.yml b/.github/workflows/check-protobuf-task.yml index 449c78e0e18..90fc6dc5a2f 100644 --- a/.github/workflows/check-protobuf-task.yml +++ b/.github/workflows/check-protobuf-task.yml @@ -51,7 +51,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Install buf uses: bufbuild/buf-action@v1 @@ -77,7 +77,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 # used by the protobuf breaking change detector - name: Fetch main branch diff --git a/.github/workflows/deploy-cobra-mkdocs-versioned-poetry.yml b/.github/workflows/deploy-cobra-mkdocs-versioned-poetry.yml index 76f32ad3eaa..59a37942e3f 100644 --- a/.github/workflows/deploy-cobra-mkdocs-versioned-poetry.yml +++ b/.github/workflows/deploy-cobra-mkdocs-versioned-poetry.yml @@ -54,7 +54,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Install Go uses: actions/setup-go@v5 diff --git a/.github/workflows/i18n-nightly-push.yaml b/.github/workflows/i18n-nightly-push.yaml index 0539549159d..1a6d2c34d15 100644 --- a/.github/workflows/i18n-nightly-push.yaml +++ b/.github/workflows/i18n-nightly-push.yaml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Install Go uses: actions/setup-go@v5 diff --git a/.github/workflows/i18n-weekly-pull.yaml b/.github/workflows/i18n-weekly-pull.yaml index 173d8070094..c9b99dbdfcf 100644 --- a/.github/workflows/i18n-weekly-pull.yaml +++ b/.github/workflows/i18n-weekly-pull.yaml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Install Go uses: actions/setup-go@v5 diff --git a/.github/workflows/publish-go-nightly-task.yml b/.github/workflows/publish-go-nightly-task.yml index 44130b9f25f..6d67896122c 100644 --- a/.github/workflows/publish-go-nightly-task.yml +++ b/.github/workflows/publish-go-nightly-task.yml @@ -45,7 +45,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Install Task uses: arduino/setup-task@v2 @@ -91,7 +91,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Download artifacts uses: actions/download-artifact@v5 @@ -196,7 +196,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Download artifacts uses: actions/download-artifact@v5 @@ -250,7 +250,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Download artifact uses: actions/download-artifact@v5 diff --git a/.github/workflows/publish-go-tester-task.yml b/.github/workflows/publish-go-tester-task.yml index e813189cb21..424aca2da35 100644 --- a/.github/workflows/publish-go-tester-task.yml +++ b/.github/workflows/publish-go-tester-task.yml @@ -128,7 +128,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: fetch-depth: 0 diff --git a/.github/workflows/release-go-task.yml b/.github/workflows/release-go-task.yml index c3c0b113fc1..db7b01f468f 100644 --- a/.github/workflows/release-go-task.yml +++ b/.github/workflows/release-go-task.yml @@ -46,7 +46,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: fetch-depth: 0 @@ -100,7 +100,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Download artifacts uses: actions/download-artifact@v5 @@ -205,7 +205,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Download artifacts uses: actions/download-artifact@v5 @@ -259,7 +259,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Download artifact uses: actions/download-artifact@v5 diff --git a/.github/workflows/release-proto-files.yml b/.github/workflows/release-proto-files.yml index abe11708d60..6b51fd29e84 100644 --- a/.github/workflows/release-proto-files.yml +++ b/.github/workflows/release-proto-files.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: fetch-depth: 0 - uses: bufbuild/buf-action@v1 diff --git a/.github/workflows/sync-labels.yml b/.github/workflows/sync-labels.yml index 291d637d801..c7e6dd9ba82 100644 --- a/.github/workflows/sync-labels.yml +++ b/.github/workflows/sync-labels.yml @@ -27,7 +27,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Download JSON schema for labels configuration file id: download-schema @@ -106,7 +106,7 @@ jobs: echo "flag=--dry-run" >> $GITHUB_OUTPUT - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Download configuration files artifact uses: actions/download-artifact@v5 diff --git a/.github/workflows/test-go-task.yml b/.github/workflows/test-go-task.yml index fae25b28db8..30c81224dfa 100644 --- a/.github/workflows/test-go-task.yml +++ b/.github/workflows/test-go-task.yml @@ -66,7 +66,7 @@ jobs: tests-data: ${{ steps.collection.outputs.tests-data }} steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Collect tests id: collection @@ -93,7 +93,7 @@ jobs: run: git config --global core.autocrlf false - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Install Go uses: actions/setup-go@v5 @@ -139,7 +139,7 @@ jobs: run: git config --global core.autocrlf false - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Install Go uses: actions/setup-go@v5 @@ -171,7 +171,7 @@ jobs: - test-integration steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Install Go uses: actions/setup-go@v5