Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions .buildkite/scripts/build_pr.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
set -euo pipefail
set +x

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
DOCS_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"

# This script should only be invoked by the Buildkite PR bot
if [ -z ${GITHUB_PR_TARGET_BRANCH+set} ] || [ -z ${GITHUB_PR_NUMBER+set} ] || [ -z ${GITHUB_PR_BASE_REPO+set} ];then
echo "One of the following env. variable GITHUB_PR_TARGET_BRANCH, GITHUB_PR_NUMBER, GITHUB_PR_BASE_REPO is missing - exiting."
Expand Down Expand Up @@ -54,7 +57,7 @@ if [[ "${GITHUB_PR_BASE_REPO}" != 'docs' ]]; then
# 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") \
if legacy_branches=$(perl "${SCRIPT_DIR}/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
Expand Down Expand Up @@ -218,9 +221,19 @@ if [[ "${GITHUB_PR_BASE_REPO}" != 'docs' ]]; then
docs_diff=$(git diff --stat "origin/$GITHUB_PR_TARGET_BRANCH"...HEAD -- ./docs/en ./docs/kr ./docs/jp)
;;

# All other repos will always build
# Repos without a specialized arm: derive doc paths from conf.yaml
*)
docs_diff="always build"
git fetch origin "$GITHUB_PR_TARGET_BRANCH"
if docs_paths=$(perl "${SCRIPT_DIR}/docs_paths.pl" "$GITHUB_PR_BASE_REPO" "${DOCS_ROOT}/conf.yaml" 2>/dev/null); then
if [[ -z "$docs_paths" ]]; then
docs_diff=""
else
mapfile -t paths <<< "$docs_paths"
docs_diff=$(git diff --stat "origin/$GITHUB_PR_TARGET_BRANCH"...HEAD -- "${paths[@]}")
fi
else
docs_diff="always build"
fi
;;
esac

Expand Down
76 changes: 76 additions & 0 deletions .buildkite/scripts/docs_paths.pl
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#!/usr/bin/env perl
use strict;
use warnings;
use YAML qw(LoadFile);

# Usage: docs_paths.pl <github-repo-name> [conf.yaml]
# Prints one git-diff path per line from conf.yaml sources for the repo.
#
# Exit 0: conf.yaml was read successfully. Output is empty if the repo is not
# in conf.yaml or has no source paths.
# 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, $conf_path ) = @ARGV;
$conf_path //= 'conf.yaml';

die "Usage: $0 <github-repo-name> [conf.yaml]\n" unless defined $github_repo;

my $conf = eval { LoadFile($conf_path) };
if ($@) {
warn "Failed to load $conf_path: $@\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 doc paths, caller should skip
}

my %paths;
walk_entries( $conf->{contents}, $conf_key, \%paths );

print "$_\n" for sort keys %paths;
exit 0;


sub walk_entries {
my ( $entries, $conf_key, $paths ) = @_;
for my $entry (@$entries) {
if ( $entry->{sections} ) {
walk_entries( $entry->{sections}, $conf_key, $paths );
} else {
collect_source_paths( $entry, $conf_key, $paths );
}
}
}

sub collect_source_paths {
my ( $book, $conf_key, $paths ) = @_;
for my $source ( @{ $book->{sources} // [] } ) {
next unless ( $source->{repo} // '' ) eq $conf_key;
my $path = normalize_path( $source->{path} );
$paths->{$path} = 1 if defined $path && length $path;
}
}

sub normalize_path {
my ($path) = @_;
return unless defined $path;
$path =~ s{^/}{}; # strip leading slash for git diff
return $path;
}
39 changes: 39 additions & 0 deletions .buildkite/scripts/docs_paths.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/usr/bin/env perl
use strict;
use warnings;
use Test::More;
use FindBin qw($RealBin);

# Regression check for docs_paths.pl's repo-name resolution and path collection.
# Run from the repo root since docs_paths.pl defaults to ./conf.yaml.

chdir "$RealBin/../.." or die "Can't chdir to repo root: $!";

my $conf = 'conf.yaml';

sub run {
my ($repo) = @_;
my $out = `perl .buildkite/scripts/docs_paths.pl @{[quotemeta $repo]} $conf 2>/dev/null`;
return ( $? >> 8, $out );
}

{
my ( $exit, $out ) = run('kibana');
is( $exit, 0, 'kibana: exits 0' );
like( $out, qr{docs/}, 'kibana: includes docs/' );
like( $out, qr{:\(glob\).*asciidoc}, 'kibana: includes a glob asciidoc pathspec' );
}

{
my ( $exit, $out ) = run('elastic-serverless-forwarder');
is( $exit, 0, 'elastic-serverless-forwarder: exits 0' );
like( $out, qr{docs/en}, 'elastic-serverless-forwarder: resolves via URL basename to docs/en' );
}

{
my ( $exit, $out ) = run('some-repo-not-in-conf-yaml');
is( $exit, 0, 'unknown repo: exits 0' );
is( $out, '', 'unknown repo: no doc paths' );
}

done_testing();
8 changes: 8 additions & 0 deletions .buildkite/scripts/legacy_branches.t
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ for my $repo (qw(kibana-cn swiftype esf elastic-serverless-forwarder)) {
isnt( $out, '', "$repo: has at least one legacy branch (conf key resolved)" );
}

{
my ( $exit, $out ) = run('kibana');
is( $exit, 0, 'kibana: exits 0' );
isnt( $out, '', 'kibana: has at least one legacy branch' );
like( $out, qr{^8\.19$}m, 'kibana: includes 8.19 legacy branch' );
unlike( $out, qr{^9\.}m, 'kibana: has no 9.x legacy branches' );
}

my ( $exit, $out ) = run('some-repo-not-in-conf-yaml');
is( $exit, 0, 'unknown repo: exits 0' );
is( $out, '', 'unknown repo: no legacy branches' );
Expand Down
Loading