Skip to content

Conversation

dnaeon
Copy link
Contributor

@dnaeon dnaeon commented Oct 13, 2025

Description

The api-compatibility workflow sets custom options for apidiff as part of the Compare-States and Check-States steps here.

These opts are picked up by the Makefile and collected in the APICOMPARE_OPTS var here.

  • # If we are running in CI, change input directory
    ifeq ($(CI), true)
    APICOMPARE_OPTS=$(COMPARE_OPTS)
    else
    APICOMPARE_OPTS=-d "./internal/data/apidiff"
    endif

However, these options are not propagated to apidiff when invoking the apidiff-compare target.

  • # Compare API state snapshots
    .PHONY: apidiff-compare
    apidiff-compare:
    @$(foreach pkg,$(ALL_PKGS),$(call exec-command,./internal/buildscripts/compare-apidiff.sh -p $(pkg)))

This PR propagates the APICOMPARE_OPTS to the apidiff-compare target, so that any configured options (e.g. by workflows) are respected.

Link to tracking issue

None

Testing

Documentation

@dnaeon dnaeon requested a review from a team as a code owner October 13, 2025 09:30
@dnaeon dnaeon requested a review from songy23 October 13, 2025 09:30
@github-actions github-actions bot added the release:risky-change This change may affect the release label Oct 13, 2025
Copy link

codecov bot commented Oct 13, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.64%. Comparing base (a96eab1) to head (4640e24).

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #14004      +/-   ##
==========================================
- Coverage   91.67%   91.64%   -0.03%     
==========================================
  Files         654      654              
  Lines       42659    42659              
==========================================
- Hits        39107    39095      -12     
- Misses       2738     2747       +9     
- Partials      814      817       +3     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@dmathieu dmathieu added the Skip Changelog PRs that do not require a CHANGELOG.md entry label Oct 13, 2025
@dmathieu
Copy link
Member

I'm slightly surprised this worked and hasn't been changed since 2021 (#3464).

@dnaeon
Copy link
Contributor Author

dnaeon commented Oct 13, 2025

I'm slightly surprised this worked and hasn't been changed since 2021 (#3464).

Yeah, that's a long time :)

@dmathieu
Copy link
Member

If we have been without this for so long, do we even need the opts?

@dnaeon
Copy link
Contributor Author

dnaeon commented Oct 13, 2025

If we have been without this for so long, do we even need the opts?

Maybe, maybe not :)

On one side things are working as expected today, however I think some changes might be needed.

  • The workflow is misleading as it is today, because readers may assume these opts are actually in use, while they are not.
  • The fact that the opts are not used at all, it actually makes Compare-States and Check-States steps identical (the Check-States step uses extra option -c for check-only, but this one is discarded).

Also, the compare-apidiff.sh and gen-apidiff.sh scripts default to internal/data/apidiff, which is populated by the Generate-States here, which might be the reason for "it just works", I'll need to double check these tomorrow once again :)

- name: Generate-States
run: |
cd $BASE_REF
make apidiff-build

... and the workflow steps are supposed to execute against the branch from the PR.

Please hold this one for now, until things get more clarity :)

WDYT?

@dnaeon
Copy link
Contributor Author

dnaeon commented Oct 14, 2025

Hey @dmathieu ,

Had some time this morning to check things again and here's what I have so far.

I'm slightly surprised this worked and hasn't been changed since 2021 (#3464).

After going again through the gen-apidiff.sh, compare-apidiff.sh scripts, and the Inform Incompatible PRs workflow I believe this never actually worked correctly since the start.

Here's why.

  1. gen-apidiff.sh creates state files for each package in internal/data/apidiff by default.

- name: Generate-States
run: |
cd $BASE_REF
make apidiff-build

dry_run=false
package=""
output_dir="./internal/data/apidiff"
repo_toplevel="$( git rev-parse --show-toplevel )"
tools_mod_file="${repo_toplevel}/internal/tools/go.mod"

  1. Since the COMPARE_OPTS are never propagated from the workflow to the Makefile target, when the apidiff-compare target is called it uses its defaults as well.

- name: Compare-States
env:
CI: true
COMPARE_OPTS: -d "../${{ github.base_ref }}/internal/data/apidiff"
run: |
cd $HEAD_REF
make apidiff-compare
# Fail GitHub Action if there are incompatible changes
- name: Check-States
env:
CI: true
COMPARE_OPTS: -d "../${{ github.base_ref }}/internal/data/apidiff" -c
run: |
cd $HEAD_REF
make apidiff-compare

package=""
input_dir="./internal/data/apidiff"
check_only=false
repo_toplevel="$( git rev-parse --show-toplevel )"
tools_mod_file="${repo_toplevel}/internal/tools/go.mod"

  1. At this point in Compare-States step both the input_dir and output_dir for gen-apidiff.sh and compare-apidiff.sh are the same values (internal/data/apidiff), but the are in different parent directories, so no check is actually performed, because of this test here.

if [ -e "$input_dir"/"$package"/apidiff.state ]; then

Here's an example run of the workflow in my fork with debugging enabled, which shows that the step succeeds silently, without actually comparing anything.

https://github.com/dnaeon/opentelemetry-collector/actions/runs/18489346746/job/52679115017

Run cd $HEAD_REF
+ '[' -e ../main/internal/data/apidiff/go.opentelemetry.io/collector/internal/statusutil/apidiff.state ']'
+ '[' -e ../main/internal/data/apidiff/go.opentelemetry.io/collector/internal/testutil/apidiff.state ']'

In my fork I've also created one example PR, which introduces a breaking change in one of the internal/ packages, just to show that it is correctly detected and reported.

And here's the workflow run for it.

https://github.com/dnaeon/opentelemetry-collector/actions/runs/18490457959/job/52682606364?pr=6

make: Entering directory '/home/runner/work/opentelemetry-collector/opentelemetry-collector/main'
make: Leaving directory '/home/runner/work/opentelemetry-collector/opentelemetry-collector/main'
make: Entering directory '/home/runner/work/opentelemetry-collector/opentelemetry-collector/test/apidiff-change'
Changes found in go.opentelemetry.io/collector/internal/testutil:
Incompatible changes:
- GetAvailableLocalAddress: changed from func(testing.TB) string to func(testing.TB) (string, error)
make: Leaving directory '/home/runner/work/opentelemetry-collector/opentelemetry-collector/test/apidiff-change'
make: Entering directory '/home/runner/work/opentelemetry-collector/opentelemetry-collector/test/apidiff-change'
Incompatible Changes Found.
Check the logs in the GitHub Action log group: 'Check-API-Compatibility'.
make: *** [Makefile:348: apidiff-compare] Error 1
make: Leaving directory '/home/runner/work/opentelemetry-collector/opentelemetry-collector/test/apidiff-change'
Error: Process completed with exit code 2.

I've also updated this PR with the changes to the workflow.

A couple of follow questions, which are not related to this PR, but might be implemented in future ones:

  • Should we include the internal packages to the list of packages being checked for API compat?
  • Should the rest of the modules (e.g. receiver, exporter, etc.) be checked for API compat as well?

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release:risky-change This change may affect the release Skip Changelog PRs that do not require a CHANGELOG.md entry

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants