diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 8825656abcc390566716dd7d1aa901099332650e..1decf69a2d455e125c9b3dbb97558207a23a9cd1 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -15,3 +15,13 @@ include:
 
 variables:
   DOCUMENTATION_DISABLED: "1"
+  DAST_DISABLED: "1"
+
+test:
+  artifacts:
+    reports:
+      coverage_report:
+        coverage_format: cobertura
+        path: ./artefacts/**/coverage.xml
+  variables:
+    TOX_ENVLIST: "black,flake8,py3"
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1a3831426a63f72038e877585040412d1a4ef554..59f4b9fa116456284adaea1f3fc80f239bbf46a0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
 The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
+## [1.0.0] - 2023-06-22
+
+### Changed
+
+- Change `--really-do-this` to `--write`.
+
 ## [0.14.2] - 2023-05-23
 
 ### Changed
diff --git a/README.md b/README.md
index fa85963d91f0ad3ee6c5aaaf2bfa9cdc14d77400..7576beda80876c9efb41b0183b9fc74abb53b2a0 100644
--- a/README.md
+++ b/README.md
@@ -25,10 +25,10 @@ By default this will log what will be done. To actually perform the
 synchronisation:
 
 ```console
-$ gsuitesync --really-do-this
+$ gsuitesync --write
 
 # And with group settings
-$ gsuitesync --group-settings --really-do-this
+$ gsuitesync --group-settings --write
 ```
 
 The default socket timeout for batch operations is 300 seconds. To change this
diff --git a/gsuitesync/__init__.py b/gsuitesync/__init__.py
index 5fa3c5c2266c8df854e8a034b14b51b6cd451569..360d1915a2979e3814a5d34ee62ed6528c260705 100644
--- a/gsuitesync/__init__.py
+++ b/gsuitesync/__init__.py
@@ -4,27 +4,24 @@ Synchronise users to GSuite
 Usage:
     gsuitesync (-h | --help)
     gsuitesync [--configuration=FILE] [--quiet] [--group-settings] [--just-users]
-               [--licensing] [--delete-users] [--really-do-this] [--timeout=SECONDS]
+               [--licensing] [--delete-users] [--write] [--timeout=SECONDS]
                [--cache-dir=DIR]
 
 Options:
     -h, --help                  Show a brief usage summary.
 
-    --quiet                     Reduce logging verbosity.
+    -q, --quiet                 Reduce logging verbosity.
 
-    --configuration=FILE        Specify configuration file to load.
+    -c, --configuration=FILE    Specify configuration file to load.
 
-    --group-settings            Also update group settings on all groups.
+    -w, --write                 Actually try to make the changes.
 
+    --group-settings            Also update group settings on all groups.
     --just-users                Just compare users not groups and institutions.
-
     --licensing                 Also update user licence allocations.
-
     --delete-users              Delete suspended users.
 
-    --really-do-this            Actually try to make the changes.
-
-    --timeout=SECONDS           Integer timeout for socket when performing batch
+    -t, --timeout=SECONDS       Integer timeout for socket when performing batch
                                 operations. [default: 300]
 
     --cache-dir=DIR             Directory to cache API responses, if provided.
@@ -57,10 +54,9 @@ def main():
     timeout_val = int(opts["--timeout"])
 
     # Safety check - could write with out of date cached data
-    if opts["--really-do-this"] and opts["--cache-dir"]:
+    if opts["--write"] and opts["--cache-dir"]:
         LOG.error(
-            "Option --really-do-this with --cache-dir is blocked to avoid "
-            "writing outdated cached data."
+            "Option --write with --cache-dir is blocked to avoid writing outdated cached data."
         )
         exit(1)
 
