diff --git a/.github/actions/test-cpan-libs/action.yml b/.github/actions/test-cpan-libs/action.yml new file mode 100644 index 0000000000..45818062d0 --- /dev/null +++ b/.github/actions/test-cpan-libs/action.yml @@ -0,0 +1,142 @@ +name: "test-cpan-libs" +description: "Test packaged CPAN libraries" +inputs: + package_extension: + description: "The package extension (deb or rpm)" + required: true + distrib: + description: "The distribution name" + required: true + arch: + description: "The architecture (amd64 or arm64)" + required: true + +runs: + using: "composite" + steps: + + - if: ${{ inputs.package_extension == 'rpm' }} + name: Install zstd, perl and Centreon repositories + run: | + dnf install -y zstd perl epel-release 'dnf-command(config-manager)' + dnf config-manager --set-enabled powertools || true # alma 8 + dnf config-manager --set-enabled crb || true # alma 9 + # Import Centreon GPG key + GPG_KEY_URL="https://yum-gpg.centreon.com/RPM-GPG-KEY-CES" + curl -sSL $GPG_KEY_URL -o RPM-GPG-KEY-CES + rpm --import RPM-GPG-KEY-CES + shell: bash + + - if: ${{ inputs.package_extension == 'deb' }} + name: Install zstd, perl and Centreon repositories + run: | + export DEBIAN_FRONTEND=noninteractive + apt-get update + apt-get install -y zstd perl wget gpg apt-utils procps + wget -O- https://apt-key.centreon.com | gpg --dearmor | tee /etc/apt/trusted.gpg.d/centreon.gpg > /dev/null 2>&1 + # Avoid apt to clean packages cache directory + rm -f /etc/apt/apt.conf.d/docker-clean + apt-get update + shell: bash + + - name: Restore packages from cache + uses: actions/cache/restore@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 + with: + path: ./*.${{ inputs.package_extension }} + key: ${{ github.sha }}-${{ github.run_id }}-${{ inputs.package_extension }}-${{ inputs.distrib }} + fail-on-cache-miss: true + + - if: ${{ inputs.package_extension == 'rpm' }} + name: Check packages installation / uninstallation + run: | + error_log="install_error_${{ inputs.distrib }}_${{ inputs.arch }}.log" + for package in ./*.rpm; do + echo "Installing package: $package" + # List dependencies, and remove version and comparison operators + dependencies=$(rpm -qpR $package | sed 's/ [0-9.-]*\(\s\|$\)/ /g' | sed 's/ [<>!=]*\(\s\|$\)/ /g') + for dependency in $dependencies; do + # Skip non-perl dependencies + if [[ $dependency != perl* ]]; then + continue + else + echo "Check dependency: $dependency" + # Update the dependency name to match the package name + dependency=$(echo $dependency | sed 's/(/-/g' | sed 's/)//g' | sed 's/::/-/g') + fi + # If the dependency has been built in the same workflow, install it + if [[ -n $(find . -maxdepth 1 -regex "\.\/$dependency-[0-9v].*\.rpm") ]]; then + echo "Installing dependency: $dependency" + error_output=$(dnf install -y ./$dependency*.rpm 2>&1) || { echo "$error_output" >> $error_log; echo "Error during installation of the dependency $dependency" >> $error_log; true; } + fi + done + # Install package, then uninstall it with all his dependencies + echo "Package installation..." + error_output=$(dnf install -y $package 2>&1) || { echo "$error_output" >> $error_log; echo "Error during installation of the package $package" >> $error_log; true; } + echo "Package installation done." + script_name=$(echo $package | tr '[:upper:]' '[:lower:]' | sed 's/\.\/perl-//' | sed 's/-[0-9\.-]*.el[0-9]..*.rpm//') + if [[ -f tests/cpan-libraries/$script_name.pl ]]; then + echo "Testing package..." + error_output=$(perl tests/cpan-libraries/$script_name.pl 2>&1) || { echo "$error_output" >> $error_log; echo "Error during the usage test of the package $package" >> $error_log; true; } + echo "Testing done." + else + echo "No test script found for the package $package" + fi + error_output=$(perl tests/cpan-libraries/$script_name.pl 2>&1) || { echo "$error_output" >> $error_log; echo "Error during testing of the package $package" >> $error_log; true; } + echo "Package uninstallation..." + error_output=$(dnf autoremove --setopt=keepcache=True -y $(echo $package | sed 's/_[0-9].*\.rpm//' | sed 's/.\///') 2>&1) || { echo "$error_output" >> $error_log; echo "Error during autoremove of the package $package" >> $error_log; true; } + echo "Package uninstallation done." + done + # If the file error_log exists and is not empty, the workflow is in error + if [[ -s $error_log ]]; then + cat $error_log + exit 1 + fi + shell: bash + + - if: ${{ inputs.package_extension == 'deb' }} + name: Check packages installation / uninstallation + run: | + error_log="install_error_${{ inputs.distrib }}_${{ inputs.arch }}.log" + for package in ./*.deb; do + # If the debian package name ends with amd64 or arm64, we only install it if the tested architecture is the same, otherwise we skip it + if [[ $package == *amd64.deb && ${{ inputs.arch }} != "amd64" || $package == *arm64.deb && ${{ inputs.arch }} != "arm64" ]]; then + continue + fi + echo "Installing package: $package" + # List dependencies + dependencies=$(dpkg-deb -I $package | grep Depends | sed 's/Depends: //' | sed 's/,//g' | sed 's/(\(.*\)//g') || { echo "$error_output" >> $error_log; echo "Error while listing dependencies of the package $package" >> $error_log; true; } + for dependency in $dependencies; do + # If the dependency exists in the Debian repository, don't check the local dependencies + dependency_info=$(apt-cache policy $dependency) + if [[ -n $dependency_info ]]; then + echo "Dependency $dependency exists in debian repository." + else + # If the dependency has been built in the same workflow, install it + for dependency_package in $(find . -maxdepth 1 -regex "\.\/${dependency}_[0-9].*all\.deb" -o -regex "\.\/${dependency}_[0-9].*${{ inputs.arch }}\.deb"); do + echo "Installing dependency: $dependency_package" + error_output=$(apt-get install -y ./$dependency_package 2>&1) || { echo "$error_output" >> $error_log; echo "Error during installation of the dependency $dependency" >> $error_log; true; } + done + fi + done + # Install package, then uninstall it with all his dependencies + echo "Package installation..." + error_output=$(apt-get install -y $package 2>&1) || { echo "$error_output" >> $error_log; echo "Error during installation of the package $package" >> $error_log; true; } + echo "Package installation done." + script_name=$(echo $package | sed 's/.\/lib//' | sed 's/-perl_[0-9\.-]*-deb.*\.deb//') + if [[ -f tests/cpan-libraries/$script_name.pl ]]; then + echo "Testing package..." + error_output=$(perl tests/cpan-libraries/$script_name.pl 2>&1) || { echo "$error_output" >> $error_log; echo "Error during the usage test of the package $package" >> $error_log; true; } + echo "Testing done." + else + echo "No test script found for the package $package" + fi + echo "Package uninstallation..." + error_output=$(apt-get autoremove -y --purge $(echo $package | sed 's/_[0-9].*\.deb//' | sed 's/.\///') 2>&1) || { echo "$error_output" >> $error_log; echo "Error during autoremove of the package $package" >> $error_log; true; } + echo "Package uninstallation done." + done + # If the file error_log exists and is not empty, the workflow is in error + if [[ -s $error_log ]]; then + cat $error_log + exit 1 + fi + shell: bash diff --git a/.github/workflows/perl-new-cpan-libraries.yml b/.github/workflows/perl-new-cpan-libraries.yml new file mode 100644 index 0000000000..399f8627c9 --- /dev/null +++ b/.github/workflows/perl-new-cpan-libraries.yml @@ -0,0 +1,512 @@ +name: test-cpan-libraries + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +on: + workflow_dispatch: + pull_request: + paths: + - ".github/workflows/perl-new-cpan-libraries.yml" + +jobs: + get-environment: + uses: ./.github/workflows/get-environment.yml + + package-rpm: + needs: [get-environment] + if: | + needs.get-environment.outputs.skip_workflow == 'false' && + needs.get-environment.outputs.stability != 'stable' + + runs-on: ubuntu-24.04 + strategy: + fail-fast: false + matrix: + distrib: [el8, el9] + name: + [ + "Crypt::Argon2", + "JSON::Path", + "Libssh::Session", + "LV", + "Net::Curl" + ] + include: + - build_distribs: "el8,el9" + - rpm_dependencies: "" + - rpm_provides: "" + - version: "" + - spec_file: "" + - no-auto-depends: "false" + - preinstall_cpanlibs: "" + - distrib: el8 + package_extension: rpm + image: packaging-plugins-alma8 + - distrib: el9 + package_extension: rpm + image: packaging-plugins-alma9 + - name: Crypt::Argon2 + preinstall_cpanlibs: "Dist::Build" + + name: package ${{ matrix.distrib }} ${{ matrix.name }} + container: + image: ${{ vars.DOCKER_INTERNAL_REGISTRY_URL }}/${{ matrix.image }}:latest + credentials: + username: ${{ secrets.HARBOR_CENTREON_PULL_USERNAME }} + password: ${{ secrets.HARBOR_CENTREON_PULL_TOKEN }} + + steps: + - if: ${{ contains(matrix.build_distribs, matrix.distrib) }} + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + + - if: ${{ contains(matrix.build_distribs, matrix.distrib) }} + name: Check if package already exists + id: check-package-existence + run: | + package_info=$(dnf provides 'perl(${{ matrix.name }})' 2>&1 | tr '[:upper:]' '[:lower:]' || true) + do_not_build="false" + if [[ ! $package_info =~ "no matches found" ]]; then + package_version=$(echo $package_info | grep -oP 'perl\(${{ matrix.name }}\) = \K[0-9]+\.[0-9]+') + if [[ -z "${{ matrix.version }}" || "$package_version" == "${{ matrix.version }}" ]]; then + echo "::warning::Package ${{ matrix.name }} already exists in the official ${{ matrix.distrib }} repository with the same version." + do_not_build="true" + else + echo "::warning::Package ${{ matrix.name }} exists in the official ${{ matrix.distrib }} repository with a different version." + do_not_build="false" + fi + fi + echo "do_not_build=$do_not_build" >> $GITHUB_OUTPUT + shell: bash + + - if: ${{ steps.check-package-existence.outputs.do_not_build == 'false' && contains(matrix.build_distribs, matrix.distrib) && matrix.spec_file == '' }} + run: | + cpan_info=$(cpanm --info ${{ matrix.name }}) + if [ -z "${{ matrix.version }}" ]; then + CPAN_PACKAGE_VERSION=$(echo $cpan_info | sed 's/\.tar\.gz$//' | sed 's/.*\-//' | sed 's/v//') + if [[ ! $CPAN_PACKAGE_VERSION =~ ^[0-9]+\.[0-9]+ ]]; then + echo "::error::Invalid version number: ${CPAN_PACKAGE_VERSION}" + exit 1 + fi + PACKAGE_VERSION=" -v ${CPAN_PACKAGE_VERSION}" + else + PACKAGE_VERSION=" -v ${{ matrix.version }}" + fi + + if [ -z "${{ matrix.rpm_dependencies }}" ]; then + PACKAGE_DEPENDENCIES="" + else + for PACKAGE_DEPENDENCY in `echo "${{ matrix.rpm_dependencies }}"`; do + PACKAGE_DEPENDENCIES="$PACKAGE_DEPENDENCIES --depends "$PACKAGE_DEPENDENCY"" + done + fi + + if [ "${{ matrix.no-auto-depends }}" == "true" ]; then + PACKAGE_DEPENDENCIES="$PACKAGE_DEPENDENCIES --no-auto-depends" + fi + + if [ -z "${{ matrix.rpm_provides }}" ]; then + PACKAGE_PROVIDES="" + else + for PACKAGE_PROVIDE in `echo "${{ matrix.rpm_provides }}"`; do + PACKAGE_PROVIDES="$PACKAGE_PROVIDES --provides $PACKAGE_PROVIDE" + done + fi + + for CPANLIB_PREINSTALL in `echo "${{ matrix.preinstall_cpanlibs }}"`; do + cpanm $CPANLIB_PREINSTALL + done + + export SYBASE="/usr" + + temp_file=$(mktemp) + echo "default.local" | tee /etc/mailname + created_package=$(fpm -s cpan -t ${{ matrix.package_extension }} --rpm-dist ${{ matrix.distrib }} --verbose --cpan-verbose --no-cpan-test$PACKAGE_DEPENDENCIES$PACKAGE_PROVIDES$PACKAGE_VERSION ${{ matrix.name }} | tee "$temp_file" | grep "Created package" | grep -oP '(?<=:path=>").*?(?=")') + # Check package name + if [ -z "$created_package" ]; then + echo "Error: fpm command failed" + exit 1 + fi + # Check rpm + rpm2cpio $created_package | cpio -t + shell: bash + + - if: ${{ steps.check-package-existence.outputs.do_not_build == 'false' && contains(matrix.build_distribs, matrix.distrib) && matrix.spec_file != '' }} + run: | + mkdir -p ~/rpmbuild/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS} + + rpmbuild --undefine=_disable_source_fetch -ba ${{ matrix.spec_file }} + + cp -r ~/rpmbuild/RPMS/noarch/*.rpm . + shell: bash + + - if: ${{ steps.check-package-existence.outputs.do_not_build == 'false' && contains(matrix.build_distribs, matrix.distrib) }} + name: Replace '::' with - in the feature path + id: package-name + run: | + name="${{ matrix.name }}" + name_with_dash="${name//::/-}" + echo "Modified Name: $name_with_dash" + echo "name_with_dash=$name_with_dash" >> $GITHUB_OUTPUT + shell: bash + + - if: ${{ steps.check-package-existence.outputs.do_not_build == 'false' && contains(matrix.build_distribs, matrix.distrib) }} + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 + with: + name: packages-${{ matrix.package_extension }}-${{ matrix.distrib }}-${{ steps.package-name.outputs.name_with_dash }} + path: ./*.${{ matrix.package_extension }} + retention-days: 1 + + merge-package-rpm-artifacts: + needs: [get-environment, package-rpm] + if: | + needs.get-environment.outputs.skip_workflow == 'false' && + needs.get-environment.outputs.stability != 'stable' + runs-on: ubuntu-24.04 + strategy: + matrix: + distrib: [el8, el9] + + steps: + - name: Merge Artifacts + uses: actions/upload-artifact/merge@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 + with: + name: packages-rpm-${{ matrix.distrib }} + pattern: packages-rpm-${{ matrix.distrib }}-* + delete-merged: false # cannot be set to true due to random fails: Failed to DeleteArtifact: Unable to make request: ECONNRESET + retention-days: 1 + + - name: Delete merged artifacts + uses: geekyeggo/delete-artifact@f275313e70c08f6120db482d7a6b98377786765b # v5.1.0 + with: + name: packages-rpm-${{ matrix.distrib }}-* + failOnError: false + + sign-rpm: + needs: [get-environment, merge-package-rpm-artifacts] + if: | + needs.get-environment.outputs.skip_workflow == 'false' && + needs.get-environment.outputs.stability != 'stable' + + runs-on: ubuntu-24.04 + strategy: + matrix: + distrib: [el8, el9] + name: sign rpm ${{ matrix.distrib }} + container: + image: docker.centreon.com/centreon-private/rpm-signing:latest + options: -t + credentials: + username: ${{ secrets.HARBOR_RPM_GPG_SIGNING_REPO_USERNAME }} + password: ${{ secrets.HARBOR_RPM_GPG_SIGNING_REPO_TOKEN }} + + steps: + - run: apt-get install -y zstd + shell: bash + + - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + + - uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 + with: + name: packages-rpm-${{ matrix.distrib }} + path: ./ + + - run: echo "HOME=/root" >> $GITHUB_ENV + shell: bash + + - run: rpmsign --addsign ./*.rpm + shell: bash + + - uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 + with: + path: ./*.rpm + key: ${{ github.sha }}-${{ github.run_id }}-rpm-${{ matrix.distrib }} + + package-deb: + needs: [get-environment] + if: | + needs.get-environment.outputs.skip_workflow == 'false' && + needs.get-environment.outputs.stability != 'stable' + + runs-on: ${{ matrix.runner_name }} + strategy: + fail-fast: false + matrix: + image: [packaging-plugins-bullseye, packaging-plugins-bookworm, packaging-plugins-jammy, packaging-plugins-bullseye-arm64] + name: + [ + "Crypt::Argon2", + "Libssh::Session", + "Net::Curl" + ] + include: + - runner_name: ubuntu-24.04 + - arch: amd64 + - build_names: "bullseye-amd64,bookworm,jammy" + - deb_dependencies: "" + - rpm_provides: "" + - version: "" + - use_dh_make_perl: "true" + - no-auto-depends: "false" + - preinstall_cpanlibs: "" + - build_name: bullseye-amd64 + distrib: bullseye + package_extension: deb + image: packaging-plugins-bullseye + - build_name: bookworm + distrib: bookworm + package_extension: deb + image: packaging-plugins-bookworm + - build_name: jammy + distrib: jammy + package_extension: deb + image: packaging-plugins-jammy + - build_name: bullseye-arm64 + distrib: bullseye + package_extension: deb + image: packaging-plugins-bullseye-arm64 + arch: arm64 + runner_name: ["self-hosted", "collect-arm64"] + - name: Crypt::Argon2 + build_names: "bullseye-amd64,jammy,bullseye-arm64" + preinstall_cpanlibs: "Dist::Build" + use_dh_make_perl: "false" + no-auto-depends: "true" + - name: Libssh::Session + use_dh_make_perl: "false" + build_names: "bullseye-amd64,bookworm,jammy,bullseye-arm64" + no-auto-depends: "true" + - name: Net::Curl + use_dh_make_perl: "false" + build_names: "bullseye-amd64,bookworm,jammy,bullseye-arm64" + no-auto-depends: "true" + name: package ${{ matrix.distrib }} ${{ matrix.arch }} ${{ matrix.name }} + container: + image: ${{ vars.DOCKER_INTERNAL_REGISTRY_URL }}/${{ matrix.image }}:latest + credentials: + username: ${{ secrets.HARBOR_CENTREON_PULL_USERNAME }} + password: ${{ secrets.HARBOR_CENTREON_PULL_TOKEN }} + + steps: + - if: ${{ contains(matrix.build_names, matrix.build_name) }} + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + + - if: ${{ contains(matrix.build_names, matrix.build_name) }} + name: Parse distrib name + id: parse-distrib + uses: ./.github/actions/parse-distrib + with: + distrib: ${{ matrix.distrib }} + + - if: ${{ contains(matrix.build_names, matrix.build_name) }} + name: Get package infos + id: package-infos + run: | + apt-get update + cpan_info=$(cpanm --info ${{ matrix.name }}) + if [ -z "${{ matrix.version }}" ]; then + CPAN_PACKAGE_VERSION=$(echo $cpan_info | sed 's/\.tar\.gz$//' | sed 's/.*\-//' | sed 's/v//') + if [[ ! $CPAN_PACKAGE_VERSION =~ ^[0-9]+\.[0-9]+ ]]; then + echo "::error::Invalid version number: ${CPAN_PACKAGE_VERSION}" + exit 1 + fi + PACKAGE_VERSION="${CPAN_PACKAGE_VERSION}" + else + PACKAGE_VERSION="${{ matrix.version }}" + fi + echo "package_version=$(echo $PACKAGE_VERSION)" >> $GITHUB_OUTPUT + CPAN_PACKAGE_NAME=$(echo $cpan_info | sed 's/.*\///g' | sed 's/-[0-9\.]*\.tar\.gz//g' | tr '[:upper:]' '[:lower:]') + PACKAGE_NAME="lib$CPAN_PACKAGE_NAME-perl" + echo "package_name=$(echo $PACKAGE_NAME)" >> $GITHUB_OUTPUT + shell: bash + + - if: ${{ contains(matrix.build_names, matrix.build_name) }} + name: Check if package already exists + id: check-package-existence + run: | + package_info=$(apt-cache policy ${{ steps.package-infos.outputs.package_name }}) + if [[ -n $package_info && "${{ steps.package-infos.outputs.package_name }}" =~ "_" ]]; then + package_info=$(apt-cache policy $(echo ${{ steps.package-infos.outputs.package_name }} | sed 's/_//g')) + fi + do_not_build="false" + if [[ -n $package_info ]]; then + candidate_version=$(echo "$package_info" | grep 'Candidate:' | awk '{print $2}') + if [[ "$candidate_version" == "${{ steps.package-infos.outputs.package_version }}"* ]]; then + echo "::warning::Package ${{ steps.package-infos.outputs.package_name }} already exists in the official ${{ matrix.distrib }} repository with the same version." + do_not_build="true" + else + echo "::warning::Package ${{ steps.package-infos.outputs.package_name }} exists in the official ${{ matrix.distrib }} repository with a different version." + do_not_build="false" + fi + fi + echo "do_not_build=$do_not_build" >> $GITHUB_OUTPUT + shell: bash + + - if: ${{ steps.check-package-existence.outputs.do_not_build == 'false' && contains(matrix.build_names, matrix.build_name) && matrix.use_dh_make_perl == 'false' }} + run: | + # Install needed cpan libs + for CPANLIB_PREINSTALL in `echo "${{ matrix.preinstall_cpanlibs }}"`; do + cpanm $CPANLIB_PREINSTALL + done + if [ -z "${{ matrix.deb_dependencies }}" ]; then + PACKAGE_DEPENDENCIES="" + else + for PACKAGE_DEPENDENCY in `echo ${{ matrix.deb_dependencies }}`; do + PACKAGE_DEPENDENCIES="$PACKAGE_DEPENDENCIES --depends $PACKAGE_DEPENDENCY" + done + fi + if [ "${{ matrix.no-auto-depends }}" == "true" ]; then + PACKAGE_DEPENDENCIES="$PACKAGE_DEPENDENCIES --no-auto-depends" + fi + + temp_file=$(mktemp) + echo "default.local" | tee /etc/mailname + created_package=$(fpm -s cpan -t ${{ matrix.package_extension }} --deb-dist ${{ matrix.distrib }} --iteration ${{ steps.parse-distrib.outputs.package_distrib_name }} --verbose --cpan-verbose --no-cpan-test$PACKAGE_DEPENDENCIES -v ${{ steps.package-infos.outputs.package_version }} ${{ matrix.name }} | tee "$temp_file" | grep "Created package" | grep -oP '(?<=:path=>").*?(?=")') || { echo "Error: fpm command failed"; exit 1; } + # Check package name + if [ -z "$created_package" ]; then + echo "Error: fpm command failed" + exit 1 + fi + # Check deb + dpkg-deb --contents $created_package || { echo "Error: dpkg-deb failed for package $created_package"; exit 1; } + shell: bash + + - if: ${{ steps.check-package-existence.outputs.do_not_build == 'false' && contains(matrix.build_names, matrix.build_name) && matrix.use_dh_make_perl == 'true' }} + run: | + # Install needed cpan libs + for CPANLIB_PREINSTALL in `echo "${{ matrix.preinstall_cpanlibs }}"`; do + cpanm $CPANLIB_PREINSTALL + done + temp_file=$(mktemp) + created_package=$(DEB_BUILD_OPTIONS="nocheck nodocs notest" dh-make-perl make --dist ${{ matrix.distrib }} --build --version ${{ steps.package-infos.outputs.package_version }}${{ steps.parse-distrib.outputs.package_distrib_separator }}${{ steps.parse-distrib.outputs.package_distrib_name }} --cpan ${{ matrix.name }} | tee "$temp_file" | grep "building package" | grep -oP "(?<=in '..\/).*.deb(?=')") || { echo "Error: dh-make-perl command failed"; exit 1; } + # Check package name + if [ -z "$created_package" ]; then + echo "Error: dh-make-perl command failed" + exit 1 + fi + # Check deb + dpkg-deb --contents $created_package || { echo "Error: dpkg-deb failed for package $created_package"; exit 1; } + shell: bash + + - if: ${{ steps.check-package-existence.outputs.do_not_build == 'false' && contains(matrix.build_names, matrix.build_name) }} + name: Replace '::' with - in the feature path + id: package-name + run: | + name="${{ matrix.name }}" + name_with_dash="${name//::/-}" + echo "Modified Name: $name_with_dash" + echo "name_with_dash=$name_with_dash" >> $GITHUB_OUTPUT + shell: bash + + - if: ${{ steps.check-package-existence.outputs.do_not_build == 'false' && contains(matrix.build_names, matrix.build_name) }} + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 + with: + name: packages-${{ matrix.package_extension }}-${{ matrix.distrib }}-${{ matrix.arch }}-${{ steps.package-name.outputs.name_with_dash}} + path: ./*.${{ matrix.package_extension }} + retention-days: 1 + + merge-package-deb-artifacts: + needs: [get-environment, package-deb] + if: | + needs.get-environment.outputs.skip_workflow == 'false' && + needs.get-environment.outputs.stability != 'stable' + runs-on: ubuntu-24.04 + strategy: + matrix: + distrib: [bullseye, bookworm, jammy] + + steps: + - name: Merge Artifacts + uses: actions/upload-artifact/merge@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 + with: + name: packages-deb-${{ matrix.distrib }} + pattern: packages-deb-${{ matrix.distrib }}-* + delete-merged: false # cannot be set to true due to random fails: Failed to DeleteArtifact: Unable to make request: ECONNRESET + retention-days: 1 + + - name: Delete merged artifacts + uses: geekyeggo/delete-artifact@f275313e70c08f6120db482d7a6b98377786765b # v5.1.0 + with: + name: packages-deb-${{ matrix.distrib }}-* + failOnError: false + + download-and-cache-deb: + needs: [get-environment, merge-package-deb-artifacts] + if: | + needs.get-environment.outputs.skip_workflow == 'false' && + needs.get-environment.outputs.stability != 'stable' + runs-on: ubuntu-24.04 + strategy: + matrix: + distrib: [bullseye, bookworm, jammy] + steps: + - uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 + with: + name: packages-deb-${{ matrix.distrib }} + path: ./ + + - uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 + with: + path: ./*.deb + key: ${{ github.sha }}-${{ github.run_id }}-deb-${{ matrix.distrib }} + + test-packages: + needs: [get-environment, sign-rpm, download-and-cache-deb] + strategy: + fail-fast: false + matrix: + include: + - package_extension: rpm + image: almalinux:8 + distrib: el8 + arch: amd64 + runner_name: ubuntu-24.04 + - package_extension: rpm + image: almalinux:9 + distrib: el9 + arch: amd64 + runner_name: ubuntu-24.04 + - package_extension: deb + image: debian:bullseye + distrib: bullseye + arch: amd64 + runner_name: ubuntu-24.04 + - package_extension: deb + image: debian:bookworm + distrib: bookworm + arch: amd64 + runner_name: ubuntu-24.04 + - package_extension: deb + image: ubuntu:jammy + distrib: jammy + arch: amd64 + runner_name: ubuntu-24.04 + - package_extension: deb + image: debian:bullseye + distrib: bullseye + arch: arm64 + runner_name: ["self-hosted", "collect-arm64"] + + runs-on: ${{ matrix.runner_name }} + container: + image: ${{ matrix.image }} + + name: Test perl CPAN libs packages on ${{ matrix.package_extension }} ${{ matrix.distrib }} ${{ matrix.arch }} + steps: + + - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + + - name: Test packaged libs + uses: ./.github/actions/test-cpan-libs + with: + package_extension: ${{ matrix.package_extension }} + distrib: ${{ matrix.distrib }} + arch: ${{ matrix.arch }} + + - name: Upload error log + if: failure() + uses: actions/upload-artifact@v4 + with: + name: install_error_log_${{ matrix.distrib }}-${{ matrix.arch }} + path: install_error_${{ matrix.distrib }}_${{ matrix.arch }}.log diff --git a/tests/cpan-libraries/crypt-argon2.pl b/tests/cpan-libraries/crypt-argon2.pl new file mode 100755 index 0000000000..c169feb5bc --- /dev/null +++ b/tests/cpan-libraries/crypt-argon2.pl @@ -0,0 +1,41 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use Crypt::Argon2 qw/argon2d_raw argon2i_raw argon2id_raw argon2_pass argon2_verify/; + +# Password to hash +my $password = 'my_secure_password'; +my $salt = 'random_salt'; +my $iterations = 3; +my $memory_cost = 32 * 1024; # in KB +my $parallelism = 1; +my $hash_length = 32; + +# Hash with Argon2d +my $argon2d_hash = argon2d_raw($password, $salt, $iterations, $memory_cost, $parallelism, $hash_length); +print("Argon2d hash: " . unpack("H*", $argon2d_hash) . "\n"); +# Hash with Argon2i +my $argon2i_hash = argon2i_raw($password, $salt, $iterations, $memory_cost, $parallelism, $hash_length); +print("Argon2i hash: " . unpack("H*", $argon2i_hash) . "\n"); +# Hash with Argon2id +my $argon2id_hash = argon2id_raw($password, $salt, $iterations, $memory_cost, $parallelism, $hash_length); +print("Argon2id hash: " . unpack("H*", $argon2id_hash) . "\n"); + +# Encode password with Argon2d +my $argon2d_encoded = argon2_pass('argon2d', $password, $salt, $iterations, $memory_cost, $parallelism, $hash_length); +print "Argon2d encoded: $argon2d_encoded\n"; +# Encode password with Argon2i +my $argon2i_encoded = argon2_pass('argon2i', $password, $salt, $iterations, $memory_cost, $parallelism, $hash_length); +print "Argon2i encoded: $argon2i_encoded\n"; +# Encode password with Argon2id +my $argon2id_encoded = argon2_pass('argon2id', $password, $salt, $iterations, $memory_cost, $parallelism, $hash_length); +print "Argon2id encoded: $argon2id_encoded\n"; + +# Verify password with Argon2d +# print argon2d_verify($argon2d_encoded1, $password) ? "Argon2d password is correct.\n" : "Argon2d password is incorrect.\n"; +argon2_verify($argon2d_encoded, $password) ? print "Argon2d password is correct.\n" : print "Argon2d password is incorrect.\n"; +# Verify password with Argon2i +argon2_verify($argon2i_encoded, $password) ? print "Argon2i password is correct.\n" : print "Argon2i password is incorrect.\n"; +# Verify password with Argon2id +argon2_verify($salt, $password) ? print "Argon2id password is correct.\n" : print "Argon2id password is incorrect.\n"; diff --git a/tests/cpan-libraries/json-path.pl b/tests/cpan-libraries/json-path.pl new file mode 100644 index 0000000000..630b239b5e --- /dev/null +++ b/tests/cpan-libraries/json-path.pl @@ -0,0 +1,32 @@ +#!/usr/bin/perl +use strict; +use warnings; +use JSON::Path; + +# Sample Perl data structure +my $data = { + store => { + book => [ + { category => "reference", author => "Nigel Rees", title => "Sayings of the Century", price => 8.95 }, + { category => "fiction", author => "Evelyn Waugh", title => "Sword of Honour", price => 12.99 }, + { category => "fiction", author => "Herman Melville", title => "Moby Dick", isbn => "0-553-21311-3", price => 8.99 }, + { category => "fiction", author => "J. R. R. Tolkien", title => "The Lord of the Rings", isbn => "0-395-19395-8", price => 22.99 } + ], + bicycle => { + color => "red", + price => 19.95 + } + } +}; + +# Create a JSON::Path object +my $jpath = JSON::Path->new('$.store.book[*].author'); + +# Find all authors +my @authors = $jpath->values($data); + +# Print authors +print "Authors:\n"; +foreach my $author (@authors) { + print "$author\n"; +} \ No newline at end of file