Skip to content
Snippets Groups Projects
Select Git revision
  • 32bec5033f68be29f3e27052291734af47593830
  • master default protected
  • 1.31
  • 4.38.8
  • 4.38.7
  • 4.38.6
  • 4.38.5
  • 4.38.4
  • 4.38.3
  • 4.38.2
  • 4.38.1
  • 4.38.0
  • 4.37.2
  • 4.37.1
  • 4.37.0
  • 4.36.0
  • 4.35.0
  • 4.34.1
  • 4.34.0
  • 4.33.1
  • 4.33.0
  • 4.32.2
  • 4.32.1
23 results

README.md

Blame
  • devenv.nix 22.24 KiB
    { pkgs ? import <nixpkgs> {}, inputs, phps, lib, config, modulesPath, ... }:
    
    {
      # https://devenv.sh/packages/
      packages = with pkgs; [
        inputs.version.defaultPackage."${builtins.currentSystem}"
        appimage-run
        blackbox
        blackbox-terminal
        coreutils-full
        dbeaver
        dbeaver
        delve
        dialog
        drill
        eza
        fd
        fd
        feh
        gcc12
        gdlv
        git
        glab
        gnugrep
        gnumake
        gnused
        go-licenses
        gosec
        go-task
        gum
        httpie
        hurl
        jq
        libffi
        logrotate
        meld
        memcached
        netcat
        nixfmt
        nodePackages.mermaid-cli
        openssh
        procps
        ranger
        unixtools.xxd
        unzip
        util-linux
        wget
        zlib
      ];
    
      # https://devenv.sh/languages/
      # languages.nix.enable = true;
      languages = { go = { enable = true; }; };
    
      difftastic.enable = true;
    
      scripts.run-sshd.exec = ''
      set -x
      
      cd ${config.devenv.root}/docker/sftp-server
      ${pkgs.docker-client}/bin/docker docker build -t jobqueue-sftp-server .
      cd -
      
      
      
      ${pkgs.coreutils}/bin/chmod 700 ${config.devenv.root}/.config/temp_rsa_key
      ${pkgs.coreutils}/bin/chmod 700 ${config.devenv.root}/.config/temp_ed25518_key
      
      ${pkgs.coreutils}/bin/mkdir -p ${config.devenv.root}/.devenv/chroot/home/demo/.ssh 
      ${pkgs.coreutils}/bin/cat ${config.devenv.root}/.config/demo_ssh_key.pub > ${config.devenv.root}/.devenv/chroot/home/demo/.ssh/authorized_keys
      ${pkgs.coreutils}/bin/chmod 700 ${config.devenv.root}/.devenv/chroot/home/demo/.ssh
      ${pkgs.coreutils}/bin/chmod 600 ${config.devenv.root}/.devenv/chroot/home/demo/.ssh/authorized_keys
      
      
      ${pkgs.coreutils}/bin/cat <<EOF > ${config.devenv.root}/.config/sshd_config
    
    AuthorizedKeysCommand ${pkgs.coreutils}/bin/cat ${config.devenv.root}/.devenv/chroot/home/demo/.ssh/authorized_keys
    AuthorizedKeysCommandUser nobody
    
    Match User root
        ChrootDirectory ${config.devenv.root}/.devenv/chroot
        ForceCommand internal-sftp
        PasswordAuthentication no
        PermitTunnel no
        AllowAgentForwarding no
        AllowTcpForwarding no
        X11Forwarding no
        PermitRootLogin no
        AllowUsers demo root
    EOF
     
      
      ${pkgs.openssh}/bin/sshd -D -e -o \
         HostKey=${config.devenv.root}/.config/temp_rsa_key \
         -f ${config.devenv.root}/.config/sshd_config \
         -o HostKey=${config.devenv.root}/.config/temp_ed25518_key \
         -o Port=''${1:-2222}  \
         -o AuthorizedKeysFile=${config.devenv.root}/.devenv/chroot/home/demo/.ssh/authorized_keys \
         -o PidFile=${config.devenv.root}/.devenv/sshd.pid   
      
      '';
      
      scripts.draw-graph.exec = ''
      echo -e "Enter Meirmaid graph definition. ''${RED}End with Ctrl+D''${RESET}\n"  
      diagram=$(${pkgs.gum}/bin/gum write --placeholder "Enter Meirmaid graph definition. End with Ctrl+D")
      
      tmpOutput=$(mktemp).png
      
      echo "$diagram" | ${pkgs.nodePackages.mermaid-cli}/bin/mmdc -i - -o "$tmpOutput"
      ${pkgs.feh}/bin/feh $tmpOutput
      
      # should delte the file, but does not work ask with gum
      ${pkgs.gum}/bin/gum confirm "Delete temporary file?"
        if [ $? -eq 0 ]; then
           rm "$tmpOutput"
           else
             echo "not deleting; file is at $tmpOutput"
        fi    
        
        
      
      
      '';
      
      scripts.get-go-default-packages.exec = ''
        #!${pkgs.bash}/bin/bash
        echo $(awk -F ' ' '/^module / { print $2 }' go.mod)
      '';
    
      # This script is executed when the app is built
      # You can use it to build the app  
      scripts.test-lib.exec = ''
        #!${pkgs.bash}/bin/bash
        set -x
    
    ${pkgs.gosec}/bin/gosec ${config.devenv.root}
    ${pkgs.go}/bin/go test -tags=runOnTask -cover -v ${config.devenv.root}
    ${pkgs.go}/bin/go test -tags=runOnTask -bench -v ${config.devenv.root}
    ${pkgs.go}/bin/go test -tags=runOnTask -race -v ${config.devenv.root}
    
      '';
    
      # This scritp is used to deploy the app to the gitlab registry
      # It is used by the gitlab-ci.yml file
      # The environment variables are set in the gitlab project settings
      scripts.deploy-lib.exec = ''
        #!${pkgs.bash}/bin/bash
    
        PATH="''${PATH}":${pkgs.coreutils}/bin
        PATH="''${PATH}":${pkgs.jq}/bin/
        PATH="''${PATH}":${pkgs.curl}/bin/
        PATH="''${PATH}":${pkgs.moreutils}/bin/
        PATH="''${PATH}":${pkgs.gnutar}/bin
        PATH="''${PATH}":${pkgs.gzip}/bin/
        PATH="''${PATH}":${pkgs.eza}/bin/
        PATH="''${PATH}":${pkgs.git}/bin/
        PATH="''${PATH}":${
          inputs.version.defaultPackage."${builtins.currentSystem}"
        }/bin/
    
        export PATH
    
        if [[ -f .env-gitlab-ci ]]; then
            source .env-gitlab-ci
            rm .env-gitlab-ci
        fi
    
        set -x
        ## if $HOME not set, set it to current directory
        if [[ -z "''${HOME}" ]]; then
            HOME=$(pwd)
        fi
    
        export HOME
    
        git config user.email "''${GITLAB_USER_EMAIL}"
        git config user.name "''${GITLAB_USER_NAME:-"Gitlab CI"}"
        git config pull.rebase true
        git config http.sslVerify "false"
        git remote set-url origin https://pad:''${GITLAB_TOKEN}@''${CI_REPOSITORY_URL#*@}
    
        git fetch --all --tags --unshallow
        git reset --hard origin/master
        git checkout $CI_COMMIT_REF_NAME
        git pull origin $CI_COMMIT_REF_NAME
    
        if [ ! -z "''${CI_PROJECT_DIR}" ]; then
            echo "CI_PROJECT_DIR is set, using it as project root."
            project_root=$(realpath "''${CI_PROJECT_DIR}")/
        elif [ ! -z "''${DEVENV_ROOT}" ]; then
            echo "DEVENV_ROOT is set, using it as project root."
            project_root=$(realpath "''${DEVENV_ROOT}")/
        else
            echo "Error: DEVENV_ROOT or CI_PROJECT_DIR environment variables are not set."
            exit 1  
        fi
    
        if [ ! -d "''${project_root}" ]; then
            echo "Error: Project root directory does not seem to be valid."
            echo "Check the DEVENV_ROOT or CI_PROJECT_DIR environment variables."
            exit 1
        fi
    
        if [ -z "'CI_JOB_TOKEN" ]; then
            echo "Error: CI_JOB_TOKEN variable is not set."
            exit 1
        fi
    
        git --no-pager log --decorate=short --pretty=oneline
        gitVersion=v$(version predict)
        git tag -a $gitVersion -m"chore: bump version" 
        git --no-pager log --decorate=short --pretty=oneline
        git push -o ci.skip origin ''${CI_COMMIT_REF_NAME} --tags
    
        echo "done"
    
      '';
    
      enterShell = ''
           
    cat <<'EOF' > CONTRIBUTING.md
    # Contributing to schukai GmbH Projects
    
    ## Code of Conduct
    
    Be a human, not an asshole. Common sense and basic human decency apply.
    
    ## Getting Started
    
    ### Setting up the Project
    
    1. Fork the project on GitLab.
    2. Clone your fork locally. Replace `[your-username]` with your GitLab username and `[project-name]` with the actual project name:
        ```bash
        git clone $(git config --get remote.origin.url)
        ```
    3. Add the upstream repository. Replace `[original-username]` and `[project-name]` with the original repository's username and project name:
        ```bash
        git remote add upstream https://gitlab.schukai.com/[original-username]/[project-name].git
        ```
    
    ### Making Changes
    
    1. Create a new branch:
        ```bash
        git checkout -b new-feature-branch
        ```
    2. Make your changes.
    3. Commit your changes:
        ```bash
        git commit -m "Description of change"
        ```
    
    ### Submitting a Merge Request
    
    1. Push your changes to your fork:
        ```bash
        git push origin new-feature-branch
        ```
    2. Navigate to the original project repository on `gitlab.schukai.com`.
    3. Open a Merge Request and provide a clear description of the changes.
    
    ## Coding Guidelines
    
    - Follow the coding style used in the project.
    - Write unit tests for new features.
    - Ensure that all tests pass before submitting a Merge Request.
    
    ## Reporting Issues
    
    If you find an issue, please create a new issue on `gitlab.schukai.com`.
    
    ## Additional Resources
    
    - [GitLab Flow](https://docs.gitlab.com/ee/topics/gitlab_flow.html)
    - [GitLab Merge Request Guidelines](https://docs.gitlab.com/ee/user/project/merge_requests/)
    
    Thank you for your contribution! 
        
    EOF
        
    cat <<'EOF' > LICENSE
    Copyright (C) 2023 schukai GmbH 
    
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published
    by the Free Software Foundation, either version 3 of the License.
    
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.
    
    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.  
        
    EOF
     
    cat <<'EOF' > Taskfile.yml
    
    # THIS FILE IS AUTOGENERATED BY THE DEVENVSHELL
    # DO NOT EDIT THIS FILE MANUALLY
    # INSTEAD EDIT THE DEVENVSHELL CONFIGURATION FILE devenv.nix 
    # AND OPEN A SHELL WITH THE COMMAND devenv shell
    #
    # Information about the task runner can be found here:
    # https://taskfile.dev
    
    version: '3'
    
    tasks:
      default: 
        cmds:
          - task --list
        silent: true
        
      test:
        desc: Execute unit tests in Go.
        env:
          TEST_BY_TASK: true
        cmds:
          - docker pull atmoz/sftp:alpine
          - docker pull axllent/mailpit 
          - echo "Execute unit tests in Go."
          - test-lib
    
      test-fuzz:
        desc: Conduct fuzzing tests.#
        env:
          TEST_BY_TASK: true
        cmds:  
          - echo "Conduct fuzzing tests."
          - go test -tags=runOnTask -v -fuzztime=30s -fuzz=Fuzz ./...
    
      add-licenses:
        desc: Attach license headers to Go files.
        cmds:
          - echo "Attach license headers to Go files."
          - go install github.com/google/addlicense@latest
          - addlicense -c "schukai GmbH" -s -l "AGPL-3.0" ./*.go
        silent: true
        
      check-licenses:
        desc: Check license headers of Go files.
        silent: true
        cmds:
          - go-licenses save "$(get-go-default-packages)"  --ignore "gitlab.schukai.com"  --force --save_path ''${DEVENV_ROOT}/licenses/
    
      check:
        desc: Confirm repository status.
        cmds:
          - git diff-index --quiet HEAD || (echo "There are uncommitted changes after running make. Please commit or stash them before running make."; exit 1)
        silent: true
    
      commit:
        desc: Commit changes to the repository.
        aliases:
          - c
          - ci
          - git-commit
        cmds:
          - do-git-commit
    EOF
    
    cat <<'EOF' > .gitlab-ci.yml
    
    # THIS FILE IS AUTOGENERATED BY THE DEVENVSHELL
    # DO NOT EDIT THIS FILE MANUALLY
    # INSTEAD EDIT THE DEVENVSHELL CONFIGURATION FILE devenv.nix
    # AND OPEN A SHELL WITH THE COMMAND devenv shell
    #
    
    image: docker-registry.schukai.com:443/nixos-ci-devenv:latest
    
    #    services:
    #      - docker:dind
    
    variables:
      # The repo name as used in
      # https://github.com/nix-community/NUR/blob/master/repos.json
      NIXOS_VERSION: "23.05"
      NIXPKGS_ALLOW_UNFREE: "1"
      NIXPKGS_ALLOW_INSECURE: "1"
      GIT_DEPTH: 10
    
    stages:
      - test
      - deploy 
    
    before_script:
      - echo > .env-gitlab-ci
      - variables=("HOME=$HOME" "CI_COMMIT_REF_NAME=$CI_COMMIT_REF_NAME" "CI_REPOSITORY_URL=$CI_REPOSITORY_URL" "GITLAB_TOKEN=$GITLAB_TOKEN" "CI_JOB_TOKEN=$CI_JOB_TOKEN" "GITLAB_USER_EMAIL=$GITLAB_USER_EMAIL" "GITLAB_USER_NAME=\"$GITLAB_USER_NAME\"" "CI_REGISTRY_USER=$CI_REGISTRY_USER" "CI_PROJECT_ID=$CI_PROJECT_ID" "CI_PROJECT_DIR=$CI_PROJECT_DIR" "CI_API_V4_URL=$CI_API_V4_URL" "CI_PROJECT_NAME=$CI_PROJECT_NAME" "CI_COMMIT_SHORT_SHA=$CI_COMMIT_SHORT_SHA"); for var in "''${variables[@]}"; do echo "$var" >> .env-gitlab-ci; done
      - cat .env-gitlab-ci
      - env 
      - nix shell nixpkgs#docker-client -c docker info
    
    after_script:
      - if [ -f .env-gitlab-ci ]; then rm .env-gitlab-ci; fi
    
    test:
      stage: test
      tags:
        - nixos
      script:
        - devenv shell test-lib
    
      cache:
        - key: nixos
          paths:
            - /nix/store
      
      artifacts:
        paths:
          - dist
    
    deploy:
      stage: deploy
      tags:
        - nixos
      script:
        - devenv shell -c deploy-lib
    
      when: on_success
    
      cache:
        - key: nixos
          paths:
            - /nix/store
    
    EOF
            
      '';
    
      scripts.do-git-commit.exec = ''
        #!/usr/bin/env bash
    
        # Define colors if the terminal supports it
        if [ -t 1 ]; then
          RED='\033[0;31m'
          GREEN='\033[0;32m'
          RESET='\033[0m'
          BOLD='\033[1m'
        else
          RED=""
          GREEN=""
          RESET=""
        fi
    
        step=1
    
        reset
        clear
    
        # create random log file
        LOGFILE="$(mktemp)"
        if [ $? -ne 0 ]; then
          echo -e "''${RED}✖ Could not create temporary log file. Exiting.''${RESET}"
          exit 1
        fi
    
        log_and_display() {
          echo -e "''${GREEN}==> $step. $1''${RESET}" | tee -a $LOGFILE
          step=$((step + 1))
        }
    
        log_error_and_display() {
          echo -e "''${RED}==> $step. $1''${RESET}" | tee -a $LOGFILE
        }
    
        printLogfileAndExit() {
          exit_code=$1
          echo -e "\n\n========================================\n\n\n"
    
          echo -e "\n\n''${BOLD}Git and GitLab Automation Script''${RESET}\n\nI have performed the following actions:\n\n"
          cat "$LOGFILE"
    
          # Optional: Remove log file
          rm -f "$LOGFILE"
    
          if [ $exit_code -eq 0 ]; then
            echo -e "\n''${GREEN}✔''${RESET} All actions were successful" | tee -a $LOGFILE
          elif [ $exit_code -eq -1 ]; then
            echo -e "\n''${RED}✖''${RESET} The script was manually cancelled" | tee -a $LOGFILE
            exit_code=0
          else
            echo -e "\n''${RED}✖''${RESET} Some actions failed" | tee -a $LOGFILE
          fi
    
          exit $exit_code
        }
    
        print_headline() {
          local title=$1
          local underline=$(printf '─%.0s' $(seq 1 ''${#title}))
          echo -e "\n\n''${BOLD}''${title}\n''${underline}''${RESET}\n"
        }
    
        do_cancel() {
          echo -e "''${RED}==> ✖ Cancelled.''${RESET}" | tee -a $LOGFILE
          printLogfileAndExit -1
        }
    
        # Function for unified logging and display
        log_action() {
          if [ $? -eq 0 ]; then
            echo -e "    ''${GREEN}✔''${RESET} $1: Successful" | tee -a $LOGFILE
          else
            echo -e "    ''${RED}✖''${RESET} $1: Failed" | tee -a $LOGFILE
            printLogfileAndExit 1
          fi
        }
    
        print_what_to_do() {
          echo -e "\n\nWhat do you want to do?\n"
        }
    
        git_status=$(git status --porcelain)
        if [[ -z "$git_status" ]]; then
          log_error_and_display "No changes to commit. Exiting."
          printLogfileAndExit 0
        fi
    
        print_headline "Choose commit type"
        selection=$(gum choose "feat: (new feature for the user, not a new feature for build script)" "fix: (bug fix for the user, not a fix to a build script)" "chore: (updating grunt tasks etc.; no production code change)" "docs: (changes to the documentation)" "style: (formatting, missing semi colons, etc; no production code change)" "refactor: (refactoring production code, eg. renaming a variable)" "test: (adding missing tests, refactoring tests; no production code change)" "Cancel")
    
        commit_type=$(echo "$selection" | awk -F':' '{print $1}')
    
        if [[ "$commit_type" == "Cancel" ]]; then
          do_cancel
        fi
    
        log_and_display "You chose the commit type: $commit_type"
    
        # NEXT STEP ISSUE HANDLING ############################################################################################################
        #log_and_display "Issue handling"
    
        gitlabIssues=()
        while IFS= read -r line; do
          if [[ $line =~ ^# ]]; then
            id=$(echo "$line" | awk '{print substr($1, 2)}')
            title=$(echo "$line" | awk -F'about' '{print $1}' | awk '{$1=$2=""; print substr($0, 3)}')
            gitlabIssues+=("$id > $title")
          fi
        done < <(gum spin --spinner dot --show-output --title "Ask gitlab ..." -- glab issue list --output-format=details)
    
        ## if issues are available, ask if user wants to use an existing issue or create a new one
        createOption="Create new issue"
        existingOption="Use existing issue"
        cancelOption="Cancel"
    
        print_headline "Choose issue handling"
        if [ ''${#gitlabIssues[@]} -eq 0 ]; then
          log_and_display "There are no issues available."
    
          print_what_to_do
          choice=$(gum choose "$createOption" "$cancelOption")
    
        else
          log_and_display "There are ''${#gitlabIssues[@]} issues available."
          print_what_to_do
          choice=$(gum choose "$createOption" "$existingOption" "$cancelOption")
        fi
    
        if [[ "$choice" == "$cancelOption" ]]; then
          do_cancel
        fi
    
        ## array of issue ids
        work_on_issue_ids=()
    
        issue_text=""
    
        if [[ "$choice" == "$createOption" ]]; then
          print_headline "Create new issue"
          issue_text=$(gum input --placeholder "Enter issue title")
          echo -e "Enter issue description. ''${RED}End with Ctrl+D''${RESET}\n"
          issue_description=$(gum write --placeholder "Enter issue description. End with Ctrl+D")
          
          if [[ -z "$issue_text" ]]; then
            log_error_and_display "Issue title is empty. Exiting."
            printLogfileAndExit 1
          fi
    
          log_and_display "You entered the issue title: $issue_text"
          log_and_display "You entered the issue description: $issue_description"
          echo -e "\n"
    
          gum confirm "Do you want to create this issue?"
          # gum confirm exits with status 0 if confirmed and status 1 if cancelled.
          if [ $? -eq 1 ]; then
            do_cancel
          fi
    
          issue_output=$(glab issue create -t"$issue_text" --no-editor --description "$issue_description")
          issue_id=$(echo "$issue_output" | grep -oP '(?<=/issues/)\d+')
    
          work_on_issue_ids+=("$issue_id")
    
          log_action "glab issue with id $issue_id created"
    
        else
    
          print_headline "Use existing issue"
          echo -e "Select issue with arrow keys and press tab or space to select. Press enter to confirm.\n"
          issue_ids=$(gum choose --no-limit "''${gitlabIssues[@]}")
    
          # assign issue_ids to work_on_issue_ids. iterate over lines and take integer from beginning of line
          while IFS= read -r line; do
            work_on_issue_ids+=($(echo "$line" | grep -oP '^\d+'))
          done <<<"$issue_ids"
    
        fi
    
        if [ ''${#work_on_issue_ids[@]} -eq 0 ]; then
          log_and_display "No issue selected. Exiting."
          printLogfileAndExit 0
        fi 
    
        # NEXT STEP COMMIT MESSAGE ############################################################################################################
        # print work_on_issue_ids
        work_on_issue_ids_string=""
        for i in "''${work_on_issue_ids[@]}"; do
          work_on_issue_ids_string+="#$i "
        done
    
        log_and_display "You chose to work on the following issues: ''${work_on_issue_ids_string}"
    
    
        print_headline "Check for changes to commit"
    
        # ' ' = unmodified
        # M = modified
        # T = file type changed (regular file, symbolic link or submodule)
        # A = added
        # D = deleted
        # R = renamed
        # C = copied (if config option status.renames is set to "copies")
        # U = updated but unmerged
        # https://man.freebsd.org/cgi/man.cgi?query=git-status&sektion=1&manpath=freebsd-release-ports
    
        count_all_changes=$(echo "$git_status" | wc -l)
        count_staged_changes=$(echo "$git_status" | grep -c '^M')
        count_new_staged_files=$(echo "$git_status" | grep -c '^A')
        count_staged_changes=$((count_staged_changes + count_new_staged_files))
    
    
    
        git_options_all="All $count_all_changes changes"
        git_options_staged="Only the $count_staged_changes staged changes"
        git_options_select_files="Select files"
        git_options_cancel="Cancel"
    
        git_options_array=()
        if [[ $count_all_changes -gt 0 ]]; then
          git_options_array+=("$git_options_all")
        fi
    
        if [[ $count_staged_changes -gt 0 ]]; then
          git_options_array+=("$git_options_staged")
        fi
    
        git_options_array+=( "$git_options_select_files" )
        git_options_array+=( "$git_options_cancel" )
    
    
        selection=$(gum choose "''${git_options_array[@]}")
        if [[ "$selection" == "$git_options_cancel" ]]; then
          do_cancel
        fi
    
        if [[ "$selection" == "$git_options_all" ]]; then
          git add -A
          echo "1"
        elif [[ "$selection" == "$git_options_select_files" ]]; then
    
          files=()
          while IFS= read -r line; do
            files+=("$line")
          done <<<"$git_status"
            
          selected_files=$(gum choose --no-limit "''${files[@]}")
          
          # no files selected
          if [[ -z "$selected_files" ]]; then
            log_and_display "No files selected. Exiting."
            printLogfileAndExit 0
          fi
    
          # add selected files
          while IFS= read -r line; do
            ## git proclimne could have letter, ? or ! at the beginning of the line
            file=$(echo "$line" | awk '{print $2}')
            if [[ -z "$file" || ! -f "$file" ]]; then
              log_and_display "No file found in line: $line"
              continue
            fi
            
            git add "$file"
          done <<<"$selected_files"
          
        fi
    
        ## count staged changes again and print
        count_staged_changes=$(echo "$git_status" | grep -c '^M')
        count_new_staged_files=$(echo "$git_status" | grep -c '^A')
        count_staged_changes=$((count_staged_changes + count_new_staged_files))
    
        log_and_display "You have $count_staged_changes staged changes to commit."
    
        # NEXT STEP COMMIT MESSAGE ############################################################################################################
    
        print_headline "Enter commit message"
        commit_message=$(gum input --placeholder "Enter commit message" --value "$commit_type: $issue_text $work_on_issue_ids_string")
    
        if [[ -z "$commit_message" ]]; then
          log_error_and_display "Commit message is empty. Exiting."
          printLogfileAndExit 1
        fi
    
        log_and_display "You entered the commit message: $commit_message"
    
        gum confirm "Do you want to commit with this message?"
        if [ $? -eq 1 ]; then
          do_cancel
        fi
    
        # NEXT STEP COMMIT ####################################################################################################################
        print_headline "Committing changes"
    
        if ! git commit -m "$commit_message" ; then
          log_error_and_display "Commit failed. Exiting."
          printLogfileAndExit 1
        fi
    
        log_and_display "Commit successful."
    
        # NEXT STEP PUSH ######################################################################################################################
    
        print_headline "Pushing changes"
    
        if ! git push ; then
          log_error_and_display "Push failed. Exiting."
          printLogfileAndExit 1
        fi
    
        log_and_display "Push successful."
    
        # Close issue ######################################################################################################################
    
        print_headline "Closing issues"
    
        for issue_id in "''${work_on_issue_ids[@]}"; do
          
          gum confirm "Do you want to close issue #$issue_id?"
          if [ $? -eq 1 ]; then
            continue
          fi
          
          if ! glab issue close "$issue_id" ; then
            log_error_and_display "Closing issue $issue_id failed. Exiting."
          else
            log_and_display "Closing issue $issue_id successful."  
          fi
        done
    
        printLogfileAndExit 0
      '';
    
    
    }