Skip to content

Commit cbbc9f6

Browse files
authored
Merge branch 'erlang:master' into data_publisher
2 parents af93a98 + 9b9cb00 commit cbbc9f6

1,114 files changed

Lines changed: 14991 additions & 8187 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/scripts/build-macos.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
##
2121
## %CopyrightEnd%
2222

23+
set -e
24+
2325
export MAKEFLAGS="-j$(getconf _NPROCESSORS_ONLN)"
2426
export ERL_TOP="$(pwd)"
2527
export ERLC_USE_SERVER=true

.github/scripts/create-openvex-pr.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
##
55
## SPDX-License-Identifier: Apache-2.0
66
##
7-
## Copyright Ericsson AB 2026. All Rights Reserved.
7+
## Copyright Ericsson AB 2026-2025. All Rights Reserved.
88
##
99
## Licensed under the Apache License, Version 2.0 (the "License");
1010
## you may not use this file except in compliance with the License.

.github/scripts/ort-scanner.es

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -186,14 +186,15 @@ sha1sums(GitRepo) ->
186186
%% Check which files on disk do not have the same sha1 as the files in the original scan
187187
FilesToRestore = check_files_to_restore(Input, Cache),
188188

189+
%% Restores from cache only the files with identical SHA1
189190
ScanResults = restore_from_cache(FilesToRestore,
190191
InputProvenance,
191192
Cache),
193+
ScannersName = [maps:get(~"name", maps:get(~"scanner", R)) || R <- ScanResults],
192194

193195
InputScanner = maps:get(~"scanner", Input),
194196
InputScanners = maps:get(~"scanners", InputScanner),
195-
Scanners = [maps:get(~"name", maps:get(~"scanner", R)) || R <- ScanResults],
196-
NewScanners = #{ K => Scanners || K := _ <- InputScanners},
197+
NewScanners = #{ K => ScannersName || K := _ <- InputScanners},
197198

198199
CacheConfig = maps:get(~"config", maps:get(~"scanner", Cache)),
199200

@@ -428,8 +429,51 @@ replace_mappings(SPDX, Map) ->
428429
%% other side of NOASSERTION.
429430
replace_mappings(SPDX, maps:to_list(Map) ++ [{"AND NOASSERTION",""},{"NOASSERTION AND",""}]).
430431

432+
%% deduplicates scan results as per oss-review-toolkit scan-result.json format
431433
deduplicate(ScanResults) ->
432-
deduplicate(ScanResults, []).
434+
UniqueScanResults = deduplicate(ScanResults, []),
435+
436+
%% some results have the exact same provenance and cater to different
437+
%% files, so we merge those scan results. this is needed because ORT
438+
%% cannot distinguish which of two scan results is the valid one,
439+
%% given that they have the same provenance and scanning options.
440+
merge_identical_scan_results(UniqueScanResults).
441+
442+
%% merges scan results whose provenance and scanner configuration options
443+
%% (and scanner versions) are identical. from `deduplicate/2` we are
444+
%% guaranteed to get scan results with different scanned files
445+
merge_identical_scan_results(ScanResults) ->
446+
Result = lists:foldl(
447+
fun (#{~"provenance" := Provenance,
448+
~"scanner" := Scanner,
449+
~"summary" := Summary}, Acc) ->
450+
case maps:get({Provenance, Scanner}, Acc, false) of
451+
false ->
452+
Acc#{{Provenance, Scanner} => Summary};
453+
SummaryAcc ->
454+
%% merge results where provenance and scanning options
455+
%% are identical. otherwise ORT (oss-review-toolkit) cannot
456+
%% know which one to choose from two identical configurations.
457+
OldCp = maps:get(~"copyrights", SummaryAcc),
458+
NewCp = maps:get(~"copyrights", Summary),
459+
460+
OldLs = maps:get(~"licenses", SummaryAcc),
461+
NewLs = maps:get(~"licenses", Summary),
462+
463+
Acc#{{Provenance, Scanner} :=
464+
Summary#{~"copyrights" := OldCp ++ NewCp,
465+
~"licenses" := OldLs ++ NewLs}}
466+
end
467+
end, #{}, ScanResults),
468+
maps:fold(fun ({Provenance, Scanner}, V, Acc) ->
469+
[#{~"summary" => V,
470+
~"provenance" => Provenance,
471+
~"scanner" => Scanner} | Acc]
472+
end, [], Result).
473+
474+
475+
%% deduplicates licenses if already found in other scanners.
476+
%% output: scanners have unique files in their copyrights and licenses
433477
deduplicate([H | T], Found) ->
434478
#{ ~"summary" := #{ ~"copyrights" := CS, ~"licenses" := LS} = Summary} = H,
435479
FilteredCS = [C || C = #{ ~"location" := #{ ~"path" := Path }} <- CS,

.github/scripts/otp-compliance.es

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@
8383
-define(spdx_download_location, ~"https://github.com/erlang/otp/releases").
8484
-define(spdx_homepage, ~"https://www.erlang.org").
8585
-define(spdx_purl_meta_data, ~"?vcs_url=git+https://github.com/erlang/otp.git").
86-
-define(spdx_version, ~"SPDX-2.2").
86+
-define(spdx_version, ~"SPDX-2.3").
8787
-define(otp_version, 'OTP_VERSION'). % file name of the OTP version
8888
-define(spdx_project_purl, #{ ~"comment" => ~"",
8989
~"referenceCategory" => ~"PACKAGE-MANAGER",
@@ -551,7 +551,8 @@ sbom_fixing_functions(ScanResults) ->
551551
{fun fix_project_package_version/2, 'OTP_VERSION'},
552552
{fun fix_has_extracted_license_info/2, extracted_license_info()},
553553
{fun fix_project_purl/2, ?spdx_project_purl},
554-
{fun fix_beam_licenses/2, {Licenses, Copyrights}} ].
554+
{fun fix_beam_licenses/2, {Licenses, Copyrights}}
555+
].
555556

