diff --git a/.github/workflows/QCSchema.yml b/.github/workflows/QCSchema.yml new file mode 100644 index 000000000..434057082 --- /dev/null +++ b/.github/workflows/QCSchema.yml @@ -0,0 +1,94 @@ +name: QCSchema + +on: [pull_request] + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + conda-env: [base] + python-version: [3.7] + env: + PYVER: ${{ matrix.python-version }} + CONDA_ENV: ${{ matrix.conda-env }} + + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + path: qcel + + - name: Checkout schema repo + uses: actions/checkout@v2 + with: + repository: loriab/QCSchema + #repository: MolSSI/QCSchema + path: qcsk + #ref: py2json + ref: json_files + #ref: master + persist-credentials: false + fetch-depth: 0 + + - name: Python Setup + uses: actions/setup-python@v1 + with: + python-version: ${{ matrix.python-version }} + + - name: Create Environment + shell: bash + working-directory: ./qcel + run: | + eval "$(conda shell.bash hook)" && conda activate + python devtools/scripts/create_conda_env.py -n=test -p=$PYVER devtools/conda-envs/$CONDA_ENV.yaml + + - name: Install + shell: bash + working-directory: ./qcel + run: | + eval "$(conda shell.bash hook)" && conda activate test + python -m pip install . --no-deps + + - name: Environment Information + shell: bash + run: | + eval "$(conda shell.bash hook)" && conda activate test + conda list --show-channel-urls + + - name: QCSchema from QCElemental + shell: bash + working-directory: ./qcel + run: | + eval "$(conda shell.bash hook)" && conda activate test + make qcschema + ls -l qcschema + #cp -p qcschema/* ../qcsk/qcschema_json/ + cp -p qcschema/* ../qcsk/qcschema/ + # Note: `qcschema_json` is a folder in the py2json branch containing plain JSON files of the schema, + # rather than the python module of the current repo + + - name: Compare Schemas (generated vs. community) + shell: bash + working-directory: ./qcsk + run: | + git diff --color-words + pull_number=$(jq --raw-output .pull_request.number "$GITHUB_EVENT_PATH") + branch=qcel-${pull_number} + git checkout -b ${branch} + git remote -v + git config --local user.email "action@github.com" + git config --local user.name "GitHub Action" + git add -A + git commit -m "auto-generated from QCElemental" + echo "::set-env name=prbranch::${branch}" + + - name: Propose changes + uses: ad-m/github-push-action@master + with: + directory: ./qcsk + repository: loriab/QCSchema + #repository: MolSSI/QCSchema + branch: ${{ env.prbranch }} + github_token: ${{ secrets.QCSK_TOKEN }} + force: true diff --git a/Makefile b/Makefile index 2bcb96c1b..a60f7740e 100644 --- a/Makefile +++ b/Makefile @@ -43,6 +43,11 @@ data: cpu_data cpu_data: (cd raw_data/cpu_data; python build_cpu_data.py; mv cpu_data_blob.py ../../qcelemental/info/data/) +.PHONY: qcschema +qcschema: #install + mkdir -p qcschema + python -c "exec(\"import qcelemental as qcel\nfrom pathlib import Path\nfor md in qcel.models.qcschema_models():\n\tmfile = (Path('qcschema') / md.__name__).with_suffix('.json')\n\twith open(mfile, 'w') as fp:\n\t\tfp.write(md.schema_json(indent=4))\")" + .PHONY: clean clean: rm -rf `find . -name __pycache__` diff --git a/qcelemental/models/__init__.py b/qcelemental/models/__init__.py index f2c6102ce..82d128530 100644 --- a/qcelemental/models/__init__.py +++ b/qcelemental/models/__init__.py @@ -14,3 +14,19 @@ from .molecule import Molecule from .procedures import Optimization, OptimizationInput, OptimizationResult from .results import AtomicInput, AtomicResult, AtomicResultProperties, Result, ResultInput, ResultProperties + + +def qcschema_models(): + return [ + AtomicInput, + AtomicResult, + AtomicResultProperties, + basis.BasisCenter, + BasisSet, + basis.ElectronShell, + basis.ECPPotential, + common_models.Model, + Molecule, + Provenance, + results.WavefunctionProperties, + ] diff --git a/qcelemental/models/common_models.py b/qcelemental/models/common_models.py index 8c29df68f..d52d83470 100644 --- a/qcelemental/models/common_models.py +++ b/qcelemental/models/common_models.py @@ -20,7 +20,10 @@ class Provenance(ProtoModel): """ creator: str = Field(..., description="The creator of the object.") - version: Optional[str] = Field(None, description="The version of the creator.") + version: Optional[str] = Field( + None, + description="The version of the creator, which should be sortable by the very broad [PEP 440](https://www.python.org/dev/peps/pep-0440/).", + ) routine: Optional[str] = Field(None, description="The routine of the creator.") class Config(ProtoModel.Config):