diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..76df8c2 --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,56 @@ +on: + push: + branches: + - main + pull_request: + workflow_dispatch: + +permissions: read-all + +jobs: + test-architectures: + name: test OS/arch combinations + strategy: + fail-fast: false + matrix: + os: + - 'ubuntu-24.04' + - 'ubuntu-24.04-arm' + - 'macos-13' # the last intel mac + - 'macos-15' # arm64 mac + - 'windows-2025' + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 + + - name: install local package + run: | + python -m pip install . + + - name: test that editorconfig-checker works by letting it output it's version + run: | + ec --version + + test-python-versions: + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v4 + + - name: install flake8 + run: | + python -m pip install flake8 + + - name: run testsuite verifying against all python versions + shell: bash + run: | + # Only test the local package, since we assume that we only + # upload to PyPI once we are certain that the local package is fine. + export TEST_LOCAL_PKG=true + export TEST_PYPI_PKG=false + + # The same commands are defined in the `Makefile` and used for local development. + # We added them here to simplify the building process of the Docker + # image that points to `python:2.7-slim`. + # For such image, `apt-get` was not working as expected. + flake8 --ignore E501 setup.py + bash run-tests.sh diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..d4f8286 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,22 @@ +# Dockerfile is run by `run-tests.sh` + +# used to define the python tag +ARG IMAGE=3.13-slim + + +FROM python:$IMAGE AS pybase +RUN python -m pip install --upgrade pip + +# separate the obtaining of the requirements from the actual test, so we can use build caching for the first step +FROM pybase as tester +LABEL maintainer="Marco M. (mmicu) " + +COPY . /app +WORKDIR /app + +# used to define which python package is installed with pip: +# - a value of `.` builds the images using the docker build context - aka the revision of the package which is currently checked out +# - using a value of `editorconfig-checker` will instead pull the image from PyPI +ARG PACKAGE=. + +RUN pip install --no-cache-dir $PACKAGE diff --git a/Makefile b/Makefile index 4948e11..c297ac5 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,7 @@ help: @echo " - clean : Remove generated files." @echo " - coding-style : Run coding style tools." @echo " - publish : Publish package to PyPI." + @echo " - quick-test : Run coding style tools and only the test for the latest python and the current git revision." @echo " - test : Run coding style tools and tests." .PHONY: all @@ -12,7 +13,7 @@ all: help .PHONY: clean clean: - @rm -rf build dist editorconfig_checker.egg-info editorconfig_checker/bin tests/Dockerfile-* + @rm -rf build dist editorconfig_checker.egg-info editorconfig_checker/bin .PHONY: coding-style coding-style: @@ -23,6 +24,11 @@ publish: clean test @python3 setup.py sdist @twine upload dist/* +.PHONY: quick-test +quick-test: coding-style + docker build -t ec-quick-test . + docker run ec-quick-test ec -version + .PHONY: test test: coding-style @bash run-tests.sh diff --git a/run-tests.sh b/run-tests.sh index a76053b..16b382c 100755 --- a/run-tests.sh +++ b/run-tests.sh @@ -2,61 +2,58 @@ set -e -DOCKERFILE_TEMPLATE="tests/Dockerfile.template" - -PY_DOCKER_IMAGES=() -PY_DOCKER_IMAGES+=("2.7.16-slim") -PY_DOCKER_IMAGES+=("3.7.4-slim") -PY_DOCKER_IMAGES+=("3.8-slim") -PY_DOCKER_IMAGES+=("3.9-slim") -PY_DOCKER_IMAGES+=("3.10-slim") -PY_DOCKER_IMAGES+=("3.11-slim") - -create_docker_file() { - local package="$1" - - # Generate a valid Dockerfile from a template file - local dockerfile="tests/Dockerfile-$py_docker_image-$package" - cp "$DOCKERFILE_TEMPLATE" "$dockerfile" - - # Replace docker image - sed -i '' "s/\$IMAGE/$py_docker_image/g" "$dockerfile" - - # Replace package name - if [[ "$package" == "local" ]]; then - package="." - fi - sed -i '' "s/\$PACKAGE/$package/g" "$dockerfile" - - echo "$dockerfile" -} - build_docker_image_and_run() { local py_docker_image="$1" local package="$2" - local dockerfile="$3" - # Build local docker_image="editorconfig-checker-$py_docker_image-$package:latest" - docker build -t "$docker_image" -f "$dockerfile" --no-cache --quiet . - # Run `editorconfig-checker` + docker_package="$package" + if [[ "$package" == "local" ]]; then + docker_package="." + fi + + docker build \ + -t "$docker_image" \ + -f "Dockerfile" \ + --no-cache-filter tester \ + --quiet \ + --build-arg "IMAGE=$py_docker_image" \ + --build-arg "PACKAGE=$docker_package" \ + . + docker run --rm "$docker_image" ec -version } main() { echo -e "Running tests...\n\n" - for py_docker_image in "${PY_DOCKER_IMAGES[@]}"; do - for package in local editorconfig-checker; do - local dockerfile=$(create_docker_file "$package") - echo "Dockerfile created at \"$dockerfile\" (\"$py_docker_image\" image and \"$package\" package)" - - echo "Building docker image. It could take some time..." - build_docker_image_and_run "$py_docker_image" "$package" "$dockerfile" + local py_versions=() + if [ -n "$TEST_PY_VERSION" ]; then + py_versions+=("$TEST_PY_VERSION") + else + py_versions+=("2.7") + py_versions+=("3.7") + py_versions+=("3.8") + py_versions+=("3.9") + py_versions+=("3.10") + py_versions+=("3.11") + py_versions+=("3.12") + py_versions+=("3.13") + fi - # docker image rm "$docker_image" &> /dev/null + local py_packages=() + if [ -z "$TEST_LOCAL_PKG" ] || [ "$TEST_LOCAL_PKG" = "true" ]; then + py_packages+=("local") + fi + if [ -z "$TEST_PYPI_PKG" ] || [ "$TEST_PYPI_PKG" = "true" ]; then + py_packages+=("editorconfig-checker") + fi + for py_version in "${py_versions[@]}"; do + for package in "${py_packages[@]}"; do + echo "Building docker image with Python version $py_version and $package package. It could take some time..." + build_docker_image_and_run "$py_version-slim" "$package" echo -e "\n" done done diff --git a/tests/.gitignore b/tests/.gitignore deleted file mode 100644 index 2527e80..0000000 --- a/tests/.gitignore +++ /dev/null @@ -1 +0,0 @@ -Dockerfile-* diff --git a/tests/Dockerfile.template b/tests/Dockerfile.template deleted file mode 100644 index 92d8138..0000000 --- a/tests/Dockerfile.template +++ /dev/null @@ -1,12 +0,0 @@ -# Dockerfile used as a template. Placeholders "$IMAGE" and "$PACKAGE" are replaced -# with their actual value by `run-tests.sh` -FROM python:$IMAGE -LABEL maintainer="Marco M. (mmicu) " - -COPY . /app -WORKDIR /app - -RUN apt-get update \ - && apt-get install -y make \ - && python -m pip install --upgrade pip \ - && pip install --no-cache-dir $PACKAGE