Skip to content

Add labels to PRs with potential ABI breaks #15682

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from

Conversation

cmb69
Copy link
Member

@cmb69 cmb69 commented Aug 31, 2024

ABI breaks are not supposed to happen after feature freeze, i.e. when
the PHP API numbers have been bumped. To make it easier to notice
inadvertent ABI breaks, we automatically add an "ABI break" label to
all PRs which modify public (aka. installed) header files. Some of
these modifications do not constitute an ABI break (e.g. adding a
comment to a header file), but we rely on natural intelligence to sort
that out. That means these labels should be removed manually, if they
are not appropriate, but if they are, the PR should not be merged into
any stable branch. For the master branch, where ABI breaks are
permissible, the labels should still be removed if irrelevant, but kept
when the PR is merged.

TODO:

  • Explain what this is about (and what it's not)
  • Choose and define a meaningful label ("Potential ABI break"? "ABI break")
  • Only check public headers (i.e. those which will be installed)
  • Add non Windows public headers to the list (apparently, there are none)
  • Move the new label with the long list of public headers to the bottom of labeler.yml
  • [ ] Target PHP-8.2 (see below)

@cmb69
Copy link
Member Author

cmb69 commented Aug 31, 2024

I generated the list of public headers by applying the following

patch
 win32/build/confutils.js | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/win32/build/confutils.js b/win32/build/confutils.js
index 95a4e5ce3c..796fb0d167 100644
--- a/win32/build/confutils.js
+++ b/win32/build/confutils.js
@@ -67,6 +67,8 @@ var sapi_enabled = new Array();
 /* Store the headers to install */
 var headers_install = new Array();
 
+var headers_install_yaml = new Array();
+
 /* Store unknown configure options */
 var INVALID_CONFIG_ARGS = new Array();
 
@@ -2090,6 +2092,7 @@ function generate_files()
 	STDOUT.WriteLine("Generating files...");
 	generate_tmp_php_ini();
 	generate_makefile();
+	generate_headers_install_yaml();
 	if (!MODE_PHPIZE) {
 		generate_internal_functions();
 		generate_config_h();
@@ -2630,6 +2633,17 @@ function generate_makefile()
 	MF.Close();
 }
 
+function generate_headers_install_yaml()
+{
+	STDOUT.WriteLine("Generating Makefile");
+	var yaml = FSO.CreateTextFile("public_headers.yaml", true);
+	headers_install_yaml = headers_install_yaml.sort();
+	for (var i in headers_install_yaml) {
+		yaml.WriteLine("      - '" + headers_install_yaml[i] + "'");
+	}
+	yaml.Close();
+}
+
 function ADD_FLAG(name, flags, target)
 {
 	if (target != null) {
@@ -2863,11 +2877,13 @@ function PHP_INSTALL_HEADERS(dir, headers_list)
 				src += '\\';
 			}
 			headers_install[headers_install.length] = [dir + src, 'dir',''];
+			headers_install_yaml[headers_install_yaml.length] = (dir + src).replace(new RegExp("\\\\", "g"), "/") + "*.h";
 			ADD_FLAG("INSTALL_HEADERS_DIR", dir + src);
 			found = true;
 		} else if (isfile) {
 			dirname = FSO.GetParentFolderName(dir + src);
 			headers_install[headers_install.length] = [dir + src, 'file', dirname];
+			headers_install_yaml[headers_install_yaml.length] = (dir + src).replace(new RegExp("\\\\", "g"), "/");
 			ADD_FLAG("INSTALL_HEADERS", dir + src);
 			found = true;
 		} else {
@@ -2879,10 +2895,12 @@ function PHP_INSTALL_HEADERS(dir, headers_list)
 					src += '\\';
 				}
 				headers_install[headers_install.length] = [path, 'dir',''];
+				ERROR("unsupported for YAML");
 				ADD_FLAG("INSTALL_HEADERS_DIR", path);
 			} else if (isfile) {
 				dirname = FSO.GetParentFolderName(path);
 				headers_install[headers_install.length] = [path, 'file', dir];
+				ERROR("unsupported for YAML");
 				ADD_FLAG("INSTALL_HEADERS", dir + src);
 				found = true;
 			}

