{"id":32139070,"url":"https://github.com/citation-file-format/cffconvert","last_synced_at":"2025-12-11T22:46:23.278Z","repository":{"id":38375020,"uuid":"116825049","full_name":"citation-file-format/cffconvert","owner":"citation-file-format","description":"Command line program to validate and convert CITATION.cff files.","archived":false,"fork":false,"pushed_at":"2025-10-01T21:04:47.000Z","size":2396,"stargazers_count":131,"open_issues_count":48,"forks_count":33,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-12-07T08:45:27.229Z","etag":null,"topics":["attribution","bibtex","cff","citation","citation-files","codemeta","endnote","ris","schemaorg","software-sustainability","zenodo"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/citation-file-format.png","metadata":{"files":{"readme":"README.dev.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":"CITATION.cff","codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":".zenodo.json","notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2018-01-09T14:16:28.000Z","updated_at":"2025-12-02T06:56:45.000Z","dependencies_parsed_at":"2023-07-14T17:08:59.934Z","dependency_job_id":"ad1e8c67-d665-49d9-8b95-b5f4b3bdf6f6","html_url":"https://github.com/citation-file-format/cffconvert","commit_stats":null,"previous_names":["citation-file-format/cffconvert","citation-file-format/cff-converter-python"],"tags_count":18,"template":false,"template_full_name":null,"purl":"pkg:github/citation-file-format/cffconvert","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/citation-file-format%2Fcffconvert","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/citation-file-format%2Fcffconvert/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/citation-file-format%2Fcffconvert/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/citation-file-format%2Fcffconvert/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/citation-file-format","download_url":"https://codeload.github.com/citation-file-format/cffconvert/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/citation-file-format%2Fcffconvert/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":27605927,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-12-08T02:00:07.111Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["attribution","bibtex","cff","citation","citation-files","codemeta","endnote","ris","schemaorg","software-sustainability","zenodo"],"created_at":"2025-10-21T05:17:47.547Z","updated_at":"2025-12-11T22:46:23.272Z","avatar_url":"https://github.com/citation-file-format.png","language":"Python","readme":"# Documentation for developers\n\n## Installing\n\n```shell\n# get a copy of the cffconvert software\ngit clone https://github.com/citation-file-format/cffconvert.git\n\n# change directory into cffconvert\ncd cffconvert\n\n# make a virtual environment named venv\npython3 -m venv venv\n\n# activate the virtual environment\nsource venv/bin/activate\n\n# upgrade pip, wheel, setuptools\npip install --upgrade pip wheel setuptools\n\n# install cffconvert  in editable mode\npip install --editable .\n```\n\nThere are various sets of dependencies that you should install depending on the work you're planning to do.\n\n```shell\npip install --editable .[dev]\n```\n\n```shell\npip install --editable .[gcloud]\n```\n\n```shell\npip install --editable .[publishing]\n```\n\n```shell\npip install --editable .[testing]\n```\n\nYou can combine these into one command like so, e.g.:\n\n```shell\npip install --editable .[dev,testing]\n```\n\n## Testing\n\n```shell\n# (from the project root)\npip install --editable .[testing]\n\n# run all tests\npytest tests/\n\n# run tests for consistent versioning\npytest tests/test_consistent_versioning.py\n\n# run pytest on a subset of the files, e.g.\ncd tests/lib/cff_1_2_0/ \u0026\u0026 pytest .\n```\n\nTests pertaining to a specific exporter have been marked accordingly with one of the following markers (see also\n`pytest` configuration section in `pyproject.toml`):\n\n1. `apalike`\n2. `bibtex`\n3. `codemeta`\n4. `endnote`\n5. `ris`\n6. `schemaorg`\n7. `zenodo`\n\nAdditionally, there are markers for CLI tests and for library tests:\n\n1. `cli`\n2. `lib`\n\nYou can instruct `pytest` to run only the tests for one or some of these marked sets. As an example, if you want to run\nonly the tests related to exporting as Endnote, you should call `pytest` with the `-m` flag as follows:\n\n```shell\npytest -m endnote\n```\n\nMarkers can also be combined with `or` and `and` and `not`, e.g.\n\n```shell\npytest -m 'endnote and lib'\npytest -m 'cli and not zenodo'\npytest -m 'schemaorg or codemeta'\n# etc\n```\n\n## Linting\n\nRunning the linters requires that the development tools have been installed:\n\n```shell\npip install --editable .[dev]\n```\n\nSorting Python import lines with '`isort`' (https://pycqa.github.io/isort/):\n\n```shell\n# recursively check import style for the cffconvert module only\nisort --check-only src/cffconvert\n\n# recursively check import style for the cffconvert module only and show\n# any proposed changes as a diff\nisort --check-only --diff src/cffconvert\n\n# recursively fix import style for the cffconvert module only\nisort src/cffconvert\n```\n\nLinting the code base by running a variety of other tools via '`prospector`' (https://github.com/landscapeio/prospector):\n\n```shell\n# linter\nprospector\n```\n\nAssessing the package metadata using '`pyroma`' (https://github.com/regebro/pyroma):\n\n```shell\n# from the project root\npyroma .\n```\n\nLinting the code base using '`ruff`' (https://github.com/astral-sh/ruff):\n\n```shell\nruff check path/to/code/\n```\n\nThe linting tools are also usable via [`pre-commit`](https://pre-commit.com/):\n\n```shell\n# Run all tools\npre-commit run --all-files\n\n# Run a specific tool, see .pre-commit-config.yaml for their IDs\npre-commit run --all-files \u003cID of the task\u003e\n```\n\nAlternatively, the linting tools can be set up to run automatically whenever you issue a `git commit` command, as\nfollows:\n \n```shell\npre-commit install\n```\n\n## Construction of author keys\n\nThere are various source keys in CFF that can be used to convert to a target format. The code uses a pattern of first\nidentifiying what information is present, then summarizing this as a key, then using that key to retrieve a method which \nis tailored only to that specific combination of source keys. As an example of this mapping, see the setup in\nhttps://github.com/citation-file-format/cffconvert/blob/3.0.0a0/cffconvert/behavior_shared/schemaorg_author_shared.py\n\nSource keys:\n\n1. `authors[i].given-names`\n2. `authors[i].family-names` (including name particle and suffix)\n3. `authors[i].alias`\n4. `authors[i].name`\n5. `authors[i].affiliation`\n6. `authors[i].orcid`\n7. `authors[i].email`\n\nThe table below lists how the key name is constructed based what information was provided in the `CITATION.cff` file:\n\n| key          | has given name | has family name | has alias | has name | has affiliation | has orcid | has email |\n|--------------|----------------|-----------------|-----------|----------|-----------------|-----------|-----------|\n| `GFANAOE`    | True           | True            | True      | True     | True            | True      | True      |\n| `GFANA_E`    | True           | True            | True      | True     | True            | False     | True      |\n| `GFAN_OE`    | True           | True            | True      | True     | False           | True      | True      |\n| `GFAN__E`    | True           | True            | True      | True     | False           | False     | True      |\n| `GFA_AOE`    | True           | True            | True      | False    | True            | True      | True      |\n| `GFA_A_E`    | True           | True            | True      | False    | True            | False     | True      |\n| `GFA__OE`    | True           | True            | True      | False    | False           | True      | True      |\n| `GFA___E`    | True           | True            | True      | False    | False           | False     | True      |\n| `GF_NAOE`    | True           | True            | False     | True     | True            | True      | True      |\n| `GF_NA_E`    | True           | True            | False     | True     | True            | False     | True      |\n| `GF_N_OE`    | True           | True            | False     | True     | False           | True      | True      |\n| `GF_N__E`    | True           | True            | False     | True     | False           | False     | True      |\n| `GF__AOE`    | True           | True            | False     | False    | True            | True      | True      |\n| `GF__A_E`    | True           | True            | False     | False    | True            | False     | True      |\n| `GF___OE`    | True           | True            | False     | False    | False           | True      | True      |\n| `GF____E`    | True           | True            | False     | False    | False           | False     | True      |\n| `G_ANAOE`    | True           | False           | True      | True     | True            | True      | True      |\n| `G_ANA_E`    | True           | False           | True      | True     | True            | False     | True      |\n| `G_AN_OE`    | True           | False           | True      | True     | False           | True      | True      |\n| `G_AN__E`    | True           | False           | True      | True     | False           | False     | True      |\n| `G_A_AOE`    | True           | False           | True      | False    | True            | True      | True      |\n| `G_A_A_E`    | True           | False           | True      | False    | True            | False     | True      |\n| `G_A__OE`    | True           | False           | True      | False    | False           | True      | True      |\n| `G_A___E`    | True           | False           | True      | False    | False           | False     | True      |\n| `G__NAOE`    | True           | False           | False     | True     | True            | True      | True      |\n| `G__NA_E`    | True           | False           | False     | True     | True            | False     | True      |\n| `G__N_OE`    | True           | False           | False     | True     | False           | True      | True      |\n| `G__N__E`    | True           | False           | False     | True     | False           | False     | True      |\n| `G___AOE`    | True           | False           | False     | False    | True            | True      | True      |\n| `G___A_E`    | True           | False           | False     | False    | True            | False     | True      |\n| `G____OE`    | True           | False           | False     | False    | False           | True      | True      |\n| `G_____E`    | True           | False           | False     | False    | False           | False     | True      |\n| `_FANAOE`    | False          | True            | True      | True     | True            | True      | True      |\n| `_FANA_E`    | False          | True            | True      | True     | True            | False     | True      |\n| `_FAN_OE`    | False          | True            | True      | True     | False           | True      | True      |\n| `_FAN__E`    | False          | True            | True      | True     | False           | False     | True      |\n| `_FA_AOE`    | False          | True            | True      | False    | True            | True      | True      |\n| `_FA_A_E`    | False          | True            | True      | False    | True            | False     | True      |\n| `_FA__OE`    | False          | True            | True      | False    | False           | True      | True      |\n| `_FA___E`    | False          | True            | True      | False    | False           | False     | True      |\n| `_F_NAOE`    | False          | True            | False     | True     | True            | True      | True      |\n| `_F_NA_E`    | False          | True            | False     | True     | True            | False     | True      |\n| `_F_N_OE`    | False          | True            | False     | True     | False           | True      | True      |\n| `_F_N__E`    | False          | True            | False     | True     | False           | False     | True      |\n| `_F__AOE`    | False          | True            | False     | False    | True            | True      | True      |\n| `_F__A_E`    | False          | True            | False     | False    | True            | False     | True      |\n| `_F___OE`    | False          | True            | False     | False    | False           | True      | True      |\n| `_F____E`    | False          | True            | False     | False    | False           | False     | True      |\n| `__ANAOE`    | False          | False           | True      | True     | True            | True      | True      |\n| `__ANA_E`    | False          | False           | True      | True     | True            | False     | True      |\n| `__AN_OE`    | False          | False           | True      | True     | False           | True      | True      |\n| `__AN__E`    | False          | False           | True      | True     | False           | False     | True      |\n| `__A_AOE`    | False          | False           | True      | False    | True            | True      | True      |\n| `__A_A_E`    | False          | False           | True      | False    | True            | False     | True      |\n| `__A__OE`    | False          | False           | True      | False    | False           | True      | True      |\n| `__A___E`    | False          | False           | True      | False    | False           | False     | True      |\n| `___NAOE`    | False          | False           | False     | True     | True            | True      | True      |\n| `___NA_E`    | False          | False           | False     | True     | True            | False     | True      |\n| `___N_OE`    | False          | False           | False     | True     | False           | True      | True      |\n| `___N__E`    | False          | False           | False     | True     | False           | False     | True      |\n| `____AOE`    | False          | False           | False     | False    | True            | True      | True      |\n| `____A_E`    | False          | False           | False     | False    | True            | False     | True      |\n| `_____OE`    | False          | False           | False     | False    | False           | True      | True      |\n| `______E`    | False          | False           | False     | False    | False           | False     | True      |\n| `GFANAO_`    | True           | True            | True      | True     | True            | True      | False     |\n| `GFANA__`    | True           | True            | True      | True     | True            | False     | False     |\n| `GFAN_O_`    | True           | True            | True      | True     | False           | True      | False     |\n| `GFAN___`    | True           | True            | True      | True     | False           | False     | False     |\n| `GFA_AO_`    | True           | True            | True      | False    | True            | True      | False     |\n| `GFA_A__`    | True           | True            | True      | False    | True            | False     | False     |\n| `GFA__O_`    | True           | True            | True      | False    | False           | True      | False     |\n| `GFA____`    | True           | True            | True      | False    | False           | False     | False     |\n| `GF_NAO_`    | True           | True            | False     | True     | True            | True      | False     |\n| `GF_NA__`    | True           | True            | False     | True     | True            | False     | False     |\n| `GF_N_O_`    | True           | True            | False     | True     | False           | True      | False     |\n| `GF_N___`    | True           | True            | False     | True     | False           | False     | False     |\n| `GF__AO_`    | True           | True            | False     | False    | True            | True      | False     |\n| `GF__A__`    | True           | True            | False     | False    | True            | False     | False     |\n| `GF___O_`    | True           | True            | False     | False    | False           | True      | False     |\n| `GF_____`    | True           | True            | False     | False    | False           | False     | False     |\n| `G_ANAO_`    | True           | False           | True      | True     | True            | True      | False     |\n| `G_ANA__`    | True           | False           | True      | True     | True            | False     | False     |\n| `G_AN_O_`    | True           | False           | True      | True     | False           | True      | False     |\n| `G_AN___`    | True           | False           | True      | True     | False           | False     | False     |\n| `G_A_AO_`    | True           | False           | True      | False    | True            | True      | False     |\n| `G_A_A__`    | True           | False           | True      | False    | True            | False     | False     |\n| `G_A__O_`    | True           | False           | True      | False    | False           | True      | False     |\n| `G_A____`    | True           | False           | True      | False    | False           | False     | False     |\n| `G__NAO_`    | True           | False           | False     | True     | True            | True      | False     |\n| `G__NA__`    | True           | False           | False     | True     | True            | False     | False     |\n| `G__N_O_`    | True           | False           | False     | True     | False           | True      | False     |\n| `G__N___`    | True           | False           | False     | True     | False           | False     | False     |\n| `G___AO_`    | True           | False           | False     | False    | True            | True      | False     |\n| `G___A__`    | True           | False           | False     | False    | True            | False     | False     |\n| `G____O_`    | True           | False           | False     | False    | False           | True      | False     |\n| `G______`    | True           | False           | False     | False    | False           | False     | False     |\n| `_FANAO_`    | False          | True            | True      | True     | True            | True      | False     |\n| `_FANA__`    | False          | True            | True      | True     | True            | False     | False     |\n| `_FAN_O_`    | False          | True            | True      | True     | False           | True      | False     |\n| `_FAN___`    | False          | True            | True      | True     | False           | False     | False     |\n| `_FA_AO_`    | False          | True            | True      | False    | True            | True      | False     |\n| `_FA_A__`    | False          | True            | True      | False    | True            | False     | False     |\n| `_FA__O_`    | False          | True            | True      | False    | False           | True      | False     |\n| `_FA____`    | False          | True            | True      | False    | False           | False     | False     |\n| `_F_NAO_`    | False          | True            | False     | True     | True            | True      | False     |\n| `_F_NA__`    | False          | True            | False     | True     | True            | False     | False     |\n| `_F_N_O_`    | False          | True            | False     | True     | False           | True      | False     |\n| `_F_N___`    | False          | True            | False     | True     | False           | False     | False     |\n| `_F__AO_`    | False          | True            | False     | False    | True            | True      | False     |\n| `_F__A__`    | False          | True            | False     | False    | True            | False     | False     |\n| `_F___O_`    | False          | True            | False     | False    | False           | True      | False     |\n| `_F_____`    | False          | True            | False     | False    | False           | False     | False     |\n| `__ANAO_`    | False          | False           | True      | True     | True            | True      | False     |\n| `__ANA__`    | False          | False           | True      | True     | True            | False     | False     |\n| `__AN_O_`    | False          | False           | True      | True     | False           | True      | False     |\n| `__AN___`    | False          | False           | True      | True     | False           | False     | False     |\n| `__A_AO_`    | False          | False           | True      | False    | True            | True      | False     |\n| `__A_A__`    | False          | False           | True      | False    | True            | False     | False     |\n| `__A__O_`    | False          | False           | True      | False    | False           | True      | False     |\n| `__A____`    | False          | False           | True      | False    | False           | False     | False     |\n| `___NAO_`    | False          | False           | False     | True     | True            | True      | False     |\n| `___NA__`    | False          | False           | False     | True     | True            | False     | False     |\n| `___N_O_`    | False          | False           | False     | True     | False           | True      | False     |\n| `___N___`    | False          | False           | False     | True     | False           | False     | False     |\n| `____AO_`    | False          | False           | False     | False    | True            | True      | False     |\n| `____A__`    | False          | False           | False     | False    | True            | False     | False     |\n| `_____O_`    | False          | False           | False     | False    | False           | True      | False     |\n| `_______`    | False          | False           | False     | False    | False           | False     | False     |\n\n## Construction of identifier keys\n\nThere are various source keys in CFF that can be used to convert to a target format. The code uses a pattern of first\nidentifiying what information is present, then summarizing this as a key, then using that key to retrieve a method which \nis tailored only to that specific combination of source keys. \n\nSource keys: \n\n- `doi`\n- `identifiers[i].type==doi`\n\nThe table below lists how the key name is constructed based what information was provided in the `CITATION.cff` file:\n\n| key  | has doi | has identifiers doi |\n|------|---------|---------------------|\n| `__` | False   | False               |\n| `_I` | False   | True                |\n| `D_` | True    | False               |\n| `DI` | True    | True                |\n\n## Construction of URL keys\n\nThere are various source keys in CFF that can be used to convert to a target format. The code uses a pattern of first\nidentifiying what information is present, then summarizing this as a key, then using that key to retrieve a method which \nis tailored only to that specific combination of source keys. \n\nSource keys:\n\n- `identifiers[i].type==url`\n- `repository`\n- `repository-artifact`\n- `repository-code`\n- `url`\n\nThe table below lists how the key name is constructed based what information was provided in the `CITATION.cff` file:\n\n| key     | has indentifiers url | has repository | has repository-artifact | has repository-code | has url |\n|---------|----------------------|----------------|-------------------------|---------------------|---------|\n| `IRACU` | True                 | True           | True                    | True                | True    |\n| `IRAC_` | True                 | True           | True                    | True                | False   |\n| `IRA_U` | True                 | True           | True                    | False               | True    |\n| `IRA__` | True                 | True           | True                    | False               | False   |\n| `IR_CU` | True                 | True           | False                   | True                | True    |\n| `IR_C_` | True                 | True           | False                   | True                | False   |\n| `IR__U` | True                 | True           | False                   | False               | True    |\n| `IR___` | True                 | True           | False                   | False               | False   |\n| `I_ACU` | True                 | False          | True                    | True                | True    |\n| `I_AC_` | True                 | False          | True                    | True                | False   |\n| `I_A_U` | True                 | False          | True                    | False               | True    |\n| `I_A__` | True                 | False          | True                    | False               | False   |\n| `I__CU` | True                 | False          | False                   | True                | True    |\n| `I__C_` | True                 | False          | False                   | True                | False   |\n| `I___U` | True                 | False          | False                   | False               | True    |\n| `I____` | True                 | False          | False                   | False               | False   |\n| `_RACU` | False                | True           | True                    | True                | True    |\n| `_RAC_` | False                | True           | True                    | True                | False   |\n| `_RA_U` | False                | True           | True                    | False               | True    |\n| `_RA__` | False                | True           | True                    | False               | False   |\n| `_R_CU` | False                | True           | False                   | True                | True    |\n| `_R_C_` | False                | True           | False                   | True                | False   |\n| `_R__U` | False                | True           | False                   | False               | True    |\n| `_R___` | False                | True           | False                   | False               | False   |\n| `__ACU` | False                | False          | True                    | True                | True    |\n| `__AC_` | False                | False          | True                    | True                | False   |\n| `__A_U` | False                | False          | True                    | False               | True    |\n| `__A__` | False                | False          | True                    | False               | False   |\n| `___CU` | False                | False          | False                   | True                | True    |\n| `___C_` | False                | False          | False                   | True                | False   |\n| `____U` | False                | False          | False                   | False               | True    |\n| `_____` | False                | False          | False                   | False               | False   |\n\n## For maintainers\n\n### Making a release\n\n\n1. make sure the release notes are up to date\n2. preparation\n\n    ```shell\n    # remove old cffconvert from your system if you have it\n    python3 -m pip uninstall cffconvert\n\n    # this next command should now return empty\n    which cffconvert\n\n    # install the package to user space, using no caching (can bring to light dependency problems)\n    python3 -m pip install --user --no-cache-dir .\n\n    # check if cffconvert works, e.g.\n    cffconvert --version\n    \n    # run the tests, make sure they pass\n    python3 -m pip pytest tests\n\n    # git push everything, merge into main as appropriate\n    ```\n    \n3. publishing on test instance of PyPI\n\n    ```shell\n    # verify that everything has been pushed and merged by testing as follows\n    cd $(mktemp -d --tmpdir cffconvert-release.XXXXXX)\n    git clone https://github.com/citation-file-format/cffconvert.git .\n    python3 -m venv venv\n    source venv/bin/activate\n    python3 -m pip install --upgrade pip wheel setuptools\n    python3 -m pip install --no-cache-dir .\n\n    # register with PyPI test instance https://test.pypi.org\n\n    # remove these directories if you have them\n    rm -rf dist\n    rm -rf cffconvert-egg.info\n    # make a source distribution:\n    python setup.py sdist\n    # make a wheel\n    python setup.py bdist_wheel \n    # install the 'upload to pypi/testpypi tool' aka twine\n    pip install .[publishing]\n    # upload the contents of the source distribution we just made (requires credentials for test.pypi.org)\n    twine upload --repository-url https://test.pypi.org/legacy/ dist/*\n    ```\n    \n4. Checking the package\n\n    Open another shell but keep the other one. We'll return to the first shell momentarily.\n    \n    Verify that there is a new version of the package on Test PyPI https://test.pypi.org/project/cffconvert/\n\n    ```shell\n    python3 -m pip -v install --user --no-cache-dir \\\n    --index-url https://test.pypi.org/simple/ \\\n    --extra-index-url https://pypi.org/simple cffconvert\n\n    # check that the package works as it should when installed from pypitest\n    ```\n5. FINAL STEP: upload to PyPI\n\n    Go back to the first shell, then (requires credentials for pypi.org)\n\n    ```shell\n    twine upload dist/*\n    ```\n6. Make the release on GitHub\n7. Go to Zenodo, log in to inspect the draft. Then click `Publish` to finalize it.\n\n### Building the docker image\n\n```shell\n# (requires 3.0.0a0 to be downloadable from PyPI)\ndocker build --tag cffconvert:3.0.0a0 .\ndocker build --tag cffconvert:latest .\n```\n\nSee if the Docker image works as expected:\n```shell\ndocker run --rm -v $PWD:/app cffconvert --validate\ndocker run --rm -v $PWD:/app cffconvert --version\ndocker run --rm -v $PWD:/app cffconvert\n# etc\n```\n\n### Publishing on DockerHub\n\nSee \u003chttps://docs.docker.com/docker-hub/repos/#pushing-a-docker-container-image-to-docker-hub\u003e for more information on publishing.\n\n```shell\n# log out of any dockerhub credentials\ndocker logout\n\n# log back in with username 'citationcff' credentials\ndocker login\n\n# re-tag existing images\ndocker tag cffconvert:3.0.0a0 citationcff/cffconvert:3.0.0a0\ndocker tag cffconvert:latest citationcff/cffconvert:latest\n\n# publish\ndocker push citationcff/cffconvert:3.0.0a0\ndocker push citationcff/cffconvert:latest\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcitation-file-format%2Fcffconvert","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcitation-file-format%2Fcffconvert","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcitation-file-format%2Fcffconvert/lists"}