{"id":34060455,"url":"https://github.com/ubffm/ojs_updater","last_synced_at":"2026-03-17T16:35:45.730Z","repository":{"id":57448468,"uuid":"391881366","full_name":"ubffm/ojs_updater","owner":"ubffm","description":"Commanline tool to update a single OJS installation to a newer version","archived":false,"fork":false,"pushed_at":"2025-05-28T08:33:53.000Z","size":57,"stargazers_count":10,"open_issues_count":1,"forks_count":5,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-12-16T00:27:32.942Z","etag":null,"topics":["ojs","openaccess","openjournalsystems","publishing"],"latest_commit_sha":null,"homepage":"https://labs.ub.uni-frankfurt.de/post/upgrading-ojs-with-the-ojs-updater/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ubffm.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2021-08-02T09:06:27.000Z","updated_at":"2025-06-13T14:26:31.000Z","dependencies_parsed_at":"2023-11-21T16:44:33.233Z","dependency_job_id":null,"html_url":"https://github.com/ubffm/ojs_updater","commit_stats":{"total_commits":9,"total_committers":3,"mean_commits":3.0,"dds":0.4444444444444444,"last_synced_commit":"a1024743660762ce6195c62f130f2c860af80329"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ubffm/ojs_updater","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ubffm%2Fojs_updater","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ubffm%2Fojs_updater/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ubffm%2Fojs_updater/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ubffm%2Fojs_updater/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ubffm","download_url":"https://codeload.github.com/ubffm/ojs_updater/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ubffm%2Fojs_updater/sbom","scorecard":{"id":906359,"data":{"date":"2025-08-11","repo":{"name":"github.com/ubffm/ojs_updater","commit":"4026404ed2dfeaff6263629ed7f645796d75b503"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.3,"checks":[{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Code-Review","score":0,"reason":"Found 0/16 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Maintained","score":2,"reason":"3 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 2","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Mozilla Public License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}}]},"last_synced_at":"2025-08-24T17:30:22.556Z","repository_id":57448468,"created_at":"2025-08-24T17:30:22.556Z","updated_at":"2025-08-24T17:30:22.556Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30627197,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-17T14:16:03.965Z","status":"ssl_error","status_checked_at":"2026-03-17T14:16:03.380Z","response_time":56,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["ojs","openaccess","openjournalsystems","publishing"],"created_at":"2025-12-14T04:06:02.099Z","updated_at":"2026-03-17T16:35:45.723Z","avatar_url":"https://github.com/ubffm.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# OJS-Updater\n\n## An OJS Update CLI-Script\n\nThis tool updates a single instance of an Open Journal System (OJS) on a server to a newer version. It wraps up all\nthe individual steps that usually have to be carried out manually in one single command and takes additional measures to\nsafely fall back. Thus, it is especially intended for OJS hosting setups which employ a\none-installation-per-journal policy. Please also refer to the upgrade guide for OJS by PKP: https://docs.pkp.sfu.ca/dev/upgrade-guide/en/\n\nBefore updating, the tool will automatically backup your OJS instance folder, the submission folder, and the database.\nIf anything in the updating process goes wrong, the tool will reset everything to its previous state.\n\n**CAUTION:** The resetting feature was yet only tested with our own servers and settings. We highly recommend doing a\nbackup yourself at least for the first time you run the tool!\n\nWe also created a more [extensive documentation](https://labs.ub.uni-frankfurt.de/post/930/) on the preparation and the workflow, if needed.\n\n### Features\n\n* Automatic update to the highest (locally available) OJS version\n* Automatic database and journal backup before the update\n* Automatic rollback when errors occur in the update process\n* Backup function can be called separately from updating\n* Checks permissions of relevant folders and free disk space before updating\n* Migration of custom files, folders, and plugins to the updated journal directory - configurable per journal\n\n### Prerequisites\n\n* A Linux (other *nix systems have not been tested; Windows Servers are currently NOT supported!)\n* MySQL/MariaDB (support for other databases is currently not implemented)\n* Python 3.6+ \n* A running installation of OJS\n* [lxml](https://pypi.org/project/lxml/) (Optional)\n\nOJS-Updater is being tested on all currently maintained python versions (3.7+) and python 3.6 on Linux.\n\n### Installation\n\nInstallation via _pipx_ is recommended:\n\n```\npipx install ojs_updater\n```\n\nAlternatively, simply clone the repository and install it on your server:\n\n```\ngit clone https://github.com/ubffm/ojs-updater.git\ncd ojs-updater\npip install .\n```\n\nNow you should be able to simply run to get the help message:\n\n`ojs_updater`\n\n### Preparation\n\nBefore running the OJS-Updater, all folders that are configured in the `ojs_updater_settings.yml` have to exist.\n\nThe OJS-Updater searches for OJS update folders (i.e. folder with new OJS versions to be applied) in the directory given in the `ojs_updater_settings.yml` with the key `ojs_version_folder`. If multiple OJS update folders exists, the OJS update folder with the highest OJS version will be chosen by default. To fill this folder, simply download **and extract** the desired OJS version from the [PKP OJS Download Page](https://pkp.sfu.ca/ojs/ojs_download/). As described before, OJS update folders containing newer OJS versions can simply be put in the same folder. The OJS version is determined by the `version.xml` file within the respective OJS update folder.\n\nIt is suggested, that you setup a folder structure like this:\n```shell\n$ mkdir -p ojs/{versions,backup/{db,htdocs}}\n$ chown -R \u003cwebserver-user\u003e:\u003cwebserver-group\u003e ojs\n```\nExample structure:\n```\nojs            \n├── backup    \u003c-- ojs_backup_folder\n│   ├── db    \u003c-- ojs_backup_db\n│   └── www   \u003c-- ojs_backup_www\n└── versions  \u003c-- ojs_version_folder\n```\n\nThe script makes, at times, rather specific assumptions in regard to folder structure and permissions. We suggest, that you run the script from the aforementioned folder (e.g. /usr/local/ojs/). Also, in order for the script to properly work, the folder that contains the journal instances has to have the permissions specified in the config file. Therefore, we recommend a folder structure like this:\n\nExample structure:\n```\n/srv/www/htdocs            \n└── journals       \u003c-- Owner/group set to \u003cwebserver_user\u003e:\u003cwebserver_group\u003e \n    ├── journal_1  \n    ├── ...\n    └── journal_n  \n```\n\n### Configuration\n\nSince every server and OJS provider philosophy may be different, the OJS-Updater tries to acknowledge this by providing you\na `ojs_updater_settings.yml`, where you have to configure all necessary OJS-folders and additional parameters. A subset of these options is also offered as CLI parameters, which take precedence over config file parameters.\n\nIn the `ojs_updater_settings.yml.example`, you will find descriptions of each parameter that you can set.\n\n### Usage\n\n**CAUTION!** Be aware that if something in the update process goes wrong, in the worst case, your OJS instance is not\nworking anymore! The OJS-Updater tries its very best to clean up, if something goes wrong while the updating process,\nbut it is not guaranteed!\n\nFurthermore, although the OJS-Updater does all the updating process for you, that does NOT mean that it resolves e.g. differences in updated templates (disregarding if the templates were modified locally or if they come with the updated OJS version). Hence, there may be post-update work to do that can be done only manually!\n\n**The tool has to be run as root.** Only as root, you can run\n\n```\nojs_updater /ojs-dir/ojs-instance-folder/\n```\n\nHowever, not the whole update process is done with root privileges. The privileges are dropped soon after some system checking (read/write privileges) is done.\n\nYou can provide the tool with command-line arguments that can override parameters given in the `ojs_updater_settings.yml`. At least you have to provide the folder with the OJS instance to update.\n\n```\npositional arguments:\n  folder                Path to the OJS instance to be upgraded.\n\noptional arguments:\n  -h, --help            show this help message and exit\n  --permissive          If set, root privileges are not dropped (no warranty;\n                        use with caution).\n  --debug               Enable debug mode.\n  --force               Enforce upgrade, even if the target OJS version is\n                        equal. This skips all version number checks.\n  -o OWNER, --owner OWNER\n                        After dropping root privileges, run as this user.\n                        (This should usually be the web server user).\n  -g GROUP, --group GROUP\n                        After dropping root privileges, run with this group.\n                        (This should usually be the web server group).\n  --backup              Run only (!) the backup routine.\n```\n\n## Tests\n\nWe recommend running tests before first usage of the OJS-Updater. This ensures that all method calls are working as intended on your system.\n\nTo run tests, you have to install the `requirements-dev.txt` into your virtual environment:\n\n```shell\npip install -r requirements-dev.txt\n```\n\nSubsequently, you can simply call:\n\n```shell\npytest .\n```\n\n### Version compatibility\n\nIn addition to the tests, the OJS-Updater comes with a configuration file for [tox](https://tox.readthedocs.io), which makes it possible to\neasily test the software with several python versions simultaneously. \n```shell\ntox\n```\n\nPlease be aware that the tested python versions have to be compiled with `libffi-dev` (python 3.7+). Hence, if you get an error while running `tox` that says something like:\n\n```\nModuleNotFoundError: No module named '_ctypes'\n```\n\nyour Python version is missing the `libffi-dev`. \n\nOn Ubuntu, you can simply run `sudo apt-get install libffi-dev`. \n\nWhen using `pyenv`, you need to re-install the problematic Python versions with e.g. `pyenv install 3.10` after you installed `libffi-dev`.\n\n## Contributing\n\nIf you want to contribute to the project, please search for an issue you would like to work on and make a Pull Request.\nIf you find a bug or have a feature request, please open an issue.\n\n\n## Acknowledgment\n\nThis is a project created and maintained by [BIOfid](https://www.biofid.de/en/) and \nthe [Specialised Information Service Linguistic](https://www.linguistik.de/en/).\nBoth are projects funded by the German Research Foundation (DFG) and located at the [University Library J. C. Senckenberg](https://www.ub.uni-frankfurt.de/).\n\nFor further details, please refer to:\n\n- BIOfid, DFG project identifier [326061700](https://gepris.dfg.de/gepris/projekt/326061700?language=en)\n- Fachinformationsdienst Linguistik, DFG project identifier [326024153](https://gepris.dfg.de/gepris/projekt/326024153?language=en)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fubffm%2Fojs_updater","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fubffm%2Fojs_updater","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fubffm%2Fojs_updater/lists"}