From 3c4550b0cd159564d34dd11f7677d8aa0c50db07 Mon Sep 17 00:00:00 2001 From: "Petr \"Stone\" Hracek" Date: Mon, 25 Oct 2021 10:40:00 +0200 Subject: [PATCH 1/2] Add GitHub workflow for release to PyPi Signed-off-by: Petr "Stone" Hracek --- .github/workflows/pypi-publish.yml | 33 +++++++++++++++++++++ .pre-commit-config.yaml | 5 ---- setup.py | 47 ++++++++++++++++++++++++++---- 3 files changed, 75 insertions(+), 10 deletions(-) create mode 100644 .github/workflows/pypi-publish.yml diff --git a/.github/workflows/pypi-publish.yml b/.github/workflows/pypi-publish.yml new file mode 100644 index 0000000..d705d44 --- /dev/null +++ b/.github/workflows/pypi-publish.yml @@ -0,0 +1,33 @@ +# MIT License +# +# Copyright (c) 2018 sclorg team at Red Hat +# +# Upload a Python package when a release is created +# https://packaging.python.org/guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows + +name: Publish Python 🐍 distributions 📦 to PyPI + +on: + release: + types: [created] + +jobs: + build-n-publish: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-python@v2 + + - name: Build a source tarball and a binary wheel + # https://pypa-build.readthedocs.io + run: | + python -m pip install build + python -m build --sdist --wheel + - name: Publish 📦 to PyPI + # https://github.com/pypa/gh-action-pypi-publish + uses: pypa/gh-action-pypi-publish@release/v1 + with: + # secrets.PYPI_API_TOKEN is set to usercont-release-bot user token + password: ${{ secrets.PYPI_CCI_API_TOKEN }} + verbose: true diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4aa13ef..14a7ac9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,11 +3,6 @@ # pre-commit install repos: -- repo: https://github.com/ambv/black - rev: 19.3b0 - hooks: - - id: black - language_version: python3.6 - repo: https://github.com/pre-commit/pre-commit-hooks rev: v2.2.3 hooks: diff --git a/setup.py b/setup.py index 0fab220..caa6404 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,31 @@ -try: - from setuptools import setup, find_packages -except ImportError: - from distutils.core import setup +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# The MIT License (MIT) +# +# Copyright (c) 2016-2018 CWT Authors +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +# Authors: Petr Hracek + +from setuptools import setup, find_packages def get_requirements(): @@ -12,11 +36,24 @@ def get_requirements(): setup( name="container-ci-suite", + description='A python3 container CI tool for testing images.', version="0.0.1", - packages=find_packages(exclude=["examples"]), + keywords='tool,containers,images,tests', + packages=find_packages(exclude=["tests"]), url="https://github.com/phracek/container-ci-suite", license="MIT", author="Petr Hracek", author_email="phracek@redhat.com", install_requires=get_requirements(), + scripts=[], + setup_requires=[], + classifiers=[ + 'Development Status :: 4 - Beta', + 'Environment :: Console', + 'Intended Audience :: Developers', + 'License :: OSI Approved :: MIT License', + 'Operating System :: POSIX :: Linux', + 'Programming Language :: Python', + 'Topic :: Software Development', + ], ) From 294fffce01abbfb2664b3e435fd9529c3e998fdc Mon Sep 17 00:00:00 2001 From: "Petr \"Stone\" Hracek" Date: Mon, 25 Oct 2021 14:01:01 +0200 Subject: [PATCH 2/2] Add GitHub worflows Signed-off-by: Petr "Stone" Hracek --- .github/workflows/pr-test.yml | 176 ++++++++++++++++++++++++++++++++ Makefile | 12 ++- README.md | 2 +- container_ci_suite/api.py | 2 +- container_ci_suite/constants.py | 2 +- requirements.txt | 2 +- tests/__init__.py | 2 +- tests/test_utils.py | 6 +- 8 files changed, 193 insertions(+), 11 deletions(-) create mode 100644 .github/workflows/pr-test.yml diff --git a/.github/workflows/pr-test.yml b/.github/workflows/pr-test.yml new file mode 100644 index 0000000..3194857 --- /dev/null +++ b/.github/workflows/pr-test.yml @@ -0,0 +1,176 @@ +# MIT License +# +# Copyright (c) 2018 sclorg team at Red Hat +# +# Upload a Python package when a release is created +# https://packaging.python.org/guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows + +name: Test PR for container-ci-suite + +on: + issue_comment: + types: [created] + +jobs: + build: + # This job only runs for '[test]' pull request comments by owner, member + name: Schedule test on Testing Farm service for Fedora + runs-on: ubuntu-latest + if: | + github.event.issue.pull_request + && contains(github.event.comment.body, '/test') + && contains(fromJson('["OWNER","MEMBER"]'), github.event.comment.author_association) + steps: + - name: Get pull request number + id: pr_nr + run: | + PR_URL="${{ github.event.comment.issue_url }}" + echo "::set-output name=PR_NR::${PR_URL##*/}" + - name: Checkout repo + uses: actions/checkout@v2 + with: + ref: "refs/pull/${{ steps.pr_nr.outputs.PR_NR }}/head" + + - name: Get sha + id: sha + run: | + # Store SHA into outputs + echo "::set-output name=SHA::$(git rev-parse HEAD)" + + - name: Schedule a test on Testing Farm for Fedora + id: sched_test + run: | + # Update ubuntu-latest in order to install curl and jq + sudo apt-get update && sudo apt-get -y install curl jq + cat << EOF > request.json + { + "api_key": "${{ secrets.TF_PUBLIC_API_KEY }}", + "test": {"fmf": { + "url": "https://github.com/sclorg/sclorg-testing-farm", + "ref": "main", + "name": "container-ci-suite" + }}, + "environments": [{ + "arch": "x86_64", + "os": {"compose": "Fedora-34"}, + "variables": { + "REPO_URL": "$GITHUB_SERVER_URL/$GITHUB_REPOSITORY", + "REPO_NAME": "$GITHUB_REPOSITORY", + "PR_NUMBER": "${{ steps.pr_nr.outputs.PR_NR }}" + } + }] + } + EOF + cat request.json + curl ${{ secrets.TF_ENDPOINT }}/requests --data @request.json --header "Content-Type: application/json" --output response.json + cat response.json + req_id=$(jq -r .id response.json) + echo "$req_id" + # Store REQ_ID into outputs for later on usage + echo "::set-output name=REQ_ID::$req_id" + + outputs: + REQ_ID: ${{ steps.sched_test.outputs.REQ_ID }} + SHA: ${{ steps.sha.outputs.SHA }} + + running: + needs: build + name: Check running tests on Testing Farm service + runs-on: ubuntu-20.04 + outputs: + REQ_ID: ${{ steps.req_sha.outputs.REQ_ID }} + SHA: ${{ steps.req_sha.outputs.SHA }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + steps: + - name: Check if REQ_ID and SHA exists + id: req_sha + run: | + # Update ubuntu-20.04 in order to install curl and jq + # each job is separate machine + sudo apt-get update && sudo apt-get -y install curl jq + # Propagate REQ_ID and SHA into the finish section + echo "::set-output name=REQ_ID::${{ needs.build.outputs.REQ_ID }}" + echo "::set-output name=SHA::${{ needs.build.outputs.SHA }}" + - name: Switch to running state of Testing Farm request + id: running + run: | + # Create running.json file for query, whether job is finished or not. + cat << EOF > running.json + { + "sha": "${{ needs.build.outputs.SHA }}", + "state": "pending", + "context": "Testing Farm", + "description": "Build started", + "target_url": "http://artifacts.dev.testing-farm.io/${{ needs.build.outputs.REQ_ID }}/" + } + EOF + # Update GitHub status description to 'Build started' + curl -X POST -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" -H "Accept: application/vnd.github.v3+json" \ + https://api.github.com/repos/$GITHUB_REPOSITORY/statuses/${{ needs.build.outputs.SHA }} \ + --data @running.json + - name: Check test is still running + id: still_running + run: | + CMD=${{ secrets.TF_ENDPOINT }}/requests/${{ needs.build.outputs.REQ_ID }} + curl $CMD > job.json + state=$(jq -r .state job.json) + # Wait till job is not finished. As soon as state is complete or failure then go to the finish action + while [ "$state" == "running" ] || [ "$state" == "new" ] || [ "$state" == "pending" ] || [ "$state" == "queued" ]; do + # Wait 30s. We do not need to query Testing Farm each second + sleep 30 + curl $CMD > job.json + state=$(jq -r .state job.json) + done + finish: + needs: running + name: Tests are finished - switching to proper state + runs-on: ubuntu-20.04 + steps: + - name: Check if REQ_ID exists + run: echo "${{ needs.running.outputs.REQ_ID }}" + + - name: Check if SHA exists + run: echo "${{ needs.running.outputs.SHA }}" + + - name: Get final state of Testing Farm request + id: final_state + run: | + # Update ubuntu-20.04 in order to install curl and jq + # each job is separate machine + sudo apt-get update && sudo apt-get -y install curl jq + curl ${{ secrets.TF_ENDPOINT }}/requests/${{ needs.running.outputs.REQ_ID }} > job.json + cat job.json + state=$(jq -r .state job.json) + result=$(jq -r .result.overall job.json) + new_state="success" + infra_error=" " + echo "State is $state and result is: $result" + if [ "$state" == "complete" ]; then + if [ "$result" != "passed" ]; then + new_state="failure" + fi + else + # Mark job in case of infrastructure issues. Report to Testing Farm team + infra_error=" - Infra problems" + new_state="failure" + fi + echo "New State is: $new_state" + echo "Infra state is: $infra_error" + echo "::set-output name=FINAL_STATE::$new_state" + echo "::set-output name=INFRA_STATE::$infra_error" + - name: Switch to final state of Testing Farm request + run: | + cat << EOF > final.json + { + "sha": "${{needs.running.outputs.SHA}}", + "state": "${{steps.final_state.outputs.FINAL_STATE}}", + "context": "Testing Farm", + "description": "Build finished${{steps.final_state.outputs.INFRA_STATE}}", + "target_url": "http://artifacts.dev.testing-farm.io/${{ needs.running.outputs.REQ_ID }}/" + } + EOF + cat final.json + # Switch Github status to proper state + curl -X POST -H "Authorization: Bearer ${{secrets.GITHUB_TOKEN}}" -H "Accept: application/vnd.github.v3+json" \ + https://api.github.com/repos/$GITHUB_REPOSITORY/statuses/${{ needs.running.outputs.SHA }} \ + --data @final.json diff --git a/Makefile b/Makefile index febee65..6219e62 100644 --- a/Makefile +++ b/Makefile @@ -1,15 +1,21 @@ .PHONY: build-test test test-in-container clean TEST_IMAGE_NAME = container-ci-suite-test +UNAME=$(shell uname) +ifeq ($(UNAME),Darwin) + PODMAN := /usr/local/bin/docker +else + PODMAN := /usr/bin/podman +endif build-test: - docker build --tag ${TEST_IMAGE_NAME} -f Dockerfile.tests . + $(PODMAN) build --tag ${TEST_IMAGE_NAME} -f Dockerfile.tests . test: cd tests && PYTHONPATH=$(CURDIR) pytest --color=yes -v --showlocals -test-in-container: build-test - docker run --rm --net=host -e DEPLOYMENT=test ${TEST_IMAGE_NAME} +test-in-container: + $(PODMAN) run --rm --net=host -e DEPLOYMENT=test ${TEST_IMAGE_NAME} clean: find . -name '*.pyc' -delete diff --git a/README.md b/README.md index 43d6b91..4d173ee 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,7 @@ class TestDummyImage(object): * [ ] ct_clone_git_repository * [ ] ct_show_resources * [ ] ct_s2i_multistage_build -* [ ] +* [ ] ## OpenShift tests diff --git a/container_ci_suite/api.py b/container_ci_suite/api.py index c364f8a..c08b1ba 100644 --- a/container_ci_suite/api.py +++ b/container_ci_suite/api.py @@ -201,7 +201,7 @@ def scl_usage_old(self): pass def create_container(self, cid_file: str, container_args: str = "", *args): - self.cid_file_dir = Path(mkdtemp(suffix=f".test_cid_files")) + self.cid_file_dir = Path(mkdtemp(suffix=".test_cid_files")) p = Path(self.cid_file_dir) self.cid_file = p / cid_file DockerCLIWrapper.run_docker_command( diff --git a/container_ci_suite/constants.py b/container_ci_suite/constants.py index 31dcf17..47d6855 100644 --- a/container_ci_suite/constants.py +++ b/container_ci_suite/constants.py @@ -20,4 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -CA_FILE_PATH: str = "/etc/pki/ca-trust/source/anchors/RH-IT-Root-CA.crt" \ No newline at end of file +CA_FILE_PATH: str = "/etc/pki/ca-trust/source/anchors/RH-IT-Root-CA.crt" diff --git a/requirements.txt b/requirements.txt index 085b78e..b9d8978 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,2 @@ pytest -flexmock \ No newline at end of file +flexmock diff --git a/tests/__init__.py b/tests/__init__.py index 4e84d14..2dbc786 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -20,4 +20,4 @@ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. \ No newline at end of file +# SOFTWARE. diff --git a/tests/test_utils.py b/tests/test_utils.py index 4bc5c6c..15334e8 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -70,8 +70,8 @@ def test_get_mount_ca_file(self): [ ("--pull-never", ""), ( - f"--pull-never -v /some/foo/bar/file:/some/foo/bar/file:Z", - f"-v /some/foo/bar/file:/some/foo/bar/file:Z", + "--pull-never -v /some/foo/bar/file:/some/foo/bar/file:Z", + "-v /some/foo/bar/file:/some/foo/bar/file:Z", ), ], ) @@ -85,7 +85,7 @@ def test_mount_point(self, s2i_args, expected_output): "s2i_args,expected_output", [ ("--pull-never", []), - (f"--pull-never -e NODE=development", ["ENV NODE=development"]), + ("--pull-never -e NODE=development", ["ENV NODE=development"]), ( "-v mount_point:mount_point:Z -e FOO=bar --env TEST=deployment", ["ENV FOO=bar", "ENV TEST=deployment"],