diff --git a/.buildkite/scripts/build_pr.sh b/.buildkite/scripts/build_pr.sh index 506a5a6d0ee11..50781309a672d 100755 --- a/.buildkite/scripts/build_pr.sh +++ b/.buildkite/scripts/build_pr.sh @@ -41,6 +41,25 @@ buildkite-agent \ if [[ "${GITHUB_PR_BASE_REPO}" != 'docs' ]]; then + # main/master are hardcoded to always skip the build, without needing conf.yaml/YAML at all: + # we no longer build legacy AsciiDoc docs against these branches. + if [[ "${GITHUB_PR_TARGET_BRANCH}" == "main" || "${GITHUB_PR_TARGET_BRANCH}" == "master" ]]; then + echo "Target branch '${GITHUB_PR_TARGET_BRANCH}' is main/master — skipping build (reporting success)." + exit 0 + fi + + # Build only if conf.yaml lists the target branch as a legacy AsciiDoc branch + # for this repo — otherwise skip but report success, since docs-build-pr is a + # required check and we want it green rather than failing or left pending. + # The helper exits non-zero only when conf.yaml itself couldn't be read (e.g. + # the perl YAML module is missing), which short-circuits the condition below + # so we fail open and build as today, rather than silently going green. + if legacy_branches=$(perl "$(dirname "$0")/legacy_branches.pl" "$GITHUB_PR_BASE_REPO") \ + && ! grep -qxF "${GITHUB_PR_TARGET_BRANCH}" <<< "${legacy_branches}"; then + echo "Target branch '${GITHUB_PR_TARGET_BRANCH}' is not a legacy AsciiDoc branch in conf.yaml for ${GITHUB_PR_BASE_REPO} — skipping build (reporting success)." + exit 0 + fi + # Buildkite PR bot for repositories other than the `elastic/docs` repo are configured to # always checkout the master branch of the `elastic/docs` repo (where the build logic resides). # We first need to checkout the product repo / branch in a sub directory, that we'll reference diff --git a/.buildkite/scripts/legacy_branches.pl b/.buildkite/scripts/legacy_branches.pl new file mode 100755 index 0000000000000..e89723462f223 --- /dev/null +++ b/.buildkite/scripts/legacy_branches.pl @@ -0,0 +1,88 @@ +#!/usr/bin/env perl +use strict; +use warnings; +use YAML qw(LoadFile); + +# Usage: legacy_branches.pl +# Prints one legacy (AsciiDoc) branch per line that the given repo still carries in conf.yaml. +# +# Exit 0: conf.yaml was read successfully. The list is empty if the repo is +# fully migrated to docs-builder or isn't in conf.yaml at all — either +# way it has no legacy branches, so the caller should skip the build. +# Exit 1: conf.yaml couldn't be loaded (e.g. missing YAML module, parse error) +# — caller should build as today (fail open), since we can't tell. + +my ($github_repo) = @ARGV + or die "Usage: $0 \n"; + +# conf.yaml lives in the repo root, which is also the working directory when +# build_pr.sh runs — same assumption used by build_docs.pl (see build_docs.pl:964). +my $conf = eval { LoadFile('conf.yaml') }; +if ($@) { + warn "Failed to load conf.yaml: $@\n"; + exit 1; +} + +# Sources in conf.yaml reference the conf key (e.g. "esf"), which for most repos +# is already the GitHub repo name but for some (e.g. "elastic-serverless-forwarder") +# differs from it. Try the GitHub name as a conf key directly first, then fall back +# to matching it against each repo's URL basename. +my $conf_key = exists $conf->{repos}{$github_repo} ? $github_repo : undef; +unless ( defined $conf_key ) { + while ( my ( $key, $url ) = each %{ $conf->{repos} } ) { + ( my $name = $url ) =~ s{.*/|\.git$}{}g; # URL -> repo name (strip path and .git) + if ( $name eq $github_repo ) { + $conf_key = $key; + last; + } + } +} + +unless ( defined $conf_key ) { + exit 0; # repo not in conf — no legacy branches, caller should skip +} + +# Walk conf.yaml contents and collect every git branch for which this repo still +# appears as a source, using the same branch-resolution rules as the build itself +# (ES::Book:104-109 + ES::BranchTracker:63): +# - git branch = LHS of each branches entry (scalar or single-key hash) +# - map_branches{book_branch} applied to get the actual git branch in the source repo +# - branches in exclude_branches skipped +my %branches; +walk_entries( $conf->{contents}, $conf_key, \%branches ); + +print "$_\n" for sort keys %branches; +exit 0; + + +sub walk_entries { + my ( $entries, $conf_key, $branches ) = @_; + for my $entry (@$entries) { + if ( $entry->{sections} ) { + walk_entries( $entry->{sections}, $conf_key, $branches ); + } else { + collect_book_branches( $entry, $conf_key, $branches ); + } + } +} + +sub collect_book_branches { + my ( $book, $conf_key, $branches ) = @_; + my $branch_list = $book->{branches} or return; + my $sources = $book->{sources} or return; + + my @matching = grep { ( $_->{repo} // '' ) eq $conf_key } @$sources; + return unless @matching; + + for my $source (@matching) { + my $map = $source->{map_branches} // {}; + my %excl = map { $_ => 1 } @{ $source->{exclude_branches} // [] }; + + for my $entry (@$branch_list) { + # Each entry is a scalar or a single-key hash { book_branch => display_title } + my ($branch) = ref $entry eq 'HASH' ? keys %$entry : ($entry); + next if $excl{$branch}; + $branches->{ $map->{$branch} // $branch } = 1; + } + } +} diff --git a/.buildkite/scripts/legacy_branches.t b/.buildkite/scripts/legacy_branches.t new file mode 100755 index 0000000000000..8905f5faa7742 --- /dev/null +++ b/.buildkite/scripts/legacy_branches.t @@ -0,0 +1,31 @@ +#!/usr/bin/env perl +use strict; +use warnings; +use Test::More; +use FindBin qw($RealBin); + +# Regression check for legacy_branches.pl's repo-name resolution: it must +# handle both a GitHub repo name that already matches a conf.yaml key +# directly (e.g. "esf" itself) and one that only matches via a source repo's +# URL basename (e.g. "elastic-serverless-forwarder" -> "esf"). Run from the +# repo root since legacy_branches.pl reads ./conf.yaml relative to cwd. + +chdir "$RealBin/../.." or die "Can't chdir to repo root: $!"; + +sub run { + my ($repo) = @_; + my $out = `perl .buildkite/scripts/legacy_branches.pl @{[quotemeta $repo]} 2>/dev/null`; + return ( $? >> 8, $out ); +} + +for my $repo (qw(kibana-cn swiftype esf elastic-serverless-forwarder)) { + my ( $exit, $out ) = run($repo); + is( $exit, 0, "$repo: exits 0" ); + isnt( $out, '', "$repo: has at least one legacy branch (conf key resolved)" ); +} + +my ( $exit, $out ) = run('some-repo-not-in-conf-yaml'); +is( $exit, 0, 'unknown repo: exits 0' ); +is( $out, '', 'unknown repo: no legacy branches' ); + +done_testing();