blob: ed444a831f8fcc05401b8ad7023d3b973d80b47b [file]
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
name: Build and Test
on:
workflow_call:
inputs:
java:
required: false
type: string
default: 17
branch:
required: false
type: string
description: Branch to run the build against
default: trunk
os:
required: false
type: string
description: Operating system to run the build on
default: ubuntu_24
jobs:
required: false
type: string
description: >-
Jobs to run, and should be in JSON Array format.
Candidates: "build-only", "build-and-test".
default: '[ "build-and-test" ]'
# Default to minimal permissions for workflow.
permissions:
packages: read
concurrency:
group: >-
build-and-test
${{ github.workflow }}
${{ github.repository == 'apache/hadoop' && github.run_id || github.ref }}
${{ inputs.java }}
${{ inputs.branch }}
${{ inputs.os }}
${{ inputs.jobs }}
cancel-in-progress: true
env:
MAVEN_ARGS:
--batch-mode
--no-transfer-progress
-Pyarn-ui
-Pnative
-Drequire.test.libhadoop
-Drequire.fuse
-Drequire.openssl
-Drequire.snappy
-Drequire.valgrind
-Dmaven.test.failure.ignore=false
-Dsurefire.rerunFailingTestsCount=2
jobs:
# TODO: use common composite actions in .github/actions/
precondition:
name: Preparation
runs-on: ubuntu-24.04
outputs:
build_image_url: ${{ steps.variables.outputs.build_image_url }}
steps:
- name: Set up Outputs
id: variables
# Security: passing inputs.{os, branch} through workflow (above) inputs removes
# ability to do shell injection below.
# See: https://securitylab.github.com/resources/github-actions-untrusted-input/
run: |
# Convert to lowercase to meet Docker repo name requirement
REPO_OWNER=$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]')
echo "build_image_url=ghcr.io/${REPO_OWNER}/gha-build-${{ inputs.os }}:${{ inputs.branch }}-${{ github.run_id }}" >> $GITHUB_OUTPUT
build-image:
name: Build Image ${{ inputs.os }}-${{ inputs.branch }}
runs-on: ubuntu-24.04
needs: [ precondition ]
# Security: this does not leak write access for our image repository to
# forked repos.
#
# We have `packages: write` permissions for our GITHUB_TOKEN below. However:
#
# - For `pull_request`, GitHub downgrades GITHUB_TOKEN permissions to
# read-only.
# - For `push` triggers on a fork, the GITHUB_TOKEN retains write
# permissions, but the `push` is happening in the context of the fork, not
# the upstream repo.
# - `pull_request_target` events (not used here) use the base repo's
# default branch. This prevents an attacker from adding code in a pull
# request which prints / leaks secrets, etc.. Also the GITHUB_TOKEN we
# use to grant access to writing to the image repo. is scoped to the
# repository it runs on. Even if a fork were to gain access to a
# GITHUB_TOKEN with write privileges, it doesn't grant access for other
# repositories to write.
permissions:
packages: write
outputs:
uid: ${{ steps.variables.outputs.uid }}
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Login to GitHub Container Registry
uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0 # v4.4.0
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0
- name: Build and push ${{ inputs.os }} base build image for ${{ inputs.branch }}
id: docker_build_base
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
with:
context: ./dev-support/docker/
file: ./dev-support/docker/Dockerfile_${{ inputs.os }}
push: true
tags: ${{ needs.precondition.outputs.build_image_url }}-base
cache-from: type=registry,ref=ghcr.io/apache/hadoop/gha-build-${{ inputs.os }}-image-cache:${{ inputs.branch }}
- name: User-specific Dockerfile
run: |
USER_ID=$(id -u "${USER}")
GROUP_ID=$(id -g "${USER}")
cat > /tmp/Dockerfile.gha <<UserSpecificDocker
FROM ${{ needs.precondition.outputs.build_image_url }}-base
RUN rm -f /var/log/faillog /var/log/lastlog
RUN groupadd --non-unique -g ${GROUP_ID} ${USER}
RUN useradd -g ${GROUP_ID} -u ${USER_ID} -k /root -m ${USER}
RUN echo "${USER} ALL=NOPASSWD: ALL" > "/etc/sudoers.d/hadoop-build-${USER_ID}"
UserSpecificDocker
- name: Build and push ${{ inputs.os }} build image for ${{ inputs.branch }}
id: docker_build_gha
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
with:
context: ./dev-support/docker/
file: /tmp/Dockerfile.gha
push: true
tags: ${{ needs.precondition.outputs.build_image_url }}
- name: Set up Outputs
id: variables
run: |
echo "uid=$(id -u "${USER}")" >> $GITHUB_OUTPUT
build-only:
name: Build Only (Java ${{ inputs.java }}) ${{ inputs.os }}-${{ inputs.branch }}
if: (!cancelled()) && contains(fromJSON(inputs.jobs), 'build-only')
runs-on: ubuntu-24.04
needs: [ precondition, build-image ]
container:
image: ${{ needs.precondition.outputs.build_image_url }}
options: --user ${{ needs.build-image.outputs.uid }}
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Setup JDK ${{ inputs.java }}
uses: actions/setup-java@v5
with:
distribution: zulu
java-version: ${{ inputs.java }}
cache: 'maven'
check-latest: false
- name: Build
shell: bash
run: ./mvnw $MAVEN_ARGS clean install -DskipTests
build-and-test:
if: (!cancelled()) && contains(fromJSON(inputs.jobs), 'build-and-test')
name: Test ${{ matrix.comment }} (Java ${{ inputs.java }}) ${{ inputs.os }}-${{ inputs.branch }}
runs-on: ubuntu-24.04
needs: [ precondition, build-image ]
container:
image: ${{ needs.precondition.outputs.build_image_url }}
options: --user ${{ needs.build-image.outputs.uid }}
strategy:
fail-fast: false
max-parallel: 8
matrix:
include:
- comment: hdfs - slow
modules:
-pl :hadoop-hdfs
-Dgroups=slow
- comment: hdfs - other
modules:
-pl :hadoop-hdfs
-DexcludedGroups=slow
- comment: yarn-server-rm
modules:
-pl :hadoop-yarn-server-resourcemanager
- comment: mr
modules:
-pl :hadoop-mapreduce-client-core
-pl :hadoop-mapreduce-client-common
-pl :hadoop-mapreduce-client-shuffle
-pl :hadoop-mapreduce-client-jobclient
-pl :hadoop-mapreduce-client-app
-pl :hadoop-mapreduce-client-hs
-pl :hadoop-mapreduce-client-hs-plugins
-pl :hadoop-mapreduce-client-nativetask
-pl :hadoop-mapreduce-client-uploader
-pl :hadoop-mapreduce-examples
- comment: common
modules:
-pl :hadoop-common
-pl :hadoop-yarn-server-nodemanager
-pl :hadoop-yarn-client
-pl :hadoop-distcp
- comment: hdfs-rbf
modules:
-pl :hadoop-hdfs-rbf
-pl :hadoop-yarn-applications-distributedshell
-pl :hadoop-yarn-services-core
- comment: other
modules:
-pl :hadoop-minikdc
-pl :hadoop-auth
-pl :hadoop-auth-examples
-pl :hadoop-nfs
-pl :hadoop-kms
-pl :hadoop-registry
-pl :hadoop-hdfs-client
-pl :hadoop-hdfs-native-client
-pl :hadoop-hdfs-httpfs
-pl :hadoop-hdfs-nfs
-pl :hadoop-yarn-api
-pl :hadoop-yarn-common
-pl :hadoop-yarn-server-common
-pl :hadoop-yarn-server-applicationhistoryservice
-pl :hadoop-yarn-server-timelineservice
-pl :hadoop-yarn-server-web-proxy
-pl :hadoop-yarn-server-tests
-pl :hadoop-yarn-server-sharedcachemanager
-pl :hadoop-yarn-server-timeline-pluginstorage
-pl :hadoop-yarn-server-timelineservice-hbase-common
-pl :hadoop-yarn-server-timelineservice-hbase-client
-pl :hadoop-yarn-server-timelineservice-hbase-server-2
-pl :hadoop-yarn-server-timelineservice-hbase-tests
-pl :hadoop-yarn-server-router
-pl :hadoop-yarn-server-timelineservice-documentstore
-pl :hadoop-yarn-server-globalpolicygenerator
-pl :hadoop-yarn-applications-unmanaged-am-launcher
-pl :hadoop-yarn-services-api
-pl :hadoop-yarn-registry
-pl org.apache.hadoop.applications.mawo:hadoop-yarn-applications-mawo-core
-pl :hadoop-yarn-csi
-pl :hadoop-minicluster
-pl :hadoop-federation-balance
-pl :hadoop-streaming
-pl :hadoop-client
-pl :hadoop-dynamometer-workload
-pl :hadoop-dynamometer-infra
-pl :hadoop-dynamometer-blockgen
-pl :hadoop-dynamometer-dist
-pl :hadoop-archives
-pl :hadoop-archive-logs
-pl :hadoop-rumen
-pl :hadoop-gridmix
-pl :hadoop-datajoin
-pl :hadoop-extras
-pl :hadoop-aws
-pl :hadoop-kafka
-pl :hadoop-aliyun
-pl :hadoop-sls
-pl :hadoop-resourceestimator
-pl :hadoop-azure
-pl :hadoop-azure-datalake
-pl :hadoop-fs2img
-pl :hadoop-tools-dist
-pl :hadoop-benchmark
-pl :hadoop-compat-bench
-pl :hadoop-client-api
-pl :hadoop-client-runtime
-pl :hadoop-client-minicluster
-pl :hadoop-client-integration-tests
-pl :hadoop-cos
-pl :hadoop-tos
-pl :hadoop-huaweicloud
-pl :hadoop-cloud-storage
-pl :hadoop-dist
# skipped modules
# -pl :hadoop-yarn-applications-catalog-webapp
steps:
- name: Checkout Hadoop repository
uses: actions/checkout@v6
# In order to fetch changed files
with:
fetch-depth: 0
- name: Setup JDK ${{ inputs.java }}
uses: actions/setup-java@v5
with:
distribution: zulu
java-version: ${{ inputs.java }}
cache: 'maven'
check-latest: false
- name: Build (Java ${{ inputs.java }}) ${{ inputs.os }}-${{ inputs.branch }}
shell: bash
run: ./mvnw $MAVEN_ARGS ${{ matrix.modules }} clean install -am -DskipTests
- name: Test (Java ${{ inputs.java }}) ${{ inputs.os }}-${{ inputs.branch }}
shell: bash
run: ./mvnw $MAVEN_ARGS ${{ matrix.modules }} test -Dsurefire.excludesFile=$PWD/.github/gha-tests/exclude-tests.txt
- name: Upload test logs
if: failure()
uses: actions/upload-artifact@v7
with:
name: unit-test-logs-${{ matrix.comment }}-java${{ inputs.java }})-${{ inputs.os }}-${{ inputs.branch }}
path: |
**/target/*.log
**/target/*.xml