diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 67c45002e0..0000000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,187 +0,0 @@ -version: 2 -jobs: - run_tests: - docker: - - image: python:3.7 - environment: - TERM: xterm-256color # To colorize output of make tasks. - - steps: - - checkout - - - restore_cache: - key: v1-py3-{{ .Branch }}-{{ checksum "setup.py" }} - - - run: - name: Create a virtualenv - command: | - mkdir -p /tmp/venv/openfisca_core - python -m venv /tmp/venv/openfisca_core - echo "source /tmp/venv/openfisca_core/bin/activate" >> $BASH_ENV - - - run: - name: Install dependencies - command: | - make install - make clean - # pip install --editable git+https://github.com/openfisca/country-template.git@BRANCH_NAME#egg=OpenFisca-Country-Template # use a specific branch of OpenFisca-Country-Template - # pip install --editable git+https://github.com/openfisca/extension-template.git@BRANCH_NAME#egg=OpenFisca-Extension-Template # use a specific branch of OpenFisca-Extension-Template - - - save_cache: - key: v1-py3-{{ .Branch }}-{{ checksum "setup.py" }} - paths: - - /tmp/venv/openfisca_core - - - run: - name: Run linters - command: make lint - - - run: - name: Run openfisca-core tests - command: make test-core pytest_args="--exitfirst" - - - run: - name: Run country-template tests - command: make test-country pytest_args="--exitfirst" - - - run: - name: Run extension-template tests - command: make test-extension pytest_args="--exitfirst" - - - run: - name: Check NumPy typing against latest 3 minor versions - command: for i in {1..3}; do VERSION=$(.circleci/get-numpy-version.py prev) && pip install numpy==$VERSION && make check-types; done - - - persist_to_workspace: - root: . - paths: - - .coverage - - test_docs: - docker: - - image: python:3.7 - environment: - TERM: xterm-256color # To colorize output of make tasks. - - steps: - - checkout - - - run: - name: Checkout docs - command: make test-doc-checkout branch=$CIRCLE_BRANCH - - - restore_cache: - key: v1-py3-{{ .Branch }}-{{ checksum "setup.py" }} - - - restore_cache: - key: v1-py3-docs-{{ .Branch }}-{{ checksum "doc/requirements.txt" }} - - - run: - name: Create a virtualenv - command: | - mkdir -p /tmp/venv/openfisca_doc - python -m venv /tmp/venv/openfisca_doc - echo "source /tmp/venv/openfisca_doc/bin/activate" >> $BASH_ENV - - - run: - name: Install dependencies - command: make test-doc-install - - - save_cache: - key: v1-py3-docs-{{ .Branch }}-{{ checksum "doc/requirements.txt" }} - paths: - - /tmp/venv/openfisca_doc - - - run: - name: Run doc tests - command: make test-doc-build - - - check_version: - docker: - - image: python:3.7 - - steps: - - checkout - - - run: - name: Check version number has been properly updated - command: | - git fetch - .circleci/is-version-number-acceptable.sh - - submit_coverage: - docker: - - image: python:3.7 - - steps: - - checkout - - - attach_workspace: - at: . - - - restore_cache: - key: v1-py3-{{ .Branch }}-{{ checksum "setup.py" }} - - - run: - name: Submit coverage to Coveralls - command: | - source /tmp/venv/openfisca_core/bin/activate - pip install coveralls - coveralls - - - save_cache: - key: v1-py3-{{ .Branch }}-{{ checksum "setup.py" }} - paths: - - /tmp/venv/openfisca_core - - deploy: - docker: - - image: python:3.7 - environment: - PYPI_USERNAME: openfisca-bot - # PYPI_PASSWORD: this value is set in CircleCI's web interface; do not set it here, it is a secret! - - steps: - - checkout - - - restore_cache: - key: v1-py3-{{ .Branch }}-{{ checksum "setup.py" }} - - - run: - name: Check for functional changes - command: if ! .circleci/has-functional-changes.sh ; then circleci step halt ; fi - - - run: - name: Upload a Python package to Pypi - command: | - source /tmp/venv/openfisca_core/bin/activate - .circleci/publish-python-package.sh - - - run: - name: Publish a git tag - command: .circleci/publish-git-tag.sh - - - run: - name: Update doc - command: | - curl -X POST --header "Content-Type: application/json" -d '{"branch":"master"}' https://circleci.com/api/v1.1/project/github/openfisca/openfisca-doc/build?circle-token=$CIRCLE_TOKEN - -workflows: - version: 2 - build_and_deploy: - jobs: - - run_tests - - test_docs - - check_version - - submit_coverage: - requires: - - run_tests - - deploy: - requires: - - run_tests - - test_docs - - check_version - filters: - branches: - only: master diff --git a/.circleci/publish-python-package.sh b/.circleci/publish-python-package.sh deleted file mode 100755 index 8d331bd946..0000000000 --- a/.circleci/publish-python-package.sh +++ /dev/null @@ -1,4 +0,0 @@ -#! /usr/bin/env bash - -python setup.py bdist_wheel # build this package in the dist directory -twine upload dist/* --username $PYPI_USERNAME --password $PYPI_PASSWORD # publish diff --git a/.circleci/get-numpy-version.py b/.github/get-numpy-version.py similarity index 100% rename from .circleci/get-numpy-version.py rename to .github/get-numpy-version.py diff --git a/.circleci/has-functional-changes.sh b/.github/has-functional-changes.sh similarity index 89% rename from .circleci/has-functional-changes.sh rename to .github/has-functional-changes.sh index b591716932..bf1270989a 100755 --- a/.circleci/has-functional-changes.sh +++ b/.github/has-functional-changes.sh @@ -1,6 +1,6 @@ #! /usr/bin/env bash -IGNORE_DIFF_ON="README.md CONTRIBUTING.md Makefile .gitignore LICENSE* .circleci/* .github/* openfisca_tasks/*.mk tasks/*.mk tests/*" +IGNORE_DIFF_ON="README.md CONTRIBUTING.md Makefile .gitignore LICENSE* .github/* tests/* openfisca_tasks/*.mk tasks/*.mk" last_tagged_commit=`git describe --tags --abbrev=0 --first-parent` # --first-parent ensures we don't follow tags not published in master through an unlikely intermediary merge commit diff --git a/.circleci/is-version-number-acceptable.sh b/.github/is-version-number-acceptable.sh similarity index 95% rename from .circleci/is-version-number-acceptable.sh rename to .github/is-version-number-acceptable.sh index ae370e2a17..0f704a93fe 100755 --- a/.circleci/is-version-number-acceptable.sh +++ b/.github/is-version-number-acceptable.sh @@ -1,6 +1,6 @@ #! /usr/bin/env bash -if [[ $CIRCLE_BRANCH == master ]] +if [[ ${GITHUB_REF#refs/heads/} == master ]] then echo "No need for a version check on master." exit 0 diff --git a/.circleci/publish-git-tag.sh b/.github/publish-git-tag.sh similarity index 100% rename from .circleci/publish-git-tag.sh rename to .github/publish-git-tag.sh diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml new file mode 100644 index 0000000000..10aff151d2 --- /dev/null +++ b/.github/workflows/workflow.yml @@ -0,0 +1,240 @@ +name: OpenFisca Core + +on: [ push ] + +jobs: + build: + runs-on: ubuntu-latest + env: + TERM: xterm-256color # To colorize output of make tasks. + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: 3.7.12 # Patch version must be specified to avoid any cache confusion, since the cache key depends on the full Python version. If left unspecified, different patch versions could be allocated between jobs, and any such difference would lead to a cache not found error. + - name: Cache build + id: restore-build + uses: actions/cache@v2 + with: + path: ${{ env.pythonLocation }} + key: build-${{ env.pythonLocation }}-${{ hashFiles('setup.py') }}-${{ github.sha }} + restore-keys: | # in case of a cache miss (systematically unless the same commit is built repeatedly), the keys below will be used to restore dependencies from previous builds, and the cache will be stored at the end of the job, making up-to-date dependencies available for all jobs of the workflow; see more at https://docs.github.com/en/actions/advanced-guides/caching-dependencies-to-speed-up-workflows#example-using-the-cache-action + build-${{ env.pythonLocation }}-${{ hashFiles('setup.py') }} + build-${{ env.pythonLocation }}- + - name: Build package + run: make build + - name: Cache release + id: restore-release + uses: actions/cache@v2 + with: + path: dist + key: release-${{ env.pythonLocation }}-${{ hashFiles('setup.py') }}-${{ github.sha }} + + test-core: + runs-on: ubuntu-latest + needs: [ build ] + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + TERM: xterm-256color # To colorize output of make tasks. + steps: + - uses: actions/checkout@v2 + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: 3.7.12 + - name: Cache build + id: restore-build + uses: actions/cache@v2 + with: + path: ${{ env.pythonLocation }} + key: build-${{ env.pythonLocation }}-${{ hashFiles('setup.py') }}-${{ github.sha }} + - name: Run openfisca-core tests + run: make test-core + - name: Submit coverage to Coveralls + run: | + pip install coveralls + coveralls --service=github + + test-country-template: + runs-on: ubuntu-latest + needs: [ build ] + env: + TERM: xterm-256color + steps: + - uses: actions/checkout@v2 + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: 3.7.12 + - name: Cache build + id: restore-build + uses: actions/cache@v2 + with: + path: ${{ env.pythonLocation }} + key: build-${{ env.pythonLocation }}-${{ hashFiles('setup.py') }}-${{ github.sha }} + - name: Run Country Template tests + run: make test-country + + test-extension-template: + runs-on: ubuntu-latest + needs: [ build ] + env: + TERM: xterm-256color + steps: + - uses: actions/checkout@v2 + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: 3.7.12 + - name: Cache build + id: restore-build + uses: actions/cache@v2 + with: + path: ${{ env.pythonLocation }} + key: build-${{ env.pythonLocation }}-${{ hashFiles('setup.py') }}-${{ github.sha }} + - name: Run Extension Template tests + run: make test-extension + + check-numpy: + runs-on: ubuntu-latest + needs: [ build ] + env: + TERM: xterm-256color + steps: + - uses: actions/checkout@v2 + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: 3.7.12 + - name: Cache build + id: restore-build + uses: actions/cache@v2 + with: + path: ${{ env.pythonLocation }} + key: build-${{ env.pythonLocation }}-${{ hashFiles('setup.py') }}-${{ github.sha }} + - name: Check NumPy typing against latest 3 minor versions + run: for i in {1..3}; do VERSION=$(${GITHUB_WORKSPACE}/.github/get-numpy-version.py prev) && pip install numpy==$VERSION && make check-types; done + + test-docs: + runs-on: ubuntu-latest + needs: [ build ] + env: + TERM: xterm-256color + steps: + - uses: actions/checkout@v2 + - name: Checkout docs + run: make test-doc-checkout branch=${GITHUB_REF#refs/heads/} + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: 3.7.12 + - name: Cache build + id: restore-build + uses: actions/cache@v2 + with: + path: ${{ env.pythonLocation }} + key: build-${{ env.pythonLocation }}-${{ hashFiles('setup.py') }}-${{ github.sha }} + - name: Cache docs + id: restore-docs + uses: actions/cache@v2 + with: + path: ${{ env.pythonLocation }} + key: docs-${{ env.pythonLocation }}-${{ hashFiles('doc/requirements.txt') }}--${{ github.sha }} + - name: Install dependencies + run: make test-doc-install + - name: Run doc tests + run: make test-doc-build + + lint-files: + runs-on: ubuntu-latest + needs: [ build ] + env: + TERM: xterm-256color + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 # Fetch all the tags + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: 3.7.12 + - name: Cache build + id: restore-build + uses: actions/cache@v2 + with: + path: ${{ env.pythonLocation }} + key: build-${{ env.pythonLocation }}-${{ hashFiles('setup.py') }}-${{ github.sha }} + - name: Run linters + run: make lint + + check-version: + runs-on: ubuntu-latest + needs: [ test-core, test-country-template, test-extension-template, check-numpy, test-docs, lint-files ] # Last job to run + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 # Fetch all the tags + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: 3.7.12 + - name: Check version number has been properly updated + run: "${GITHUB_WORKSPACE}/.github/is-version-number-acceptable.sh" + + # GitHub Actions does not have a halt job option, to stop from deploying if no functional changes were found. + # We build a separate job to substitute the halt option. + # The `deploy` job is dependent on the output of the `check-for-functional-changes`job. + check-for-functional-changes: + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/master' # Only triggered for the `master` branch + needs: [ check-version ] + outputs: + status: ${{ steps.stop-early.outputs.status }} + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 # Fetch all the tags + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: 3.7.12 + - id: stop-early + run: if "${GITHUB_WORKSPACE}/.github/has-functional-changes.sh" ; then echo "::set-output name=status::success" ; fi # The `check-for-functional-changes` job should always succeed regardless of the `has-functional-changes` script's exit code. Consequently, we do not use that exit code to trigger deploy, but rather a dedicated output variable `status`, to avoid a job failure if the exit code is different from 0. Conversely, if the job fails the entire workflow would be marked as `failed` which is disturbing for contributors. + + deploy: + runs-on: ubuntu-latest + needs: [ check-for-functional-changes ] + if: needs.check-for-functional-changes.outputs.status == 'success' + env: + PYPI_USERNAME: openfisca-bot + PYPI_PASSWORD: ${{ secrets.PYPI_PASSWORD }} + CIRCLE_TOKEN: ${{ secrets.CIRCLECI_V1_OPENFISCADOC_TOKEN }} # Personal API token created in CircleCI to grant full read and write permissions + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 # Fetch all the tags + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: 3.7.12 + - name: Cache build + id: restore-build + uses: actions/cache@v2 + with: + path: ${{ env.pythonLocation }} + key: build-${{ env.pythonLocation }}-${{ hashFiles('setup.py') }}-${{ github.sha }} + - name: Cache release + id: restore-release + uses: actions/cache@v2 + with: + path: dist + key: release-${{ env.pythonLocation }}-${{ hashFiles('setup.py') }}-${{ github.sha }} + - name: Upload a Python package to PyPi + run: twine upload dist/* --username $PYPI_USERNAME --password $PYPI_PASSWORD + - name: Publish a git tag + run: "${GITHUB_WORKSPACE}/.github/publish-git-tag.sh" + - name: Update doc + run: | + curl -X POST --header "Content-Type: application/json" -d '{"branch":"master"}' https://circleci.com/api/v1.1/project/github/openfisca/openfisca-doc/build?circle-token=${{ secrets.CIRCLECI_V1_OPENFISCADOC_TOKEN }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 27d95ddaa3..c0bed218ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +### 35.7.2 [#1057](https://github.com/openfisca/openfisca-core/pull/1057) + +#### Technical changes + +- Switch CI provider from CircleCI to GitHub Actions + ### 35.7.1 [#1075](https://github.com/openfisca/openfisca-core/pull/1075) #### Bug fix diff --git a/README.md b/README.md index 7f253c9114..7f8b79c150 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,6 @@ [![Twitter](https://img.shields.io/badge/twitter-follow%20us!-9cf.svg?style=flat)](https://twitter.com/intent/follow?screen_name=openfisca) [![Slack](https://img.shields.io/badge/slack-join%20us!-blueviolet.svg?style=flat)](mailto:contact%40openfisca.org?subject=Join%20you%20on%20Slack%20%7C%20Nous%20rejoindre%20sur%20Slack&body=%5BEnglish%20version%20below%5D%0A%0ABonjour%2C%0A%0AVotre%C2%A0pr%C3%A9sence%C2%A0ici%C2%A0nous%C2%A0ravit%C2%A0!%20%F0%9F%98%83%0A%0ARacontez-nous%20un%20peu%20de%20vous%2C%20et%20du%20pourquoi%20de%20votre%20int%C3%A9r%C3%AAt%20de%20rejoindre%20la%20communaut%C3%A9%20OpenFisca%20sur%20Slack.%0A%0AAh%C2%A0!%20Et%20si%20vous%20pouviez%20remplir%20ce%20petit%20questionnaire%2C%20%C3%A7a%20serait%20encore%20mieux%C2%A0!%0Ahttps%3A%2F%2Fgoo.gl%2Fforms%2F45M0VR1TYKD1RGzX2%0A%0AN%E2%80%99oubliez%20pas%20de%20nous%20envoyer%20cet%20email%C2%A0!%20Sinon%2C%20on%20ne%20pourra%20pas%20vous%20contacter%20ni%20vous%20inviter%20sur%20Slack.%0A%0AAmiti%C3%A9%2C%0AL%E2%80%99%C3%A9quipe%20OpenFisca%0A%0A%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%20ENGLISH%20VERSION%20%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%0A%0AHi%2C%20%0A%0AWe're%20glad%20to%20see%20you%20here!%20%F0%9F%98%83%0A%0APlease%20tell%20us%20a%20bit%20about%20you%20and%20why%20you%20want%20to%20join%20the%20OpenFisca%20community%20on%20Slack.%0A%0AAlso%2C%20if%20you%20can%20fill%20out%20this%20short%20survey%2C%20even%20better!%0Ahttps%3A%2F%2Fgoo.gl%2Fforms%2FsOg8K1abhhm441LG2.%0A%0ADon't%20forget%20to%20send%20us%20this%20email!%20Otherwise%20we%20won't%20be%20able%20to%20contact%20you%20back%2C%20nor%20invite%20you%20on%20Slack.%0A%0ACheers%2C%0AThe%20OpenFisca%20Team) -[![CircleCI](https://img.shields.io/circleci/project/github/openfisca/openfisca-core/master.svg?style=flat)](https://circleci.com/gh/openfisca/openfisca-core) [![Coveralls](https://img.shields.io/coveralls/github/openfisca/openfisca-core/master.svg?style=flat)](https://coveralls.io/github/openfisca/openfisca-core?branch=master) [![Python](https://img.shields.io/pypi/pyversions/openfisca-core.svg)](https://pypi.python.org/pypi/openfisca-core) [![PyPi](https://img.shields.io/pypi/v/openfisca-core.svg?style=flat)](https://pypi.python.org/pypi/openfisca-core) @@ -158,7 +157,7 @@ rm -rf doc 7. Finally, open a pull request both in [core](https://github.com/openfisca/openfisca-core/compare/master...fix-doc) and in the [doc](https://github.com/openfisca/openfisca-doc/compare/master...fix-doc). -[CircleCI](.circleci/config.yml) will automatically try to build the documentation from the same branch in both core and the doc (in our example "fix-doc") so we can integrate first our changes to core, and then our changes to the doc. +Continuous integration will automatically try to build the documentation from the same branch in both core and the doc (in our example "fix-doc") so we can integrate first our changes to Core, and then our changes to the doc. If no changes were needed to the doc, then your changes to core will be verified against the production version of the doc. diff --git a/setup.py b/setup.py index 36e30a751e..0575d56776 100644 --- a/setup.py +++ b/setup.py @@ -41,7 +41,7 @@ setup( name = 'OpenFisca-Core', - version = '35.7.1', + version = '35.7.2', author = 'OpenFisca Team', author_email = 'contact@openfisca.org', classifiers = [