diff --git a/CHANGELOG.md b/CHANGELOG.md
index af982895d2759775f936def741311d6b03b71078..2b4621070d1a58069f63a774e0678c648659ce82 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,7 +2,7 @@
 
 ## Unreleased
 
-[Please see the wiki-page](https://gitlab.opengeosys.org/ogs/ogs/-/wikis/6.5.1)
+[Please see the wiki-page](https://gitlab.opengeosys.org/ogs/ogs/-/wikis/Release-notes-6.5.1)
 
 ----
 
diff --git a/scripts/python/do-release.py b/scripts/python/do-release.py
new file mode 100644
index 0000000000000000000000000000000000000000..ebeeb3068a70722840c5ae04e4626e1eda700d5f
--- /dev/null
+++ b/scripts/python/do-release.py
@@ -0,0 +1,93 @@
+import re
+import subprocess
+from pathlib import Path
+
+
+def increment_ver(version):
+    version = version.split(".")
+    version[2] = str(int(version[2]) + 1)
+    return ".".join(version)
+
+
+script_path = Path(__file__).resolve()
+source_path = script_path.parent.parent.parent.resolve()
+
+git_describe = subprocess.run(
+    "git describe --tags --abbrev=0",
+    shell=True,
+    check=True,
+    text=True,
+    capture_output=True,
+)
+current_version = git_describe.stdout.splitlines()[0]
+
+# Modify changelog
+new_version = ""
+changelog_content = ""
+with (source_path / "CHANGELOG.md").open() as f:
+    changelog_content = f.read()
+
+new_version_match = re.search(
+    r"\[Please see the wiki-page\]\(.*Release-notes-([0-9]+\.[0-9]+\.[0-9]+)\)",
+    changelog_content,
+)
+new_version = new_version_match[1]
+
+print(f"New version: {new_version}")
+
+changelog_new_content = re.sub(
+    r"\[Please see the wiki-page\]\(.*Release-notes-[0-9]+\.[0-9]+\.[0-9]+\)\n\n----",
+    f"""[Please see the wiki-page](https://gitlab.opengeosys.org/ogs/ogs/-/wikis/Release-notes-{increment_ver(new_version)})
+
+## {new_version}
+
+[Changelog for OpenGeoSys {new_version}](https://gitlab.opengeosys.org/ogs/ogs/-/wikis/Release-notes-{new_version})
+
+----""",
+    changelog_content,
+)
+
+with (source_path / "CHANGELOG.md").open("w") as f:
+    f.write(changelog_new_content)
+
+# Create web release page
+subprocess.run(
+    f"hugo new releases/{new_version}.md",
+    shell=True,
+    check=True,
+    cwd=source_path / "web",
+)
+
+path = Path(source_path / "Documentation" / "mainpage.dox.in")
+text = path.read_text()
+text = text.replace(
+    " * The documentation for OGS releases can be found here:\n *\n",
+    f" * The documentation for OGS releases can be found here:\n *\n * - https://doxygen.opengeosys.org/v{new_version}\n",
+)
+path.write_text(text)
+
+path = Path(source_path / "README.md")
+text = path.read_text()
+text = text.replace(
+    f"https://doxygen.opengeosys.org/v{current_version}",
+    f"https://doxygen.opengeosys.org/v{new_version}",
+)
+path.write_text(text)
+
+new_version_dash = new_version.replace(".", "-")
+with (source_path / "scripts" / "doc" / "_redirects").open("a") as f:
+    f.write(
+        f"/v{new_version}/* https://ogs-doxygen-v{new_version_dash}.netlify.app/:splat 200!\n"
+    )
+
+print(
+    f"""Run the following and update CITATION.cff:
+
+git shortlog -sne {new_version}...{current_version}
+
+Then check diff and run:
+
+git commit -m "{new_version}"
+git tag -s -m "OpenGeoSys {new_version}" {new_version}
+git push --tags"""
+)
diff --git a/scripts/python/post-release.py b/scripts/python/post-release.py
new file mode 100644
index 0000000000000000000000000000000000000000..d34c20c20979391383447eed0a6ac1db74f9fecd
--- /dev/null
+++ b/scripts/python/post-release.py
@@ -0,0 +1,89 @@
+import re
+import subprocess
+from pathlib import Path
+
+script_path = Path(__file__).resolve()
+source_path = script_path.parent.parent.parent.resolve()
+
+r = subprocess.run(
+    "curl https://zenodo.org/doi/10.5281/zenodo.591265",
+    shell=True,
+    check=True,
+    capture_output=True,
+    text=True,
+)
+
+zenodo_record = re.search(r'"https://zenodo.org/records/([0-9]+)"', r.stdout).group(1)
+print(f"Zenodo record: {zenodo_record}")
+
+print("Issuing scan on Software Heritage ...")
+r = subprocess.run(
+    "curl -X POST https://archive.softwareheritage.org/api/1/origin/save/git/url/https://gitlab.opengeosys.org/ogs/ogs.git/",
+    shell=True,
+    check=True,
+)
+
+print("\n\nUpdating bibtex entry on website ...")
+r = subprocess.run(
+    f"curl https://zenodo.org/records/{zenodo_record}/export/bibtex",
+    shell=True,
+    check=True,
+    capture_output=True,
+    text=True,
+)
+
+bibtex = r.stdout
+
+m = re.search(r"\{([0-9]+\.[0-9]+\.[0-9]+)\}", bibtex)
+version = m.group(1)
+
+bibtex = re.sub(r"@software\{.*,\n", f"@software{{ogs:{version},\n", bibtex)
+
+publications_index_page = ""
+with (source_path / "web/content/publications/_index.md").open() as f:
+    publications_index_page = f.read()
+
+publications_index_page = re.sub(
+    r"(?s)```bibtex.*```", f"```bibtex\n{bibtex}\n```", publications_index_page
+)
+
+with (source_path / "web/content/publications/_index.md").open("w") as f:
+    f.write(publications_index_page)
+
+r = subprocess.run(
+    f"curl -s https://gitlab.opengeosys.org/api/v4/projects/120/releases/{version} | jq '.description'",
+    shell=True,
+    check=True,
+    text=True,
+    capture_output=True,
+)
+changelog = r.stdout[1:-2].replace(r"\n", "\n").replace(r"\"", '"')
+
+print(
+    f"""Add to CITATION.cff:
+
+```
+identifiers:
+    - type: doi
+      value: 10.5281/zenodo.{zenodo_record}
+      description: Zenodo DOI for {version}
+```
+
+Commit and push to master and create Zenodo release post:
+
+[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.{zenodo_record}.svg)](https://doi.org/10.5281/zenodo.{zenodo_record})
+
+We are happy to announce the release of **OpenGeoSys {version}**!
+
+## Links
+
+- [Release page on www.opengeosys.org](https://www.opengeosys.org/releases/{version}/)
+- [GitLab Release](https://gitlab.opengeosys.org/ogs/ogs/-/releases/{version})
+- [Zenodo Release](https://zenodo.org/record/{zenodo_record})
+- [PyPI Release](https://pypi.org/project/ogs/{version}/)
+
+## Highlights
+
+{changelog}
+"""
+)
diff --git a/web/archetypes/releases.md b/web/archetypes/releases.md
new file mode 100644
index 0000000000000000000000000000000000000000..1d29e6ce1174de898ded5bda6ad430793f4f632a
--- /dev/null
+++ b/web/archetypes/releases.md
@@ -0,0 +1,23 @@
++++
+date = "{{ .Date }}"
+title = "OpenGeoSys {{ .File.ContentBaseName }}"
+tag = "{{ .File.ContentBaseName }}"
+author = "Lars Bilke"
+release_date = "{{ .Date }}"
+
+[downloads]
+binary = [
+"Windows-10.0.22621-python-3.10.9-de-utils.zip",
+"Windows-10.0.22621-python-3.10.9-utils.zip",
+]
+container = [
+"serial.sif",
+"openmpi-4.0.5.sif",
+]
+pip = true
+note = """
+**Note:** When using Python bindings make sure to have Python installed on your system:
+
+- Windows: [Python 3.10.9](https://www.python.org/ftp/python/3.10.9/python-3.10.9-amd64.exe)
+"""
++++
diff --git a/web/content/docs/devguide/procedures/publish-a-release/index.md b/web/content/docs/devguide/procedures/publish-a-release/index.md
index c919100ea090b6289d4ecc1305ee6258e9225f7d..e640222840d7e3b71d264f48e8714f65f325d173 100644
--- a/web/content/docs/devguide/procedures/publish-a-release/index.md
+++ b/web/content/docs/devguide/procedures/publish-a-release/index.md
@@ -12,44 +12,14 @@ weight = 1080
 ## Publication procedure
 
 - Update merge request template (settings / merge_requests) to point to a new changelog wiki page
-- Update `CHANGELOG.md` to point to new GitLab release
-- Create new web release page with generated artifact names (frontmatter only!)
-- Add a link to the (upcoming) Doxygen documentation for this tag in `Documentation/mainpage.dox.in` (with `v`-prefix)
-- Update `[docs-release]`-link in `README.md` to the new tag (with `v`-prefix)
-- Add a redirect in `scripts/doc/_redirects`
-- Update `CITATION.cff` (Zenodo DOI will be added later)
-- Create a commit and push
-- Wait for CI to be green (except for URL checker which will fail)
-- Create a tag and push
-
-  ```bash
-  git tag -s -m "OpenGeoSys 6.5.0" 6.5.0
-  git push --tags
-  ```
-
+- Run `python scripts/python/do-release.py`
+- Update `CITATION.cff`, create a commit, tag and push (see script output)
 - A new release is automatically created on GitLab
   - Fill in the release notes from the Wiki
   - Convert MR ids to URLs: replace `!([0-9][0-9][0-9][0-9])` with `[!$1](https://gitlab.opengeosys.org/ogs/ogs/-/merge_requests/$1)` and `#([0-9][0-9][0-9][0-9])` with `[#$1](https://gitlab.opengeosys.org/ogs/ogs/-/issues/$1)`
 - Copy release binaries and container images from CI job to Azure OGS storage to a subdirectory containing the tag name at <https://ogsstorage.blob.core.windows.net/binaries/ogs6>
 - Create a release on GitHub mirror (`ufz/ogs`)
 - Check if a [Zenodo release](https://zenodo.org/account/settings/github/repository/ufz/ogs#) is automatically issued
-- Issue a scan on [Software Heritage Archive](https://archive.softwareheritage.org/save/)
-- Update `CITATION.cff` and `web/content/publications/_index.md` with new Zenodo DOI
-- Update `CITATION.cff` author list (`git shortlog -sne 6.4.3...6.4.2`) and corresponding bibtex-entry in publications web page
+- Run `python scripts/python/post-release.py` and commit and create a discourse announcement post
 - Update Zenodo entry with correct authors
-- Create bugfix branch
-  - Create new netlify site (in an empty directory)
-    <!-- vale off -->
-    - `netlify init`
-    - `# [ENTER]`
-    - `# ogs-doxygen-v[TAG (- separated instead of .)]`
-    <!-- vale on -->
-  - Create branch from `master` with name `v[TAG]` and push
-- Create a discourse announcement post
-  - DOI badge
-  - Software heritage badge
-  - Link to release page on opengeosys.org
-  - Link to GitLab release
-  - Link to Zenodo release
-  - Link to archive on Software Heritage
 - Set milestone on expired issues and merge requests
diff --git a/web/content/publications/_index.md b/web/content/publications/_index.md
index 227a03fb109d7d3331a019c083c623512b93a3ea..6e2cc2f10c38a991591ceae935e29abf57f28a4c 100644
--- a/web/content/publications/_index.md
+++ b/web/content/publications/_index.md
@@ -12,36 +12,37 @@ weight = 3
 ### Cite the software
 
 ```bibtex
-@software{ogs:6.4.3,
-  author       = {Lars Bilke and
-                  Thomas Fischer and
-                  Dmitri Naumov and
-                  Christoph Lehmann and
-                  Wenqing Wang and
-                  Renchao Lu and
-                  Boyan Meng and
-                  Karsten Rink and
-                  Norbert Grunwald and
-                  Jörg Buchwald and
-                  Christian Silbermann and
-                  Robert Habel and
-                  Linda Günther and
-                  Mostafa Mollaali and
-                  Tobias Meisel and
-                  Jakob Randow and
-                  Sophia Einspänner and
-                  Haibing Shao and
-                  Kata Kurgyis and
-                  Olaf Kolditz and
-                  Jaime Garibay},
+@software{ogs:6.5.0,
+  author       = {Naumov, Dmitri and
+                  Bilke, Lars and
+                  Fischer, Thomas and
+                  Lehmann, Christoph and
+                  Wang, Wenqing and
+                  Heinze, Julian and
+                  Chen, Chaofan and
+                  Silbermann, Christian and
+                  Kiszkurno, Feliks K. and
+                  Buchwald, Jörg and
+                  Rink, Karsten and
+                  Nagel, Thomas and
+                  Meisel, Tobias and
+                  Gerasimov, Tymofiy and
+                  Loer, Frieder and
+                  Mollaali, Mostafa and
+                  You, Tao and
+                  Brato Shil, Joy and
+                  Chen, Shuang and
+                  Selzer, Philipp and
+                  Shao, Haibing and
+                  Kessler, Kristof and
+                  Ghasabeh, Mehran},
   title        = {OpenGeoSys},
-  month        = apr,
-  year         = 2022,
-  note         = {{If you use this software, please cite it using these metadata.}},
+  month        = nov,
+  year         = 2023,
   publisher    = {Zenodo},
-  version      = {6.4.3},
-  doi          = {10.5281/zenodo.7092676},
-  url          = {https://doi.org/10.5281/zenodo.7092676}
+  version      = {6.5.0},
+  doi          = {10.5281/zenodo.2600042},
+  url          = {https://doi.org/10.5281/zenodo.2600042}
 }
 ```