and then ran buildconf && configure --enable-snapshot-build, and finally copy-pasting public_headers.yaml into labeler.yml`. I don't know how this could be done for other systems; adding the missing headers manually would be a last resort.

@cmb69
Copy link
Member Author

cmb69 commented Aug 31, 2024

I don't know if I screwed up somewhere, or if it is not possible to test the labelling in this PR right away. Maybe @iluuu1994 knows?

@iluuu1994
Copy link
Member

The output says:

The configuration file (path: .github/labeler.yml) was not found locally, fetching via the api

This is because we're not actually checking out the repo when running the labeler:

https://github.com/php/php-src/blob/master/.github/workflows/labeler.yml

I suspect that the file is fetched from the default branch, but I don't know for sure.

ABI breaks are not supposed to happen after feature freeze, i.e. when
the PHP API numbers have been bumped.  To make it easier to notice
inadvertent ABI breaks, we automatically add an "ABI break" label to
all PRs which modify public (aka. installed) header files.  Some of
these modifications do not constitute an ABI break (e.g. adding a
comment to a header file), but we rely on natural intelligence to sort
that out.  That means these labels should be removed manually, if they
are not appropriate, but if they are, the PR should not be merged into
any stable branch.  For the master branch, where ABI breaks are
permissible, the labels should still be removed if irrelevant, but kept
when the PR is merged.

Since tests are futile[1], we leave that to further (test) PRs.

[1] <php#15682 (comment)>
@cmb69 cmb69 changed the title Add labels to potential ABI breaks Add labels to PRs with potential ABI breaks Sep 1, 2024
@cmb69
Copy link
Member Author

cmb69 commented Sep 3, 2024

Actually, I don't think it makes sense to rebase onto PHP-8.2, since running CI is useless anyway, and there are different sets of public headers for each minor PHP version.

PHP-8.2
      - 'TSRM/*.h'
      - 'Zend/*.h'
      - 'Zend/Optimizer/zend_call_graph.h'
      - 'Zend/Optimizer/zend_cfg.h'
      - 'Zend/Optimizer/zend_dump.h'
      - 'Zend/Optimizer/zend_func_info.h'
      - 'Zend/Optimizer/zend_inference.h'
      - 'Zend/Optimizer/zend_optimizer.h'
      - 'Zend/Optimizer/zend_ssa.h'
      - 'ext/curl/php_curl.h'
      - 'ext/date/lib/timelib.h'
      - 'ext/date/lib/timelib_config.h'
      - 'ext/date/php_date.h'
      - 'ext/dom/xml_common.h'
      - 'ext/filter/php_filter.h'
      - 'ext/gd/*.h'
      - 'ext/gd/libgd/*.h'
      - 'ext/gmp/php_gmp_int.h'
      - 'ext/hash/php_hash.h'
      - 'ext/hash/php_hash_adler32.h'
      - 'ext/hash/php_hash_crc32.h'
      - 'ext/hash/php_hash_gost.h'
      - 'ext/hash/php_hash_haval.h'
      - 'ext/hash/php_hash_md.h'
      - 'ext/hash/php_hash_murmur.h'
      - 'ext/hash/php_hash_ripemd.h'
      - 'ext/hash/php_hash_sha.h'
      - 'ext/hash/php_hash_sha3.h'
      - 'ext/hash/php_hash_snefru.h'
      - 'ext/hash/php_hash_tiger.h'
      - 'ext/hash/php_hash_whirlpool.h'
      - 'ext/hash/php_hash_xxhash.h'
      - 'ext/iconv/*.h'
      - 'ext/json/php_json.h'
      - 'ext/json/php_json_parser.h'
      - 'ext/json/php_json_scanner.h'
      - 'ext/libxml/php_libxml.h'
      - 'ext/mbstring/libmbfl/config.h'
      - 'ext/mbstring/libmbfl/mbfl/eaw_table.h'
      - 'ext/mbstring/libmbfl/mbfl/mbfilter.h'
      - 'ext/mbstring/libmbfl/mbfl/mbfilter_8bit.h'
      - 'ext/mbstring/libmbfl/mbfl/mbfilter_pass.h'
      - 'ext/mbstring/libmbfl/mbfl/mbfilter_wchar.h'
      - 'ext/mbstring/libmbfl/mbfl/mbfl_consts.h'
      - 'ext/mbstring/libmbfl/mbfl/mbfl_convert.h'
      - 'ext/mbstring/libmbfl/mbfl/mbfl_defs.h'
      - 'ext/mbstring/libmbfl/mbfl/mbfl_encoding.h'
      - 'ext/mbstring/libmbfl/mbfl/mbfl_filter_output.h'
      - 'ext/mbstring/libmbfl/mbfl/mbfl_language.h'
      - 'ext/mbstring/libmbfl/mbfl/mbfl_memory_device.h'
      - 'ext/mbstring/libmbfl/mbfl/mbfl_string.h'
      - 'ext/mbstring/mbstring.h'
      - 'ext/mbstring/php_mbregex.h'
      - 'ext/mbstring/php_onig_compat.h'
      - 'ext/mysqli/php_mysqli_structs.h'
      - 'ext/mysqlnd/*.h'
      - 'ext/pcre/pcre2lib/*.h'
      - 'ext/pcre/php_pcre.h'
      - 'ext/pdo/php_pdo.h'
      - 'ext/pdo/php_pdo_driver.h'
      - 'ext/pdo/php_pdo_error.h'
      - 'ext/random/php_random.h'
      - 'ext/session/mod_files.h'
      - 'ext/session/mod_mm.h'
      - 'ext/session/mod_user.h'
      - 'ext/session/php_session.h'
      - 'ext/simplexml/php_simplexml.h'
      - 'ext/simplexml/php_simplexml_exports.h'
      - 'ext/sockets/php_sockets.h'
      - 'ext/sockets/windows_common.h'
      - 'ext/sodium/php_libsodium.h'
      - 'ext/spl/php_spl.h'
      - 'ext/spl/spl_array.h'
      - 'ext/spl/spl_directory.h'
      - 'ext/spl/spl_dllist.h'
      - 'ext/spl/spl_engine.h'
      - 'ext/spl/spl_exceptions.h'
      - 'ext/spl/spl_fixedarray.h'
      - 'ext/spl/spl_functions.h'
      - 'ext/spl/spl_heap.h'
      - 'ext/spl/spl_iterators.h'
      - 'ext/spl/spl_observer.h'
      - 'ext/standard/*.h'
      - 'ext/xml/*.h'
      - 'main/*.h'
      - 'main/streams/*.h'
      - 'sapi/embed/php_embed.h'
      - 'win32/*.h'
PHP-8.3
      - 'TSRM/*.h'
      - 'Zend/*.h'
      - 'Zend/Optimizer/zend_call_graph.h'
      - 'Zend/Optimizer/zend_cfg.h'
      - 'Zend/Optimizer/zend_dump.h'
      - 'Zend/Optimizer/zend_func_info.h'
      - 'Zend/Optimizer/zend_inference.h'
      - 'Zend/Optimizer/zend_optimizer.h'
      - 'Zend/Optimizer/zend_ssa.h'
      - 'ext/date/lib/timelib.h'
      - 'ext/date/lib/timelib_config.h'
      - 'ext/date/php_date.h'
      - 'ext/filter/php_filter.h'
      - 'ext/hash/php_hash.h'
      - 'ext/hash/php_hash_adler32.h'
      - 'ext/hash/php_hash_crc32.h'
      - 'ext/hash/php_hash_gost.h'
      - 'ext/hash/php_hash_haval.h'
      - 'ext/hash/php_hash_md.h'
      - 'ext/hash/php_hash_murmur.h'
      - 'ext/hash/php_hash_ripemd.h'
      - 'ext/hash/php_hash_sha.h'
      - 'ext/hash/php_hash_sha3.h'
      - 'ext/hash/php_hash_snefru.h'
      - 'ext/hash/php_hash_tiger.h'
      - 'ext/hash/php_hash_whirlpool.h'
      - 'ext/hash/php_hash_xxhash.h'
      - 'ext/json/php_json.h'
      - 'ext/json/php_json_parser.h'
      - 'ext/json/php_json_scanner.h'
      - 'ext/mbstring/libmbfl/config.h'
      - 'ext/mbstring/libmbfl/mbfl/eaw_table.h'
      - 'ext/mbstring/libmbfl/mbfl/mbfilter.h'
      - 'ext/mbstring/libmbfl/mbfl/mbfilter_8bit.h'
      - 'ext/mbstring/libmbfl/mbfl/mbfilter_pass.h'
      - 'ext/mbstring/libmbfl/mbfl/mbfilter_wchar.h'
      - 'ext/mbstring/libmbfl/mbfl/mbfl_consts.h'
      - 'ext/mbstring/libmbfl/mbfl/mbfl_convert.h'
      - 'ext/mbstring/libmbfl/mbfl/mbfl_defs.h'
      - 'ext/mbstring/libmbfl/mbfl/mbfl_encoding.h'
      - 'ext/mbstring/libmbfl/mbfl/mbfl_filter_output.h'
      - 'ext/mbstring/libmbfl/mbfl/mbfl_language.h'
      - 'ext/mbstring/libmbfl/mbfl/mbfl_memory_device.h'
      - 'ext/mbstring/libmbfl/mbfl/mbfl_string.h'
      - 'ext/mbstring/mbstring.h'
      - 'ext/mysqli/php_mysqli_structs.h'
      - 'ext/mysqlnd/*.h'
      - 'ext/pcre/pcre2lib/*.h'
      - 'ext/pcre/php_pcre.h'
      - 'ext/pdo/php_pdo.h'
      - 'ext/pdo/php_pdo_driver.h'
      - 'ext/pdo/php_pdo_error.h'
      - 'ext/random/php_random.h'
      - 'ext/session/mod_files.h'
      - 'ext/session/mod_mm.h'
      - 'ext/session/mod_user.h'
      - 'ext/session/php_session.h'
      - 'ext/sockets/php_sockets.h'
      - 'ext/sockets/windows_common.h'
      - 'ext/spl/php_spl.h'
      - 'ext/spl/spl_array.h'
      - 'ext/spl/spl_directory.h'
      - 'ext/spl/spl_dllist.h'
      - 'ext/spl/spl_engine.h'
      - 'ext/spl/spl_exceptions.h'
      - 'ext/spl/spl_fixedarray.h'
      - 'ext/spl/spl_functions.h'
      - 'ext/spl/spl_heap.h'
      - 'ext/spl/spl_iterators.h'
      - 'ext/spl/spl_observer.h'
      - 'ext/standard/*.h'
      - 'main/*.h'
      - 'main/streams/*.h'
      - 'sapi/embed/php_embed.h'
      - 'win32/*.h'

So this can be applied either way.

I'm not quite sure if we should commit the patch above; that would make it easy to recreate the list of public headers. Or maybe someone has a better (or at least more portable solution).

@cmb69 cmb69 marked this pull request as ready for review September 3, 2024 11:32
Copy link
Member

@iluuu1994 iluuu1994 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. One note is that editing the header again will re-add the label. That's a feature. It will also happen when rebasing, which is a bit more annoying.

@cmb69
Copy link
Member Author

cmb69 commented Sep 6, 2024

It will also happen when rebasing, which is a bit more annoying.

Actually, that might be a good thing in this case, since there have been changes about which headers are installed between the minor PHP versions.

@TimWolla TimWolla removed their request for review September 15, 2024 13:00
@cmb69 cmb69 closed this in 170230f Sep 20, 2024
@cmb69 cmb69 deleted the cmb/abi-break branch September 20, 2024 22:15
@DanielEScherzer
Copy link
Member

I might be missing something, but #15988 was tagged as an ABI break and it only changed ext/phar/phar.c - is that meant to be considered an ABI break?

@iluuu1994
Copy link
Member

Indeed, good catch. Sadly, the job output is not helpful. https://github.com/php/php-src/actions/runs/10983460534/job/30492852826

@cmb69
Copy link
Member Author

cmb69 commented Sep 22, 2024

I might be missing something, but #15988 was tagged as an ABI break and it only changed ext/phar/phar.c - is that meant to be considered an ABI break?

Nope, see #15988 (comment).

@iluuu1994, I have no idea what's going on there, PR #15975 was also not supposed to be labeled (although it makes sense; an omission that should be fixed). It seems that PRs targeting master are correctly handled (or not handled at all), but PRs targeting lower branches get the "ABI break" label.

@iluuu1994
Copy link
Member

@cmb69 In that case, you could try to add a actions/checkout step to avoid pulling the labels file from the master branch. Other than that, I don't have any ideas.

@cmb69
Copy link
Member Author

cmb69 commented Sep 23, 2024

In that case, you could try to add a actions/checkout step to avoid pulling the labels file from the master branch.

Ah, right, that should be done anyway, since the list of published headers is different for each branch. However, this shouldn't matter for the PRs where the labeler went wrong.

I wonder whether the problem is because were still using v4, but v5 only on master.

@cmb69
Copy link
Member Author

cmb69 commented Sep 23, 2024

I wonder whether the problem is because were still using v4, but v5 only on master.

Yep. I've just went with the syntax for master, but that is not compatible with v4. Not sure if should update the older branches to v5, or adapt the syntax to v4.

@cmb69
Copy link
Member Author

cmb69 commented Sep 23, 2024

Went with 89b5cc3 and 2e5f748 for now.

@cmb69
Copy link
Member Author

cmb69 commented Sep 23, 2024

Small sanity check successful: PR #16008. \o/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants