From c45d6179b80da66bb411cb5eafe760b542aaafe6 Mon Sep 17 00:00:00 2001 From: ModeSevenIndustrialSolutions <93649628+ModeSevenIndustrialSolutions@users.noreply.github.com> Date: Mon, 26 Aug 2024 08:13:15 +0000 Subject: [PATCH 1/2] Chore: Update DevOps tooling from central repository [skip ci] Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .github/workflows/bootstrap.yaml | 4 +- .github/workflows/builds.yaml | 38 ++++++++----- .github/workflows/codeql.yml | 83 ++++++++++++++++++++++++++++ .github/workflows/notebooks.yaml | 84 +++++++++++++++++++++++++++++ .github/workflows/release.yaml | 37 ++++++------- .github/workflows/security.yaml | 28 ++++++---- .github/workflows/test-release.yaml | 6 +-- .github/workflows/testing.yaml | 19 ++++--- .gitignore | 15 +++--- .pre-commit-config.yaml | 55 ++++++++++--------- .prettierignore | 4 ++ scripts/bootstrap.sh | 20 +++++-- 12 files changed, 300 insertions(+), 93 deletions(-) create mode 100644 .github/workflows/codeql.yml create mode 100644 .github/workflows/notebooks.yaml create mode 100644 .prettierignore diff --git a/.github/workflows/bootstrap.yaml b/.github/workflows/bootstrap.yaml index 3e1df480..4886b3b4 100644 --- a/.github/workflows/bootstrap.yaml +++ b/.github/workflows/bootstrap.yaml @@ -212,8 +212,8 @@ jobs: git branch -D "$AUTOMATION_BRANCH" || : git checkout -b "$AUTOMATION_BRANCH" else - # The -B flag swaps branch and creates it if NOT present - git checkout -B "$AUTOMATION_BRANCH" + git fetch origin "$AUTOMATION_BRANCH" + git switch -c "$AUTOMATION_BRANCH" "origin/$AUTOMATION_BRANCH" fi # Only if NOT running in GitHub diff --git a/.github/workflows/builds.yaml b/.github/workflows/builds.yaml index 1c7f1714..a152862f 100644 --- a/.github/workflows/builds.yaml +++ b/.github/workflows/builds.yaml @@ -10,22 +10,34 @@ on: - "*" - "!update-devops-tooling" +env: + package-path: "dist/" + jobs: - parse-project-metadata: - name: "Determine Python versions" - # yamllint disable-line rule:line-length - uses: os-climate/devops-reusable-workflows/.github/workflows/pyproject-toml-fetch-matrix.yaml@main + get-python-versions: + name: "Validate Python project" + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.parse-project-metadata.outputs.python-matrix-versions }} + + steps: + - uses: actions/checkout@v4 - test-builds: - name: "Build: Python" - needs: [parse-project-metadata] + - name: "Parse: pyproject.toml" + id: parse-project-metadata + # yamllint disable-line rule:line-length + uses: os-climate/devops-reusable-workflows/.github/actions/python-versions-matrix@main + + builds: + name: "Python builds" + needs: [get-python-versions] runs-on: "ubuntu-latest" continue-on-error: true # Don't run when pull request is merged if: github.event.pull_request.merged == false strategy: fail-fast: false - matrix: ${{ fromJson(needs.parse-project-metadata.outputs.matrix) }} + matrix: ${{ fromJson(needs.get-python-versions.outputs.matrix) }} steps: - name: "Populate environment variables" @@ -81,8 +93,8 @@ jobs: python -m build fi - - name: "Validating Artefacts with Twine" - run: | - echo "Validating artefacts with: twine check dist/*" - pip install --upgrade twine - twine check dist/* + - name: "Validate Artefacts with Twine" + id: twine-check-artefacts + env: + package-path: ${{ env.package-path }} + uses: os-climate/devops-reusable-workflows/.github/actions/twine-check-artefacts@main diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 00000000..876fb543 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,83 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "🔐 CodeQL" + +on: + push: + branches: [ "main", "gh-pages", "master" ] + pull_request: + branches: [ "main", "gh-pages", "master" ] + schedule: + - cron: '39 20 * * 6' + +jobs: + analyze: + name: Analyze (${{ matrix.language }}) + # Runner size impacts CodeQL analysis time. To learn more, please see: + # - https://gh.io/recommended-hardware-resources-for-running-codeql + # - https://gh.io/supported-runners-and-hardware-resources + # - https://gh.io/using-larger-runners (GitHub.com only) + # Consider using larger runners or machines with greater resources for possible analysis time improvements. + runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }} + timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }} + permissions: + # required for all workflows + security-events: write + + # required to fetch internal or private CodeQL packs + packages: read + + # only required for workflows in private repositories + actions: read + contents: read + + strategy: + fail-fast: false + matrix: + include: + - language: python + build-mode: none + # CodeQL supports the following values keywords for 'language': + # 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift' + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: ${{ matrix.language }} + build-mode: ${{ matrix.build-mode }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + + # If the analyze step fails for one of the languages you are analyzing with + # "We were unable to automatically build your code", modify the matrix above + # to set the build mode to "manual" for that language. Then modify this step + # to build your code. + - if: matrix.build-mode == 'manual' + shell: bash + run: | + echo 'If you are using a "manual" build mode for one or more of the' \ + 'languages you are analyzing, replace this with the commands to build' \ + 'your code, for example:' + echo ' make bootstrap' + echo ' make release' + exit 1 + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 + with: + category: "/language:${{matrix.language}}" diff --git a/.github/workflows/notebooks.yaml b/.github/workflows/notebooks.yaml new file mode 100644 index 00000000..c10efca1 --- /dev/null +++ b/.github/workflows/notebooks.yaml @@ -0,0 +1,84 @@ +--- +# Run all notebooks on every push +name: "🗒️ Notebook Testing" + +# yamllint disable-line rule:truthy +on: + workflow_dispatch: + pull_request: + types: [opened, reopened, edited, synchronize] + +jobs: + + validate-notebook-tests: + name: "Check for notebook tests" + if: github.event.pull_request.merged == false + permissions: + actions: 'write' + runs-on: ubuntu-latest + outputs: + proceed: ${{ steps.proceed.outputs.proceed }} + steps: + - name: "Checking for test files" + id: proceed + run: | + RESULT=(**/test_*.ipynb) + if [ -z "${RESULT[0]}" ]; then + echo "Found Jupyter Notebook tests" + echo "proceed=true" >> "$GITHUB_OUTPUT" + fi + + parse-project-metadata: + name: "Determine Python versions" + needs: [validate-notebook-tests] + if: needs.validate-notebook-tests.outputs.proceed == 'true' + # yamllint disable-line rule:line-length + uses: os-climate/devops-reusable-workflows/.github/workflows/python-versions-matrix.yaml@main + + notebook-tests: + name: "Test Jupyter Notebooks" + needs: [validate-notebook-tests, parse-project-metadata] + runs-on: ubuntu-latest + continue-on-error: true + # Don't run when pull request is merged + if: github.event.pull_request.merged == 'false' + + strategy: + fail-fast: false + matrix: ${{ fromJson(needs.parse-project-metadata.outputs.matrix) }} + steps: + - name: "Checkout repository" + uses: actions/checkout@v4 + + - name: "Set up Python ${{ matrix.python-version }}" + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + + - name: "Setup PDM for build commands" + uses: pdm-project/setup-pdm@v4 + with: + python-version: ${{ matrix.python-version }} + + - name: "Install dependencies" + run: | + which python; which python3 + python --version; python3 --version + python -m pip install --upgrade pip + pdm export -o requirements.txt + if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + pip install . + pip install pytest nbmake + + - name: "Testing Jupyter Notebooks" + run: | + echo "Testing notebooks using: pytest --nbmake -- **/test_*.ipynb" + pytest --nbmake -- **/test_*.ipynb + + - name: Upload logs as artefacts + if: always() + uses: actions/upload-artifact@v4 + with: + name: debug-logs + path: /tmp/*.log + retention-days: 14 diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 3452c11a..6fe13e0d 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -1,17 +1,13 @@ --- -name: "🐍📦 Production build and release" +name: "🐍📦 Old Production build and release" # GitHub/PyPI trusted publisher documentation: # https://packaging.python.org/en/latest/guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows/ # yamllint disable-line rule:truthy on: - # workflow_dispatch: push: # Only invoked on release tag pushes - branches: - - 'main' - - 'master' tags: - 'v*.*.*' @@ -28,8 +24,9 @@ jobs: if: startsWith(github.ref, 'refs/tags/') runs-on: ubuntu-latest permissions: - # IMPORTANT: mandatory for Sigstore + contents: write id-token: write + steps: ### BUILDING ### @@ -44,10 +41,20 @@ jobs: - name: "Setup PDM for build commands" uses: pdm-project/setup-pdm@v4 + - name: "Fetch current semantic tag" + id: fetch-tags + # yamllint disable-line rule:line-length + uses: os-climate/devops-reusable-workflows/.github/actions/latest-semantic-tag@main + - name: "Update version from tags for production release" run: | - echo "Github versioning: ${{ github.ref_name }}" - scripts/release-versioning.sh + echo "Github tag/versioning: ${{ github.ref_name }}" + if (grep 'dynamic = \[\"version\"\]' pyproject.toml > /dev/null); then + echo "Proceeding build with dynamic versioning" + else + echo "Using legacy script to bump release version" + scripts/release-versioning.sh + fi - name: "Build with PDM backend" run: | @@ -56,6 +63,7 @@ jobs: ### SIGNING ### - name: "Sign packages with Sigstore" + # Use new action uses: sigstore/gh-action-sigstore-python@v3.0.0 with: inputs: >- @@ -72,8 +80,6 @@ jobs: github: name: "📦 Publish to GitHub" - # Only publish on tag pushes - if: startsWith(github.ref, 'refs/tags/') needs: - build runs-on: ubuntu-latest @@ -94,8 +100,7 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} prerelease: false tag_name: ${{ github.ref_name }} - name: "Test/Development Build \ - ${{ github.ref_name }}" + name: ${{ github.ref_name }}" # body_path: ${{ github.workspace }}/CHANGELOG.rst files: | dist/*.tar.gz @@ -105,9 +110,7 @@ jobs: ### PUBLISH PYPI TEST ### testpypi: - name: "📦 Publish to PyPi Test" - # Only publish on tag pushes - if: startsWith(github.ref, 'refs/tags/') + name: "📦 Test publishing to PyPI" needs: - build runs-on: ubuntu-latest @@ -130,7 +133,7 @@ jobs: fi rm dist/*.sigstore* - - name: Publish distribution to Test PyPI + - name: "Test publishing to PyPI" uses: pypa/gh-action-pypi-publish@release/v1 with: repository-url: https://test.pypi.org/legacy/ @@ -140,8 +143,6 @@ jobs: pypi: name: "📦 Publish to PyPi" - # Only publish on tag pushes - if: startsWith(github.ref, 'refs/tags/') needs: - testpypi runs-on: ubuntu-latest diff --git a/.github/workflows/security.yaml b/.github/workflows/security.yaml index 15617632..89c57f11 100644 --- a/.github/workflows/security.yaml +++ b/.github/workflows/security.yaml @@ -16,21 +16,29 @@ on: - "!update-devops-tooling" jobs: + get-python-versions: + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.parse-project-metadata.outputs.python-matrix-versions }} + + steps: + - uses: actions/checkout@v4 - parse-project-metadata: - name: "Determine Python versions" - # yamllint disable-line rule:line-length - uses: os-climate/devops-reusable-workflows/.github/workflows/pyproject-toml-fetch-matrix.yaml@main + - name: "Populate environment variables" + id: parse-project-metadata + # yamllint disable-line rule:line-length + uses: os-climate/devops-reusable-workflows/.github/actions/python-versions-matrix@main - build: - name: "Audit Python dependencies" - needs: [parse-project-metadata] - runs-on: ubuntu-latest + builds: + name: "Python builds" + needs: [get-python-versions] + runs-on: "ubuntu-latest" + continue-on-error: true # Don't run when pull request is merged if: github.event.pull_request.merged == false strategy: fail-fast: false - matrix: ${{ fromJson(needs.parse-project-metadata.outputs.matrix) }} + matrix: ${{ fromJson(needs.get-python-versions.outputs.matrix) }} steps: - name: "Checkout repository" @@ -57,4 +65,4 @@ jobs: pdm list --graph - name: "Run: pip-audit" - uses: pypa/gh-action-pip-audit@v1.1.0 + uses: pypa/gh-action-pip-audit@v1.0.8 diff --git a/.github/workflows/test-release.yaml b/.github/workflows/test-release.yaml index a4b91e4d..bafecb48 100644 --- a/.github/workflows/test-release.yaml +++ b/.github/workflows/test-release.yaml @@ -62,7 +62,7 @@ jobs: ### SIGNING ### - name: "Sign packages with Sigstore" - uses: sigstore/gh-action-sigstore-python@v3.0.0 + uses: sigstore/gh-action-sigstore-python@v2 with: inputs: >- @@ -117,7 +117,7 @@ jobs: files: | dist/*.tar.gz dist/*.whl - dist/*.sigstore* + dist/*.sigstore ### PUBLISH TEST PYPI ### @@ -143,7 +143,7 @@ jobs: if [ -f dist/buildvars.txt ]; then rm dist/buildvars.txt fi - rm dist/*.sigstore* + rm dist/*.sigstore - name: Publish distribution to Test PyPI uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/.github/workflows/testing.yaml b/.github/workflows/testing.yaml index aebd8a94..125e06e9 100644 --- a/.github/workflows/testing.yaml +++ b/.github/workflows/testing.yaml @@ -11,21 +11,28 @@ on: - "!update-devops-tooling" jobs: + get-python-versions: + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.parse-project-metadata.outputs.python-matrix-versions }} + + steps: + - uses: actions/checkout@v4 - parse-project-metadata: - name: "Determine Python versions" - # yamllint disable-line rule:line-length - uses: os-climate/devops-reusable-workflows/.github/workflows/pyproject-toml-fetch-matrix.yaml@main + - name: "Populate environment variables" + id: parse-project-metadata + # yamllint disable-line rule:line-length + uses: os-climate/devops-reusable-workflows/.github/actions/python-versions-matrix@main testing: name: "Run unit tests" - needs: [parse-project-metadata] + needs: [get-python-versions] runs-on: ubuntu-latest # Don't run when pull request is merged if: github.event.pull_request.merged == false strategy: fail-fast: false - matrix: ${{ fromJson(needs.parse-project-metadata.outputs.matrix) }} + matrix: ${{ fromJson(needs.get-python-versions.outputs.matrix) }} steps: - name: "Checkout repository" diff --git a/.gitignore b/.gitignore index 0e4dc4ff..60040b62 100644 --- a/.gitignore +++ b/.gitignore @@ -1,14 +1,14 @@ # Temporary devops repo -.devops +/.devops + +# Twine temporary files +package-lock.json +package.json # Output files from co2budget.ipynb (ITR-Examples) OECM-images TPI-images -# Test output paths - -**/test_output/** - # Local node cache node_modules @@ -103,8 +103,8 @@ instance/ docs/_build/ # PyBuilder -.pybuilder/ -target/ +/.pybuilder/ +/target/ # Jupyter Notebook .ipynb_checkpoints @@ -177,7 +177,6 @@ docker-compose_aws.yml .noseids test/.DS_Store .DS_Store -tests/test_output/* # pytype static type analyzer .pytype/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8c12182b..1e7725ff 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,9 +1,6 @@ --- ci: autofix_commit_msg: "Chore: pre-commit autoupdate" - skip: - # pre-commit.ci cannot install WGET, so tomlint must be disabled - - tomllint exclude: | (?x)^( @@ -13,16 +10,6 @@ exclude: | repos: - - repo: local - hooks: - - id: tomllint - name: "Script: scripts/tomllint.sh" - language: script - # pass_filenames: false - files: \^*.toml - types: [file] - entry: scripts/tomllint.sh . - - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.6.0 hooks: @@ -37,26 +24,28 @@ repos: # - id: detect-aws-credentials - id: check-xml - id: check-yaml - - id: debug-statements - id: detect-private-key - id: end-of-file-fixer - - id: mixed-line-ending - args: ["--fix=lf"] + # - id: mixed-line-ending + # args: ["--fix=lf"] - id: name-tests-test args: ["--pytest-test-first"] - id: no-commit-to-branch # - id: pretty-format-json - id: requirements-txt-fixer - - id: trailing-whitespace -# yamllint disable rule:comments-indentation - ## Commenting until issue #94 is fixed - # - repo: https://github.com/igorshubovych/markdownlint-cli - # rev: v0.41.0 - # hooks: - # - id: markdownlint - # args: ["--fix"] -# yamllint enable rule:comments-indentation + - repo: https://github.com/pre-commit/mirrors-prettier + rev: v4.0.0-alpha.8 + hooks: + - id: prettier + args: + ['--no-error-on-unmatched-pattern', '--ignore-unknown'] + + - repo: https://github.com/igorshubovych/markdownlint-cli + rev: v0.41.0 + hooks: + - id: markdownlint + args: ["--fix"] - repo: https://github.com/jorisroovers/gitlint rev: v0.19.1 @@ -73,6 +62,7 @@ repos: rev: v0.10.0.1 hooks: - id: shellcheck + args: ["-x"] # Check external files - repo: https://github.com/Mateusz-Grzelinski/actionlint-py rev: v1.7.1.15 @@ -88,14 +78,23 @@ repos: ignore-from-file: [.gitignore],}"] - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.6.1 + rev: v0.5.5 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix, --config=pyproject.toml] - id: ruff-format + - repo: local + hooks: + - id: mypy-cache + name: "create mypy cache" + language: system + pass_filenames: false + entry: bash -c 'if [ ! -d .mypy_cache ]; + then /bin/mkdir .mypy_cache; fi; exit 0' + - repo: https://github.com/pre-commit/mirrors-mypy - rev: "v1.11.1" + rev: "v1.11.0" hooks: - id: mypy verbose: true @@ -107,7 +106,7 @@ repos: # - repo: https://github.com/codespell-project/codespell # rev: v2.2.2 # hooks: - # - id: codespell + # - id: codespell # Automatically upgrade Python syntax for newer versions # - repo: https://github.com/asottile/pyupgrade diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000..6491e424 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,4 @@ +**/.pre-commit-config.yaml +**/*.yaml +**/*.yml +**/.git/** diff --git a/scripts/bootstrap.sh b/scripts/bootstrap.sh index 322e1d5c..ac070c28 100755 --- a/scripts/bootstrap.sh +++ b/scripts/bootstrap.sh @@ -11,6 +11,7 @@ SOURCE_FILE="bootstrap.yaml" WGET_URL="https://raw.githubusercontent.com/os-climate/devops-toolkit/main/.github/workflows/$SOURCE_FILE" AUTOMATION_BRANCH="update-devops-tooling" DEVOPS_DIR=".devops" +FETCH_MODE="wget" ### Checks ### @@ -21,7 +22,8 @@ fi WGET_CMD=$(which wget) if [ ! -x "$WGET_CMD" ]; then - echo "WGET command was NOT found in PATH"; exit 1 + echo "WGET command was NOT found in PATH; using CURL" + FETCH_MODE="curl" fi MKTEMP_CMD=$(which mktemp) @@ -29,6 +31,8 @@ if [ ! -x "$MKTEMP_CMD" ]; then echo "MKTEMP command was NOT found in PATH"; exit 1 fi + + SHELL_SCRIPT=$(mktemp -t script-XXXXXXXX.sh) ### Functions ### @@ -95,15 +99,21 @@ if [ -f "$SOURCE_FILE" ]; then echo "Removing existing copy of: $SOURCE_FILE" rm "$SOURCE_FILE" fi -echo "Pulling latest DevOps bootstrap workflow from:" +echo "Pulling latest DevOps bootstrap YAML from:" echo " $WGET_URL" -"$WGET_CMD" -q "$WGET_URL" +if [ "$FETCH_MODE" = "wget" ]; then + "$WGET_CMD" -q "$WGET_URL" > /dev/null 2>&1 +fi +if [ ! -f "$SOURCE_FILE" ]; then + echo "Attempting to retrieve YAML file with CURL" + curl "$WGET_URL" > "$SOURCE_FILE" +fi # The section below extracts shell code from the YAML file echo "Extracting shell code from: $SOURCE_FILE" EXTRACT="false" while read -r LINE; do - if [ "$LINE" = "### SHELL CODE START ###" ]; then + if [ "$LINE" = "#SHELLCODESTART" ]; then EXTRACT="true" SHELL_SCRIPT=$(mktemp -t script-XXXXXXXX.sh) touch "$SHELL_SCRIPT" @@ -113,7 +123,7 @@ while read -r LINE; do fi if [ "$EXTRACT" = "true" ]; then echo "$LINE" >> "$SHELL_SCRIPT" - if [ "$LINE" = "### SHELL CODE END ###" ]; then + if [ "$LINE" = "#SHELLCODEEND" ]; then break fi fi From 6b99d6e6e740ab13c7d57cd9d5dfb42b8f326d95 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 08:14:07 +0000 Subject: [PATCH 2/2] Chore: pre-commit autoupdate --- src/hazard/onboard/iris_wind.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/hazard/onboard/iris_wind.md b/src/hazard/onboard/iris_wind.md index da831e6b..e58c505f 100644 --- a/src/hazard/onboard/iris_wind.md +++ b/src/hazard/onboard/iris_wind.md @@ -1,6 +1,7 @@ -Sparks, N., Toumi, R. The Imperial College Storm Model (IRIS) Dataset. *Sci Data* **11**, 424 (2024). +Sparks, N., Toumi, R. The Imperial College Storm Model (IRIS) Dataset. _Sci Data_ **11**, 424 (2024). ## The Imperial College Storm Model (IRIS) Dataset - Scientific Data + Assessing tropical cyclone risk on a global scale given the infrequency of landfalling tropical cyclones and the short period of reliable observations remains a challenge. Synthetic tropical cyclone datasets can help overcome these problems. Here we present a new global dataset created by IRIS, the ImpeRIal college Storm Model. IRIS is novel because, unlike other synthetic TC models, it only simulates the decay from the point of lifetime maximum intensity. This minimises the bias in the dataset. It takes input from 42 years of observed tropical cyclones and creates a 10,000 year synthetic dataset which is then validated against the observations. IRIS captures important statistical characteristics of the observed data. The return periods of the landfall maximum wind speed (1 minute sustained in m/s) are realistic globally. Climate model projections are used to adjust the life-time maximum intensity. -***Disclaimer***: There have been many improvements on the dataset. Contact Professor Toumi from the Imperial College London for improved data. +**_Disclaimer_**: There have been many improvements on the dataset. Contact Professor Toumi from the Imperial College London for improved data.