Skip to content

Commit

Permalink
Publication vers Conda
Browse files Browse the repository at this point in the history
Merge pull request #1786 from openfisca/publish-to-conda
  • Loading branch information
benoit-cty authored Feb 3, 2022
2 parents 06df8a5 + ddac27c commit 94680fc
Show file tree
Hide file tree
Showing 8 changed files with 313 additions and 35 deletions.
42 changes: 42 additions & 0 deletions .conda/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Publication vers Anaconda

Ce readme décrit la partie publication vers conda, pour utiliser le paquet conda résultant, voir [le readme principal](https://github.com/openfisca/openfisca-france/tree/publish-to-conda#installez-un-environnement-virtuel-avec-conda).

Pour envoyer un paquet vers conda il faut obligatoirement un fichier `meta.yaml` qui décrit le package.

Nous avons fait le choix d'utiliser le paquet PyPi comme source du paquet Conda, pour s'assurer que l'on publie bien la même chose sur les deux plateformes.

L'upload automatique est fait de la façon suivante par la CI uniquement si l'étape de livraison sur PyPi s'est bien déroulée :
- Installation de Miniconda.
- Récupération par le script `.github/get_pypi_info.py` des informations du package sur PyPi.
- Ecriture de ces informations par ce même script dans le fichier `.conda/meta.yaml`.
- Exécution de `conda build` pour construire et publier le paquet conformément au fichier `.conda/meta.yaml`. Cette étape nécessite la variable de CI ANACONDA_TOKEN.

Pour valider que tout a fonctionné, une étape `test-on-windows` a été ajoutée en fin de CI. Cette étape récupère le paquet conda sur une machine Windows et exécute les tests.

**A noter** : Le paquet OpenFisca-France est aussi publié sur `conda-forge`, pour cela voir [le feedstock](https://github.com/openfisca/openfisca-france-feedstock/tree/master/recipe)

C'est le channel `conda-forge` qui est le channel stable à conseiller aux utilisateurs. Le channel `openfisca` reçoit les derniers paquets de façon automatique.

## Etapes préparatoires pour arriver à cette automatisation

- Création d'un compte sur https://anaconda.org.
- Création d'un token sur https://anaconda.org/openfisca/settings/access avec le droit _Allow write access to the API site_. Attention il expire le 2023/01/13.

- Mis en place du token dans GitHub Action sous le nom de variable ANACONDA_TOKEN.

### Publication manuelle du package

Les étapes suivantes peuvent être réalisées sous Windows pour tester la publication :

_Cela fonctionne aussi sous macOS et Linux, à condition d'adapter les chemins._

- Editer `.conda/meta.yaml` pour vérifier son contenu.
- Installer [MiniConda](https://docs.conda.io/projects/conda/en/latest/user-guide/install/windows.html) si vous n'avez pas déjà [AnaConda](https://www.anaconda.com/products/individual).
- Puis dans le terminal saisissez les instructions suivantes :
- `conda install -c anaconda conda-build anaconda-client` Pour installer les outils indispensable.
- `conda build --croot c:\temp .conda` L'option `--croot ` est nécessaire sous Windows à cause des chemins trop long.
- `conda install -c anaconda anaconda-client` Pour installer l'outil en ligne de commande.
- `anaconda login` Pour vous connecter avec le compte _openfisca_, voir le Keepass OpenFisca.
- `anaconda upload c:\temp\noarch\openfisca-france-<VERSION>-py_0.tar.bz2` pour publier le package.
- Vérifier que tout c'est bien passé sur https://anaconda.org/search?q=openfisca.
78 changes: 78 additions & 0 deletions .conda/meta.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
###############################################################################
## Fichier de description du package pour Anaconda.org
## Attention, les chaines PYPI_VERSION, PYPI_URL et PYPI_SHA256 sont remplacées
## par la CI, il faut les conserver.
###############################################################################

{% set name = "OpenFisca-France" %}
{% set version = "PYPI_VERSION" %}

package:
name: {{ name|lower }}
version: {{ version }}

source:
url: PYPI_URL
sha256: PYPI_SHA256

build:
noarch: python
number: 0
script: "{{ PYTHON }} -m pip install . -vv"

requirements:
host:
- python
- pip
run:
- python >=3.6,<4.0
- OpenFisca-Core >=35.2.0,<36.0


test:
imports:
- openfisca_france
requires:
- pip
commands:
- pip check

outputs:
- name: openfisca-france

- name: openfisca-france-scipy
build:
noarch: python
requirements:
host:
- python
run:
- scipy >=0.17
- {{ pin_subpackage('openfisca-france', exact=True) }}

- name: openfisca-france-dev
build:
noarch: python
requirements:
host:
- python
run:
- autopep8 ==1.5.7
- flake8 >=3.8.0,<3.10.0
- flake8-print
- pytest >=5.0.0, <7.0.0
- requests >=2.8
- yamllint >=1.11.1,<1.27
- {{ pin_subpackage('openfisca-france-scipy', exact=True) }}

about:
home: https://fr.openfisca.org/
license_family: AGPL
license: AGPL-3.0-only
license_file: LICENSE.AGPL.txt
summary: "French tax and benefit system for OpenFisca"
description: |
OpenFisca is a versatile microsimulation free software.
This repository contains the OpenFisca model of the French tax and benefit system.
doc_url: https://fr.openfisca.org/
dev_url: https://github.com/openfisca/openfisca-france/
47 changes: 47 additions & 0 deletions .github/get_pypi_info.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import argparse
import requests


def get_info(package_name: str = "") -> dict:
"""
Get minimal informations needed by .conda/meta.yaml from PyPi JSON API.
::package_name:: Name of package to get infos from.
::return:: A dict with last_version, url and sha256
"""
if package_name == "":
raise ValueError("Package name not provided.")
resp = requests.get(f"https://pypi.org/pypi/{package_name}/json").json()
version = resp["info"]["version"]
for v in resp["releases"][version]:
if v["packagetype"] == "sdist": # for .tag.gz
return {
"last_version": version,
"url": v["url"],
"sha256": v["digests"]["sha256"]
}


def replace_in_file(filepath: str, info: dict):
'''
::filepath:: Path to meta.yaml, with filename
::info:: Dict with information to populate
'''
with open(filepath, "rt") as fin:
meta = fin.read()
# Replace with info from PyPi
meta = meta.replace("PYPI_VERSION", info["last_version"])
meta = meta.replace("PYPI_URL", info["url"])
meta = meta.replace("PYPI_SHA256", info["sha256"])
with open(filepath, "wt") as fout:
fout.write(meta)
print(f"File {filepath} has been updated with informations from PyPi.") # noqa: T001


if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument("-p", "--package", type=str, default="", required=True, help="The name of the package")
parser.add_argument("-f", "--filename", type=str, default=".conda/meta.yaml", help="Path to meta.yaml, with filename")
args = parser.parse_args()
info = get_info(args.package)
print("Information of the last published PyPi package :", info) # noqa: T001
replace_in_file(args.filename, info)
7 changes: 4 additions & 3 deletions .github/workflows/validate_yaml.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
name: Validate YAML

on:
- pull_request
- push
- workflow_dispatch
push:
workflow_dispatch:
pull_request:
types: [opened, reopened]

jobs:
validate_yaml:
Expand Down
Loading

0 comments on commit 94680fc

Please sign in to comment.