diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e955097a4f..9560de94f4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,6 +20,7 @@ jobs: path-filter: runs-on: ubuntu-latest if: github.repository == 'podman-container-tools/podman' + timeout-minutes: 5 outputs: all: ${{ steps.filter.outputs.all }} code: ${{ steps.filter.outputs.code }} @@ -48,6 +49,8 @@ jobs: name: Validate source code changes runs-on: cncf-ubuntu-8-32-x86 if: github.repository == 'podman-container-tools/podman' + # While in most cases it should faster than 10m, if there are many commits in the PR "Build each commit" takes a bit longer + timeout-minutes: 20 permissions: pull-requests: read # For hack/ci/pr-should-include-tests to query PR labels. env: @@ -186,6 +189,7 @@ jobs: name: Cross Build (Linux, FreeBSD) runs-on: cncf-ubuntu-16-64-x86 if: github.repository == 'podman-container-tools/podman' + timeout-minutes: 10 steps: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: @@ -433,6 +437,7 @@ jobs: needs.path-filter.outputs.machine == 'true' name: machine linux ${{ matrix.os.arch }} runs-on: ${{ matrix.os.runner }} + timeout-minutes: 40 strategy: fail-fast: false matrix: @@ -725,6 +730,7 @@ jobs: - macos-installer - macos-machine runs-on: ubuntu-latest + timeout-minutes: 5 steps: - name: Check all required jobs run: | diff --git a/hack/ci/ci_yaml_test.py b/hack/ci/ci_yaml_test.py index cec924c7df..7f655e1a52 100755 --- a/hack/ci/ci_yaml_test.py +++ b/hack/ci/ci_yaml_test.py @@ -1,20 +1,21 @@ #!/usr/bin/env python3 """ -Verify contents of .github/workflows/ci.yml meet specific expectations +Verify contents of .github/workflows/ci.yml meets some basic expectations """ import sys import os import unittest import yaml +import re # Assumes directory structure of this file relative to repo. SCRIPT_DIRPATH = os.path.dirname(os.path.realpath(__file__)) -REPO_ROOT = os.path.realpath(os.path.join(SCRIPT_DIRPATH, '../', '../')) +REPO_ROOT = os.path.realpath(os.path.join(SCRIPT_DIRPATH, '..', '..')) -class TestCaseBase(unittest.TestCase): +class TestCase(unittest.TestCase): CI_YAML = None @@ -22,21 +23,34 @@ class TestCaseBase(unittest.TestCase): with open(os.path.join(REPO_ROOT, '.github/workflows/ci.yml')) as ci_yaml: self.CI_YAML = yaml.safe_load(ci_yaml.read()) - -class TestDependsOn(TestCaseBase): - - ALL_TASK_NAMES = None - - def setUp(self): - super().setUp() - self.ALL_TASK_NAMES = list(self.CI_YAML['jobs'].keys()) - - + # Critical for the merge protection to work as we only block on this task. def test_success_deps(self): - """Specific success task depends on all others""" - all_tasks = self.ALL_TASK_NAMES.remove('success') + """success task depends on all others""" + all_tasks = list(self.CI_YAML['jobs'].keys()) + # need to remove success from the list as it cannot depend on itself + all_tasks.remove('success') needs = self.CI_YAML['jobs']['success']['needs'] - self.assertCountEqual(needs, self.ALL_TASK_NAMES) + self.assertCountEqual(needs, all_tasks) + + def test_gh_actions_are_pinned_by(self): + """ensure all actions are pinned by digest and have version comment""" + # Note local paths are allowed, i.e. uses: ./.github/workflows/lima.yml + pattern = re.compile(r"uses:\s+(?:(\./[\w./-]+)(?:\s+#.*)?|([\w.-]+/[\w./-]+)@([a-f0-9]{40})\s+#\s*(.+))$") + dir = os.path.join(REPO_ROOT, '.github/workflows') + for name in os.listdir(dir): + with open(os.path.join(dir, name)) as file: + for i, line in enumerate(file, 1): + if 'uses:' in line: + self.assertRegex(line, pattern, msg=f"Action must be pinned with a version number comment, file: .github/workflows/{name}:{i}") + + def test_job_timeout(self): + """ensure all the ci jobs have a timeout set""" + for job, item in self.CI_YAML['jobs'].items(): + # Note some jobs just start another workflow via uses, in this case no runs-on is set and no timeout can be set so skip it. + if item.get('runs-on') is not None: + timeout = item.get('timeout-minutes') + self.assertIsNotNone(timeout, msg=f"job '{job}' has no timeout-minutes set") + self.assertLessEqual(timeout, 60, msg=f"job '{job}' should never take longer than 1 hour") if __name__ == "__main__": unittest.main() diff --git a/hack/get_ci_vm.sh b/hack/get_ci_vm.sh deleted file mode 100755 index 69b29fd86f..0000000000 --- a/hack/get_ci_vm.sh +++ /dev/null @@ -1,83 +0,0 @@ -#!/usr/bin/env bash - -# -# For help and usage information, simply execute the script w/o any arguments. -# -# This script is intended to be run by Red Hat podman developers who need -# to debug problems specifically related to Cirrus-CI automated testing. -# It requires that you have been granted prior access to create VMs in -# google-cloud. For non-Red Hat contributors, VMs are available as-needed, -# with supervision upon request. - -set -e - -SCRIPT_FILEPATH=$(realpath "${BASH_SOURCE[0]}") -SCRIPT_DIRPATH=$(dirname "$SCRIPT_FILEPATH") -REPO_DIRPATH=$(realpath "$SCRIPT_DIRPATH/../") - -# Help detect what get_ci_vm container called this script -GET_CI_VM="${GET_CI_VM:-0}" -in_get_ci_vm() { - if ((GET_CI_VM == 0)); then - echo "Error: $1 is not intended for use in this context" - exit 2 - fi -} - -# get_ci_vm APIv1 container entrypoint calls into this script -# to obtain required repo. specific configuration options. -if [[ "$1" == "--config" ]]; then - in_get_ci_vm "$1" # handles GET_CI_VM==0 case - case "$GET_CI_VM" in - 1) - cat << EOF -DESTDIR="/var/tmp/go/src/github.com/containers/podman" -UPSTREAM_REPO="https://github.com/containers/podman.git" -CI_ENVFILE="/etc/ci_environment" -GCLOUD_PROJECT="libpod-218412" -GCLOUD_IMGPROJECT="libpod-218412" -GCLOUD_CFG="libpod" -GCLOUD_ZONE="${GCLOUD_ZONE:-us-central1-a}" -GCLOUD_CPUS="2" -GCLOUD_MEMORY="4Gb" -GCLOUD_DISK="200" -EOF - ;; - 2) - # get_ci_vm APIv2 configuration details - echo "AWS_PROFILE=containers" - ;; - *) - echo "Error: Your get_ci_vm container image is too old." - ;; - esac -elif [[ "$1" == "--setup" ]]; then - in_get_ci_vm "$1" - unset GET_CI_VM - # get_ci_vm container entrypoint calls us with this option on the - # Cirrus-CI environment instance, to perform repo.-specific setup. - cd $REPO_DIRPATH - echo "+ Loading ./hack/ci/lib.sh" > /dev/stderr - source ./hack/ci/lib.sh - echo "+ Mimicking .cirrus.yml build_task" > /dev/stderr - make install.tools - make binaries - make docs - echo "+ Running environment setup" > /dev/stderr - ./hack/ci/setup_environment.sh -else - # Pass this repo and CLI args into container for VM creation/management - mkdir -p $HOME/.config/gcloud/ssh - mkdir -p $HOME/.aws - podman run -it --rm \ - --tz=local \ - -e NAME="$USER" \ - -e SRCDIR=/src \ - -e GCLOUD_ZONE="$GCLOUD_ZONE" \ - -e A_DEBUG="${A_DEBUG:-0}" \ - -v $REPO_DIRPATH:/src:O \ - -v $HOME/.config/gcloud:/root/.config/gcloud:z \ - -v $HOME/.config/gcloud/ssh:/root/.ssh:z \ - -v $HOME/.aws:/root/.aws:z \ - quay.io/libpod/get_ci_vm:latest "$@" -fi