diff --git a/.github/TESTING b/.github/TESTING new file mode 100644 index 00000000..14297a2f --- /dev/null +++ b/.github/TESTING @@ -0,0 +1,10 @@ +The name of the branch plays a role in the tests run when changes are +submitted. For this reason, when modifying the workflows in ./.github, if you +want to test them prior to submission, the PR must be tested against a branch that +exists also in the `alire-index-checks` repo, e.g., 'stable-1.2' or 'devel-1.2' + +Normally you'll want to use the latest stable or devel branch. + +E.g., if you modify a workflow in the `alire-index` repo and want to test it +privately, you can do so in your own account, but using the same `stable-x.x` +base branch for your private PR. diff --git a/.github/workflows/build-crate.yml b/.github/workflows/build-crate.yml index 994db6bc..88c3b5be 100644 --- a/.github/workflows/build-crate.yml +++ b/.github/workflows/build-crate.yml @@ -1,5 +1,11 @@ +# Please read the TESTING file before modifying this file + name: Build Crate +env: + CHECKS_ORG: alire-project + CHECKS_REPO: alire-index-checks + on: pull_request: paths: @@ -59,6 +65,13 @@ jobs: # changed files detectors (in both scripts/gh-build-crate.sh and # check-author action). + - name: Check out alire-index-checks + uses: actions/checkout@v3 + with: + repository: ${{env.CHECKS_ORG}}/${{env.CHECKS_REPO}} + ref: ${{github.base_ref}} + path: ${{env.CHECKS_REPO}} + - name: Update system repositories if: matrix.os == 'ubuntu-latest' run: sudo apt update @@ -93,7 +106,7 @@ jobs: uses: mosteo/actions@docker-run/v1 with: image: alire/gnat:${{matrix.tag}} - command: scripts/gh-build-crate.sh + command: ${{env.CHECKS_REPO}}/scripts/gh-build-crate.sh params: -v ${{ github.workspace }}/alire_install/bin/alr:/usr/bin/alr - name: Install tar from msys2 (Windows) # Git tar in Actions VM does not seem to work) @@ -102,5 +115,5 @@ jobs: - name: Test crate (Windows/MacOS) if: matrix.os != 'ubuntu-latest' # native testing in Windows/MacOS - run: scripts/gh-build-crate.sh + run: ${{env.CHECKS_REPO}}/scripts/gh-build-crate.sh shell: bash diff --git a/.github/workflows/build-native.yml b/.github/workflows/build-native.yml index a004cdb0..d0fa816d 100644 --- a/.github/workflows/build-native.yml +++ b/.github/workflows/build-native.yml @@ -1,6 +1,12 @@ +# Please read the TESTING file before modifying this file + name: Toolchain # Build the submitted crate with a native toolchain from Alire +env: + CHECKS_ORG: alire-project + CHECKS_REPO: alire-index-checks + on: pull_request: paths: @@ -30,6 +36,13 @@ jobs: # changed files detectors (in both scripts/gh-build-crate.sh and # check-author action). + - name: Check out alire-index-checks + uses: actions/checkout@v3 + with: + repository: ${{env.CHECKS_ORG}}/${{env.CHECKS_REPO}} + ref: ${{github.base_ref}} + path: ${{env.CHECKS_REPO}} + # For the devel branch we need a compiler available to build alr in # setup-alire. We will be able to get rid of this once composite actions # support conditional steps. @@ -63,5 +76,5 @@ jobs: run: C:\Users\runneradmin\.cache\alire\msys64\usr\bin\pacman --noconfirm -S tar - name: Test crate - run: scripts/gh-build-crate.sh + run: ${{env.CHECKS_REPO}}/scripts/gh-build-crate.sh shell: bash diff --git a/.github/workflows/diff-release.yml b/.github/workflows/diff-release.yml index 4516edba..48e958ba 100644 --- a/.github/workflows/diff-release.yml +++ b/.github/workflows/diff-release.yml @@ -1,8 +1,14 @@ +# Please read the TESTING file before modifying this file + # Show differences between the submitted manifest and the previous # release of the same crate, to enable easier catching of problems name: Diff release +env: + CHECKS_ORG: alire-project + CHECKS_REPO: alire-index-checks + on: pull_request: paths: @@ -23,6 +29,13 @@ jobs: # need the full history or else grafted partial branches confuse the # changed files detector + - name: Check out alire-index-checks + uses: actions/checkout@v3 + with: + repository: ${{env.CHECKS_ORG}}/${{env.CHECKS_REPO}} + ref: ${{github.base_ref}} + path: ${{env.CHECKS_REPO}} + - name: Set up stable `alr` if: contains(github.base_ref, 'stable-') uses: alire-project/setup-alire@v1 @@ -49,5 +62,5 @@ jobs: branch: master - name: Diff releases - run: scripts/diff-release.sh || true # No deal breaker if failed + run: ${{env.CHECKS_REPO}}/scripts/diff-release.sh || true # No deal breaker if failed shell: bash diff --git a/scripts/diff-release.sh b/scripts/diff-release.sh deleted file mode 100755 index a44fef61..00000000 --- a/scripts/diff-release.sh +++ /dev/null @@ -1,76 +0,0 @@ -#!/bin/bash - -trap 'echo "ERROR at line ${LINENO} (code: $?)" >&2' ERR -trap 'echo "Interrupted" >&2 ; exit 1' INT - -set -o errexit -set -o nounset - -# Ensure all alr runs are non-interactive -alias alr="alr -n" - -# Detect changes -CHANGES=$(git diff --name-only HEAD~1) - -# Bulk changes for the record -echo Changed files: $CHANGES - -# Disable assistant. This is necessary despite the setup-alire action doing it -# too, because we sometimes run inside a Docker with fresh configuration -alr toolchain --disable-assistant - -# Configure index -alr index --del local >/dev/null || true # Simplifies local testing -alr index --name local --add ./index - -# Remove community index in case it has been added before -alr index --del community >/dev/null || true - -diff_opts=(--minimal -U0 --line-prefix "--| " --ignore-all-space --ignore-blank-lines --ignore-cr-at-eol) - -function diff_one() { - local file="$1" - local folder=$(dirname $file) - local crate=$(basename $file .toml | cut -f1 -d-) - local version=$(basename $file .toml | cut -f2- -d-) - local milestone="$crate=$version" - - echo " " - echo "------8<------" - - if echo $milestone | grep -q external; then - echo DIFFING external: $milestone - git diff "${diff_opts[@]}" HEAD~1 -- $file - else - echo DIFFING release: $milestone - - # Locate the immediately precedent release - - # For a first release, there's nothing to compare - if [ $(ls $folder | grep -v external | wc -l) -eq 1 ]; then - echo NOTHING to diff against, first crate release - return 0 - fi - - # Othewise, get from alr what's the immediately preceding version - local prev_milestone=$(alr show "$crate<$version" | head -1 | cut -f1 -d:) - echo DIFFING milestones $prev_milestone '-->' $milestone - - if [ "$prev_milestone" == "ERROR" ]; then - echo ERROR extracting milestone: - alr show "$crate<$version" - return 1 - fi - - # Convert into filename - local prev_file=$folder/${prev_milestone//=/-}.toml - - git diff --no-index "${diff_opts[@]}" -- $prev_file $file - fi - - return 0 -} - -for file in $CHANGES; do - diff_one "$file" || true # keep on trying for different files -done diff --git a/scripts/gh-build-crate.sh b/scripts/gh-build-crate.sh deleted file mode 100755 index 62fbb895..00000000 --- a/scripts/gh-build-crate.sh +++ /dev/null @@ -1,215 +0,0 @@ -#!/bin/bash - -trap 'echo "ERROR at line ${LINENO} (code: $?)" >&2' ERR -trap 'echo "Interrupted" >&2 ; exit 1' INT - -set -o errexit -set -o nounset - -# Required for aliases to work in non-interactive scripts -shopt -s expand_aliases - -# Ensure all alr runs are non-interactive and able to output unexpected errors -alias alr="alr -d -n" - -# Disable check for ownership that sometimes confuses docker-run git -# Also, Github is not vulnerable to iCVE-2022-24765/CVE-2022-24767, see -# https://github.blog/2022-04-12-git-security-vulnerability-announced/ -git config --global --add safe.directory '*' - -# See whats happening -git log --graph --decorate --pretty=oneline --abbrev-commit --all | head -30 - -# Detect changes -CHANGES=$(git diff --name-only HEAD~1) - -# Bulk changes for the record -echo Changed files: $CHANGES - -# Disable assistant. This is necessary despite the setup-alire action doing it -# too, because we sometimes run inside a Docker with fresh configuration -alr toolchain --disable-assistant - -# Show alr metadata -alr version - -# Configure index -alr index --name local --add ./index - -# Remove community index in case it has been added before -alr index --del community || true - -# Show environment for the record -env - -# Check index for obsolescent features -echo STRICT MODE index checks -alr index --check - -# Check no warning during index loading. -# Such a warning would also happen during `alr printenv`, breaking it. -# TODO: remove after old license deprecation. -alr search --crates 2>&1 | grep "Warning:" && exit 1 - -# Test crate -for file in $CHANGES; do - - if [[ $file == index.toml ]]; then - echo Skipping index metadata file: $file - continue - fi - - if [[ $file != *.toml ]]; then - echo Skipping non-crate file: $file - continue - fi - - if ! [ -f ./$file ]; then - echo Skipping deleted file: $file - continue - fi - - # Checks passed, this is a crate we must test - is_system=false - - crate=$(basename $file .toml | cut -f1 -d-) - version=$(basename $file .toml | cut -f2- -d-) - version_noextras=$(echo $version | cut -f1 -d- | cut -f1 -d+) - milestone="$crate=$version" - echo Testing crate: $milestone - # Remember that version can be "external", in which case we do not know the - # actual version, and indeed the test will only work if the external is the - # newest version. This probably merits a way of being tested properly, but - # that will require changes in alr. - - if [[ $version = external ]]; then - echo Downgrading milestone to plain crate name - milestone=$crate - fi - - # Show info for the record - echo PLATFORM-INDEPENDENT CRATE INFO $milestone - alr show $milestone - alr show --external $milestone - alr show --external-detect $milestone - - echo PLATFORM-DEPENDENT CRATE INFO $milestone - alr show --system $milestone - alr show --external --system $milestone - alr show --external-detect --system $milestone - crateinfo=$(alr show --external-detect --system $milestone) - - echo CRATE DEPENDENCIES $milestone - alr show --solve --detail --external-detect $milestone - solution=$(alr show --solve --detail --external-detect $milestone) - - # Fail if there are pins in the manifest - if grep -q 'Pins (direct)' <<< $crateinfo ; then - echo "FAIL: release $milestone manifest contains pins" - exit 1 - fi - - # Skip on explicit unavailability - if alr show --system $milestone | grep -q 'Available when: False'; then - echo SKIPPING crate build: $milestone UNAVAILABLE on system - continue - fi - - # In unsupported platforms, externals are properly reported as missing. We - # can skip testing of such a crate since it will likely fail. - if grep -q 'Dependencies (external):' <<< $solution ; then - echo SKIPPING build for crate $milestone with MISSING external dependencies - continue - fi - - # Update system repositories whenever a detected system package is involved, - # either as dependency or as the crate being tested. - if grep -iq 'origin: system' <<< $solution; then - echo "UPDATING system repositories with sudo from user ${USERNAME:-unset} ($UID:-unset)..." - type apt-get 2>/dev/null && sudo apt-get update || true - type pacman 2>/dev/null && sudo pacman -Syy || true - else - echo No need to update system repositories - fi - - # Install an Alire-provided gprbuild whenever there is a non-external gnat in solution - if grep -iq 'gnat_' <<< $solution && ! grep -iq 'gnat_external' <<< $solution; then - gnat_dep=$(grep -E -o '^ gnat_[a-z0-9_]*=\S*' <<< $solution | tail -1 | xargs) - gnat_dep=${gnat_dep:-gnat_native} - if alr show $gnat_dep | grep 'Provides: gnat=' >/dev/null; then - echo "INSTALLING indexed toolchain compatible with $gnat_dep" - alr toolchain --select $gnat_dep gprbuild - # -E for regex, -o for only the matched part, xargs to trim space - # We must give both the gnat in the solution and gprbuild, so both are compatible - # Even if we default to gnat_native, that would select the appropriate gprbuild - else - echo "Dependency $gnat_dep is not a GNAT compiler dependency, treating it as a regular crate" - fi - fi - - # Detect whether the crate is binary to skip build - is_binary=false - if grep -iq 'binary archive' <<< $crateinfo; then - echo Crate is BINARY - is_binary=true - fi - - # Alternatives for when the crate itself comes from an external. Only system - # externals should be tested. - if grep -q 'Origin: external path' <<< $crateinfo ; then - echo SKIPPING detected external crate $milestone - continue - elif grep -q 'Origin: system package' <<< $crateinfo ; then - echo INSTALLING detected system crate $milestone - is_system=true - elif grep -q 'Not found:' <<< $crateinfo && \ - grep -q 'There are external definitions' <<< $crateinfo - then - echo SKIPPING undetected external crate $crate - continue - fi - - # Detect missing dependencies for clearer error - if grep -q 'Dependencies cannot be met' <<< $solution ; then - echo FAIL: crate $milestone dependencies cannot be met - exit 1 - fi - - # Actual checks - echo DEPLOYING CRATE $milestone - if $is_binary; then - echo SKIPPING BUILD for BINARY crate, FETCHING only - elif $is_system; then - echo SKIPPING BUILD for SYSTEM crate, FETCHING only - fi - - alr -q get $milestone - - if $is_system; then - echo DETECTING INSTALLED PACKAGE via crate $milestone - alr show --external-detect $milestone - elif $is_binary; then - echo FETCHED BINARY crate OK - else - echo FETCHED SOURCE crate OK, deployed at $(alr get --dirname $milestone) - - # Enter the deployment dir - cd $(alr get --dirname $milestone) - - echo BUILD ENVIRONMENT - alr printenv - - echo BUILDING CRATE - alr build --release - # As normally dependencies/executables are built in release mode, we also - # check any submissions in this mode. Should we go overboard and check the - # three profile modes? - - echo LISTING EXECUTABLES of crate $milestone - alr run --list - - cd .. - fi - - echo CRATE $milestone TEST ENDED SUCCESSFULLY -done