From db7cd82fd7ca8a551469fc7241b1503c815a5929 Mon Sep 17 00:00:00 2001 From: Mikael Lixenstrand Date: Tue, 2 Jun 2026 09:02:11 +0200 Subject: [PATCH 1/2] Harden CI workflow and modernize OTP/runner matrix Addresses findings from a security scan of .github/workflows/main.yml: - Pin every GitHub Action to a full commit SHA (with version comment) to mitigate mutable-tag supply-chain risk - Upgrade outdated/vulnerable actions: * actions/checkout v2 -> v6.0.2 * actions/cache v2 -> v5.0.5 * codecov/codecov-action v2 -> v6.0.1 (was subject to CVE-2022-1681) * actions/setup-go v4 -> v6.4.0 * erlef/setup-beam v1 -> v1.24.0 - Add top-level permissions: contents: read for least-privilege GITHUB_TOKEN - Rename Codecov input file: -> files: (required by codecov-action v4+) - Add .github/dependabot.yml for weekly github-actions updates so SHA pins stay current Unrelated modernization in the same workflow: - Switch runner from ubuntu-20.04 (removed from GitHub-hosted runners in April 2025) to ubuntu-24.04 - Update OTP matrix to currently supported majors (26, 27, 28); drops EOL 23.3, 24.1.2, 25.2.3 - Bump rebar3 to 3.27.0 in both jobs - Drop version-type: strict on the dialyzer setup-beam step (no longer compatible with loose major-only version spec) --- .github/dependabot.yml | 6 ++++++ .github/workflows/main.yml | 34 ++++++++++++++++++---------------- 2 files changed, 24 insertions(+), 16 deletions(-) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..5ace460 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index da1c522..7532cdd 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -8,22 +8,25 @@ on: branches: - 'main' +permissions: + contents: read + jobs: build: name: Test on OTP ${{ matrix.otp_version }} and ${{ matrix.os }} runs-on: ${{ matrix.os }} strategy: matrix: - otp_version: ['26.0', '25.2.3', '24.1.2', '23.3'] - rebar3_version: ['3.20.0'] - os: [ubuntu-20.04] + otp_version: ['28', '27', '26'] + rebar3_version: ['3.27.0'] + os: [ubuntu-24.04] env: OTP_VERSION: ${{ matrix.otp_version }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: erlef/setup-beam@v1 + - uses: erlef/setup-beam@fc68ffb90438ef2936bbb3251622353b3dcb2f93 # v1.24.0 with: otp-version: ${{ matrix.otp_version }} rebar3-version: ${{ matrix.rebar3_version }} @@ -34,19 +37,19 @@ jobs: run: rebar3 ct --cover - name: Covertool run: rebar3 covertool generate - - uses: codecov/codecov-action@v2 + - uses: codecov/codecov-action@e79a6962e0d4c0c17b229090214935d2e33f8354 # v6.0.1 if: ${{ always() }} with: - file: _build/test/covertool/grpcbox.covertool.xml + files: _build/test/covertool/grpcbox.covertool.xml env_vars: OTP_VERSION - name: Setup Go 1.21.4 - uses: actions/setup-go@v4 + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 with: # Semantic version range syntax or exact version of Go go-version: '1.21.4' - - uses: actions/checkout@v4 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: repository: 'grpc/grpc-go' path: 'grpc-go' @@ -68,17 +71,16 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - otp_version: ['26.0'] - rebar3_version: ['3.22.1'] - os: [ubuntu-20.04] + otp_version: ['28'] + rebar3_version: ['3.27.0'] + os: [ubuntu-24.04] steps: - - uses: actions/checkout@v2 - - uses: erlef/setup-beam@v1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: erlef/setup-beam@fc68ffb90438ef2936bbb3251622353b3dcb2f93 # v1.24.0 with: otp-version: ${{ matrix.otp_version }} rebar3-version: ${{ matrix.rebar3_version }} - version-type: 'strict' - - uses: actions/cache@v2 + - uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 name: Cache with: path: | From 59968ae6cca07bd06cb0f1e242161c02ba8944c4 Mon Sep 17 00:00:00 2001 From: Mikael Lixenstrand Date: Tue, 2 Jun 2026 13:15:02 +0200 Subject: [PATCH 2/2] Fix dialyzer warnings for unset interval fields The refresh_interval and idle_interval record fields in #data{} are declared but never assigned, so they default to undefined. Allow undefined in the type spec to match the runtime reality, consistent with other optional fields in the same records. --- src/grpcbox_channel.erl | 2 +- src/grpcbox_subchannel.erl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/grpcbox_channel.erl b/src/grpcbox_channel.erl index 2c4781f..0656f65 100644 --- a/src/grpcbox_channel.erl +++ b/src/grpcbox_channel.erl @@ -46,7 +46,7 @@ stream_interceptor => grpcbox_client:stream_interceptor()} | undefined, stats_handler :: module() | undefined, - refresh_interval :: timer:time()}). + refresh_interval :: timer:time() | undefined}). -spec start_link(name(), [endpoint()], options()) -> {ok, pid()} | ignore | {error, term()}. start_link(Name, Endpoints, Options) -> diff --git a/src/grpcbox_subchannel.erl b/src/grpcbox_subchannel.erl index 02c589f..c7c2e42 100644 --- a/src/grpcbox_subchannel.erl +++ b/src/grpcbox_subchannel.erl @@ -25,7 +25,7 @@ }, conn :: h2_stream_set:stream_set() | undefined, conn_pid :: pid() | undefined, - idle_interval :: timer:time()}). + idle_interval :: timer:time() | undefined}). start_link(Name, Channel, Endpoint, Encoding, StatsHandler) -> gen_statem:start_link(?MODULE, [Name, Channel, Endpoint, Encoding, StatsHandler], []).