@@ -70,7 +66,7 @@ def main():
     # Perform sync
     sync.sync(
         configuration,
-        read_only=not opts["--really-do-this"],
+        write_mode=opts["--write"],
         timeout=timeout_val,
         group_settings=opts["--group-settings"],
         just_users=opts["--just-users"],
diff --git a/gsuitesync/gapiutil.py b/gsuitesync/gapiutil.py
index 2a4f8f0eaac65a559226910d8e9df9edc9f26c50..f71e6326c1ee4da98480a7fc70bf1bc56d8218e3 100644
--- a/gsuitesync/gapiutil.py
+++ b/gsuitesync/gapiutil.py
@@ -228,7 +228,7 @@ def get_all_in_list(
     return resources
 
 
-def process_requests(service, requests, sync_config, read_only=True):
+def process_requests(service, requests, sync_config, write_mode=False):
     """
     Process an iterable list of requests to the specified Google service in batches.
     These APIs support a maximum batch size of 1000. See:
@@ -241,9 +241,9 @@ def process_requests(service, requests, sync_config, read_only=True):
         for request in request_batch:
             batch.add(request, callback=_handle_batch_response)
 
-        # Execute the batch request if not in read only mode. Otherwise log that we would
+        # Execute the batch request if in write mode. Otherwise log that we would
         # have.
-        if not read_only:
+        if write_mode:
             LOG.info("Issuing batch request to Google.")
             sleep(sync_config.inter_batch_delay)
             retries = sync_config.http_retries
diff --git a/gsuitesync/sync/base.py b/gsuitesync/sync/base.py
index adb6296cd628228187bdbfe174d3f26c61f9d59b..12347e9580b8371229f898c338e3e681eabffa35 100644
--- a/gsuitesync/sync/base.py
+++ b/gsuitesync/sync/base.py
@@ -7,11 +7,11 @@ Base classes for retrievers, comparator and updater classes that consume configu
 class ConfigurationStateConsumer:
     required_config = None
 
-    def __init__(self, configuration, state, read_only=True, delete_users=False, cache_dir=None):
+    def __init__(self, configuration, state, write_mode=False, delete_users=False, cache_dir=None):
         # For convenience, create properties for required configuration
         for c in self.required_config if self.required_config is not None else []:
             setattr(self, f"{c}_config", configuration.get(c, {}))
         self.state = state
-        self.read_only = read_only
+        self.write_mode = write_mode
         self.delete_users = delete_users
         self.cache_dir = cache_dir
diff --git a/gsuitesync/sync/gapi.py b/gsuitesync/sync/gapi.py
index 4856f85b586d0ba16ee15974631da6127535fab2..3946c2ed475f7ccac31021ee39e9ba66ed55c1c7 100644
--- a/gsuitesync/sync/gapi.py
+++ b/gsuitesync/sync/gapi.py
@@ -52,7 +52,7 @@ class GAPIRetriever(ConfigurationStateConsumer):
 
     def connect(self, timeout=300):
         # load credentials
-        self.creds = self._get_credentials(self.read_only)
+        self.creds = self._get_credentials(read_only=not self.write_mode)
         # Build the directory service using Google API discovery.
         socket.setdefaulttimeout(timeout)
         directory_service = discovery.build("admin", "directory_v1", credentials=self.creds)
@@ -89,7 +89,7 @@ class GAPIRetriever(ConfigurationStateConsumer):
             }
         )
 
-    def _get_credentials(self, read_only):
+    def _get_credentials(self, read_only=True):
         """
         Create a Google credentials object from the configuration. Use *read_only* to indicate if
         read-only credentials are preferred.
diff --git a/gsuitesync/sync/main.py b/gsuitesync/sync/main.py
index 1f0e17ae19768cc9a0adf07c0de702f6362a87b2..15b7a1721d278f286464f22dbfa6a002fcc83d46 100644
--- a/gsuitesync/sync/main.py
+++ b/gsuitesync/sync/main.py
@@ -17,19 +17,17 @@ LOG = logging.getLogger(__name__)
 def sync(
     configuration,
     *,
-    read_only=True,
+    write_mode=False,
     timeout=300,
     group_settings=False,
     just_users=False,
     licensing=False,
     cache_dir=None,
-    delete_users=False
+    delete_users=False,
 ):
     """Perform sync given configuration dictionary."""
-    if read_only:
-        LOG.info("Performing synchronisation in READ ONLY mode.")
-    else:
-        LOG.info("Performing synchronisation in WRITE mode.")
+
+    LOG.info(f'Performing synchronisation in {"WRITE" if write_mode else "READ ONLY"} mode.')
 
     # Parse configuration into Configuration dict of appropriate dataclasses
     configuration = config.parse_configuration(configuration)
@@ -45,7 +43,7 @@ def sync(
         lookup.retrieve_groups()
 
     # Get users and optionally groups from Google
-    gapi = GAPIRetriever(configuration, state, read_only=read_only, cache_dir=cache_dir)
+    gapi = GAPIRetriever(configuration, state, write_mode=write_mode, cache_dir=cache_dir)
     gapi.connect(timeout)
     gapi.retrieve_users()
     if licensing:
@@ -73,7 +71,7 @@ def sync(
     comparator.enforce_limits(just_users, licensing)
 
     # Update Google with necessary updates found doing comparison
-    updater = GAPIUpdater(configuration, state, read_only=read_only, delete_users=delete_users)
+    updater = GAPIUpdater(configuration, state, write_mode=write_mode, delete_users=delete_users)
     updater.update_users()
     if licensing:
         updater.update_licensing()
diff --git a/gsuitesync/sync/update.py b/gsuitesync/sync/update.py
index 8bbe98bd388a4491d3bc860da8c5cf65b1e50e7e..57b0703e771e99cddab831b0526cd08f8645369c 100644
--- a/gsuitesync/sync/update.py
+++ b/gsuitesync/sync/update.py
@@ -1,5 +1,5 @@
 """
-Perform the actual updates in Google (unless in read_only mode)
+Perform the actual updates in Google (unless not in write_mode)
 
 """
 import crypt
@@ -22,7 +22,7 @@ class GAPIUpdater(ConfigurationStateConsumer):
             self.state.directory_service,
             self.user_api_requests(),
             self.sync_config,
-            self.read_only,
+            write_mode=self.write_mode,
         )
 
     def update_licensing(self):
@@ -33,7 +33,7 @@ class GAPIUpdater(ConfigurationStateConsumer):
             self.state.licensing_service,
             self.licensing_api_requests(),
             self.sync_config,
-            self.read_only,
+            write_mode=self.write_mode,
         )
 
     def update_groups(self):
@@ -41,20 +41,20 @@ class GAPIUpdater(ConfigurationStateConsumer):
             self.state.directory_service,
             self.group_api_requests(),
             self.sync_config,
-            self.read_only,
+            write_mode=self.write_mode,
         )
         # Still need to do this even if `not group_settings` as new groups need their settings
         process_requests(
             self.state.groupssettings_service,
             self.group_settings_api_requests(),
             self.sync_config,
-            self.read_only,
+            write_mode=self.write_mode,
         )
         process_requests(
             self.state.directory_service,
             self.member_api_requests(),
             self.sync_config,
-            self.read_only,
+            write_mode=self.write_mode,
         )
 
     def user_api_requests(self):
diff --git a/setup.py b/setup.py
index 50cf79a769b9d503c432cc9915c5706abc4e21a6..4ef1d12f659f69ca0447f92f79d5d08375d72fd3 100644
--- a/setup.py
+++ b/setup.py
@@ -16,7 +16,7 @@ def load_requirements():
 
 setup(
     name="gsuitesync",
-    version="0.14.2",
+    version="1.0.0",
     packages=find_packages(),
     install_requires=load_requirements(),
     entry_points={
diff --git a/tox.sh b/test.sh
similarity index 59%
rename from tox.sh
rename to test.sh
index 2f6654affcd3fc8e4c8d2388aed9ba6cee9124b8..8a07dc79dc46562ab624e1a48c6ea07987704785 100755
--- a/tox.sh
+++ b/test.sh
@@ -11,4 +11,8 @@ cd "$( dirname "$0")"
 # Execute tox runner, logging command used
 set -x
 docker build -t gsuite-synctool .
-docker run -it --rm -e TOXINI_SITEPACKAGES=True --entrypoint /bin/sh gsuite-synctool -c "tox $*"
\ No newline at end of file
+docker run \
+    -it --rm \
+    -v $(pwd)/htmlcov:/usr/src/app/build/py3/htmlcov:rw \
+    -e TOXINI_SITEPACKAGES=True \
+    --entrypoint /bin/sh gsuite-synctool -c "tox $*"