556557
fix_project_name(ProjectName, #{ ~"documentDescribes" := [ ProjectName0 ],
557558
~"packages" := Packages}=Sbom) ->
@@ -1172,7 +1173,7 @@ create_spdx_package(Pkg) ->
11721173
Supplier = Pkg#spdx_package.'supplier',
11731174
Purl1 = case Pkg#spdx_package.'purl' of
11741175
false -> [];
1175-
_ -> [Pkg#spdx_package.'purl']
1176+
_ -> Pkg#spdx_package.'purl'
11761177
end,
11771178
#{ ~"SPDXID" => SPDXID,
11781179
~"versionInfo" => VersionInfo,
@@ -1888,7 +1889,8 @@ create_spdx_package_record(PackageName, Vsn, Description, SpdxPackageFiles,
18881889
VerificationCodeValue = generate_verification_code_value(SpdxPackageFiles),
18891890
Purl1 = case Purl of
18901891
false -> false;
1891-
true -> create_externalRef_purl(Description, otp_purl(PackageName, Vsn))
1892+
true -> [create_externalRef_purl(Description, otp_purl(PackageName, Vsn)),
1893+
fix_openvex_reference()]
18921894
end,
18931895
#spdx_package {
18941896
'SPDXID' = SpdxPackageName,
@@ -1911,6 +1913,19 @@ create_spdx_package_record(PackageName, Vsn, Description, SpdxPackageFiles,
19111913
}.
19121914

19131915

1916+
fix_openvex_reference() ->
1917+
OTPMajorVersion = hd(string:split(get_otp_version(), ".")),
1918+
Reference = openvex_iri(OTPMajorVersion),
1919+
#{
1920+
~"referenceCategory" => ~"SECURITY",
1921+
~"referenceLocator" => Reference,
1922+
~"referenceType" => ~"advisory"
1923+
}.
1924+
1925+
%% Branch = ~"28" or similar. just the current version number.
1926+
openvex_iri(Branch) when is_binary(Branch) ->
1927+
<<"https://erlang.org/download/vex/otp-", Branch/binary, ".openvex.json">>.
1928+
19141929
otp_app_license_mapping(Name) ->
19151930
case Name of
19161931
~"edoc" -> ~"Apache-2.0 OR LGPL-2.1-or-later";
@@ -2375,16 +2390,23 @@ test_project_purl(#{~"documentDescribes" := [ProjectName], ~"packages" := Packag
23752390
ok.
23762391

23772392
test_packages_purl(#{~"documentDescribes" := [ProjectName], ~"packages" := Packages}=_Sbom) ->
2378-
OTPPackages = lists:filter(fun (#{~"SPDXID" := Id, ~"name" := Name}) -> ProjectName =/= Id andalso lists:member(Name, minimum_otp_apps()) end, Packages),
2379-
true = lists:all(fun (#{~"name" := Name, ~"versionInfo" := Version, ~"externalRefs" := [#{~"referenceLocator":= RefLoc}=Ref]}) ->
2393+
OTPPackages = lists:filter(fun (#{~"SPDXID" := Id, ~"name" := Name}) ->
2394+
ProjectName =/= Id andalso lists:member(Name, minimum_otp_apps())
2395+
end, Packages),
2396+
true = lists:all(fun (#{~"name" := Name, ~"versionInfo" := Version,
2397+
~"externalRefs" := [#{~"referenceLocator":= RefLoc}=Ref,
2398+
OpenVex]}) ->
23802399
ExternalRef = create_externalRef_purl(~"", otp_purl(Name, Version)),
23812400
ExternalRef1 = maps:remove(~"comment", ExternalRef),
23822401
Ref1 = maps:remove(~"comment", Ref),
23832402

2403+
ExpectedVEX = fix_openvex_reference(),
2404+
23842405
%% check expected external ref
23852406
ExternalRef1 =:= Ref1 andalso
23862407
%% check metadata is included in purl
2387-
nomatch =/= string:find(RefLoc, ?spdx_purl_meta_data)
2408+
nomatch =/= string:find(RefLoc, ?spdx_purl_meta_data) andalso
2409+
ExpectedVEX == OpenVex
23882410
end, OTPPackages),
23892411
ok.
23902412

@@ -3202,12 +3224,13 @@ fetch_app_from_table(OTPVersion, App0) ->
32023224
convert_range(Version) ->
32033225
string:split(Version, ".", all).
32043226

3205-
3227+
%% Branch = "otp-28"
32063228
init_openvex_file(Branch) ->
32073229
Ts = calendar:system_time_to_rfc3339(erlang:system_time(microsecond), [{unit, microsecond}]),
3230+
[~"otp", Version] = string:split(Branch, ~"-"),
32083231
#{
32093232
~"@context" => ~"https://openvex.dev/ns/v0.2.0",
3210-
~"@id" => <<"https://openvex.dev/docs/public/otp/vex-", Branch/binary>>,
3233+
~"@id" => openvex_iri(Version),
32113234
~"author" => ~"vexctl",
32123235
~"timestamp" => erlang:list_to_binary(Ts),
32133236
~"version" => 1,

.github/workflows/main.yaml

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,37 @@ permissions:
5959

6060
jobs:
6161

62+
check-beam:
63+
name: Forbid non-maintainers from committing BEAM files
64+
runs-on: ubuntu-latest
65+
if: github.repository == 'erlang/otp' && github.event_name == 'pull_request'
66+
steps:
67+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # ratchet:actions/checkout@v4.2.2
68+
with:
69+
fetch-depth: 0
70+
71+
- name: Detect modified BEAM files
72+
env:
73+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
74+
PR_AUTHOR: ${{ github.event.pull_request.user.login }}
75+
run: |
76+
PERMISSION=$(gh api \
77+
-H "Accept: application/vnd.github+json" \
78+
-H "X-GitHub-Api-Version: 2022-11-28" \
79+
/repos/{owner}/{repo}/collaborators/$PR_AUTHOR/permission --jq '.role_name')
80+
81+
MODIFIED_BEAM_FILES=$(git diff --name-only ${{github.event.pull_request.base.sha}} \
82+
${{ github.event.pull_request.head.sha }} | grep '\.beam$' || true)
83+
if [[ "$PERMISSION" != "admin" && "$PERMISSION" != "maintain" && "$PERMISSION" != "Security Master" && -n "$MODIFIED_BEAM_FILES" ]]; then
84+
echo "::error::Workflow failed: Only maintainers can make modifications to '*.beam' files:"
85+
echo "$MODIFIED_BEAM_FILES"
86+
exit 1
87+
fi
88+
6289
pack:
6390
name: Build Erlang/OTP (64-bit)
6491
runs-on: ubuntu-latest
92+
needs: check-beam
6593
if: github.repository == 'erlang/otp' || github.event_name != 'scheduled'
6694
outputs:
6795
changes: ${{ steps.changes.outputs.changes }}
@@ -194,7 +222,7 @@ jobs:
194222
needs: pack
195223
if: needs.pack.outputs.build-c-code == 'true'
196224
env:
197-
WXWIDGETS_VERSION: 3.2.8.1
225+
WXWIDGETS_VERSION: 3.2.9
198226
MACOS_VERSION: 15
199227
steps:
200228
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # ratchet:actions/checkout@v4.2.2
@@ -206,7 +234,7 @@ jobs:
206234

207235
- name: Cache wxWidgets
208236
id: wxwidgets-cache
209-
uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
237+
uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # ratchet:actions/cache@v4.2.4
210238
with:
211239
path: wxWidgets
212240
key: wxWidgets-${{ env.WXWIDGETS_VERSION }}-${{ runner.os }}-${{ hashFiles('.github/scripts/build-macos-wxwidgets.sh') }}-${{ env.MACOS_VERSION }}
@@ -279,7 +307,7 @@ jobs:
279307
env:
280308
WXWIDGETS_VERSION: 3.2.6
281309
name: Build Erlang/OTP (Windows)
282-
runs-on: windows-2022
310+
runs-on: windows-2025
283311
needs: pack
284312
if: needs.pack.outputs.build-c-code == 'true'
285313
steps:
@@ -290,6 +318,11 @@ jobs:
290318
- name: Install WSL dependencies
291319
run: apt update && apt install -y make autoconf unzip
292320

321+
- name: Install NSIS
322+
shell: cmd
323+
run: |
324+
choco install nsis --version 3.11.0
325+
293326
- name: Install openssl
294327
shell: cmd
295328
run: |
@@ -349,6 +382,7 @@ jobs:
349382
cp -R wxWidgets /mnt/c/opt/local64/pgm/wxWidgets-${{ env.WXWIDGETS_VERSION }}
350383
tar -xzf ./otp_src.tar.gz
351384
cd otp
385+
export PATH="/mnt/c/Program Files (x86)/NSIS/bin":$PATH
352386
export ERL_TOP=`pwd`
353387
export MAKEFLAGS=-j$(($(nproc) + 2))
354388
export ERLC_USE_SERVER=true
@@ -796,7 +830,7 @@ jobs:
796830
runs-on: ubuntu-latest
797831
needs: pack
798832
env:
799-
ORT_VERSION: 58.0.1
833+
ORT_VERSION: 72.0.0
800834
SCAN_RESULT_CACHE_PATH: .ort/scan-result.json
801835

802836
steps:
@@ -843,6 +877,7 @@ jobs:
843877
- name: Restore ORT Scanner cache
844878
uses: actions/cache/restore@5a3ec84eff668545956fd18022155c47e93e2684 # ratchet:actions/cache/restore@v4
845879
id: ort-cache
880+
if: ${{ env.FULL_BUILD_AND_CHECK == 'false' }}
846881
with:
847882
path: ${{ env.SCAN_RESULT_CACHE_PATH }}
848883
key: ort-scan-result-${{ env.ORT_VERSION }}-${{ github.ref_name }}-${{ github.sha }}
@@ -858,7 +893,7 @@ jobs:
858893
FROM otp
859894
RUN echo 'export PATH="\$HOME/.local/bin:\$PATH"' >> /home/otptest/.profile
860895
RUN sudo apt-get install -y libicu-dev pip && \
861-
pip install click==8.1.7 scancode-toolkit==${SCANCODE_VERSION} reuse && \
896+
pip install click==8.3.1 scancode-toolkit==${SCANCODE_VERSION} reuse && \
862897
pip install -U ntia-conformance-checker
863898
EOF
864899
@@ -886,7 +921,7 @@ jobs:
886921
sw-version: ${{ env.OTP_SBOM_VERSION }}
887922

888923
- name: Overwrite scan results using reuse
889-
run: |
924+
run: |
890925
cp $HOME/.ort/ort-results/scan-result.json $HOME/.ort/ort-results/scan-result.scanned.json
891926
docker run -v $PWD/:/github -v $HOME:$HOME otp \
892927
"/github/.github/scripts/ort-scanner.es scan -t reuse -s overwrite \
@@ -1042,7 +1077,7 @@ jobs:
10421077
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # ratchet:actions/download-artifact@v4.3.0
10431078
with:
10441079
name: otp_doc_man
1045-
1080+
10461081
## We add the correct version name into the file names
10471082
## and create the hash files for all assets
10481083
- name: Create pre-build and doc archives
@@ -1056,7 +1091,7 @@ jobs:
10561091
FILES=$(ls {*.tar.gz,*.txt})
10571092
md5sum $FILES > MD5.txt
10581093
sha256sum $FILES > SHA256.txt
1059-
1094+
10601095
- name: Download SBoM
10611096
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # ratchet:actions/download-artifact@v4.3.0
10621097
with:

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,5 +349,7 @@ JAVADOC-GENERATED
349349

350350
/lib/xmerl/src/xmerl_sax_parser_*.erl
351351
/lib/xmerl/src/xmerl_b64Bin.erl
352+
/lib/xmerl/src/xmerl_xsd_re_parse.erl
352353
/lib/xmerl/src/xmerl_xpath_parse.erl
353354
/lib/xmerl/test/xmerl_test.erl
355+

.ort/config/config.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,9 @@ ort:
3636
enabledPackageManagers: [Unmanaged]
3737
# A flag to control whether excluded scopes and paths should be skipped during the analysis.
3838
skipExcluded: true
39+
40+
reporter:
41+
reporters:
42+
SpdxDocument:
43+
options:
44+
spdxVersion: "SPDX-2.3"

Makefile.in

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -994,3 +994,7 @@ APPS_TEST=$(patsubst %, %_test,$(APPS))
994994
$(NO_DIALYZER_APPS): $$(patsubst %,%_build,$$@)
995995
$(APPS_TEST): $$(patsubst %_test,%_build,$$@)
996996
ERL_TOP=$(ERL_TOP) TYPE=$(TYPE) $(MAKE) -C lib/$(patsubst %_test,%,$@) test
997+
998+
.PHONY: clean_docs
999+
clean_docs:
1000+
rm -rf $(ERL_TOP)/doc $(ERL_TOP)/make/otp_doc_built

SECURITY.md

Lines changed: 1 addition & 1 deletion

bootstrap/bin/no_dot_erlang.boot

12 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)