From d1adcb1188b5fef92580da3133fe501036484866 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 28 Sep 2025 19:47:15 +0000 Subject: [PATCH 1/8] Update --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 235662a..b810ad0 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ backend/.env frontend/node_modules docker-compose.dev.yml scripts/docker-release.sh +scripts/dev-script.sh \ No newline at end of file From 03b3766a22cafa2657b0554ba3cf005461a56128 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 29 Sep 2025 07:16:21 +0000 Subject: [PATCH 2/8] Update --- .gitignore | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index b810ad0..7955269 100644 --- a/.gitignore +++ b/.gitignore @@ -11,5 +11,13 @@ backend/node_modules backend/.env frontend/node_modules docker-compose.dev.yml +scripts/dev-script.sh scripts/docker-release.sh -scripts/dev-script.sh \ No newline at end of file +scripts/git-push.sh +scripts/merge-dev-to-master.sh +scripts/merge-feature-to-dev.sh +scripts/new-feature.sh +scripts/stash.sh +scripts/switch-branch.sh + + From 2e7ebfe06d538c658792ac94fb4942a4ca2d6826 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 29 Sep 2025 07:17:07 +0000 Subject: [PATCH 3/8] Update --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 7955269..a3adef2 100644 --- a/.gitignore +++ b/.gitignore @@ -19,5 +19,5 @@ scripts/merge-feature-to-dev.sh scripts/new-feature.sh scripts/stash.sh scripts/switch-branch.sh - +backup From 47f632f8fc12ea10b3c46432a888fd0c829125c2 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 29 Sep 2025 07:17:47 +0000 Subject: [PATCH 4/8] Update --- .gitignore | 9 +-------- scripts/docker-release.sh | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 8 deletions(-) create mode 100755 scripts/docker-release.sh diff --git a/.gitignore b/.gitignore index a3adef2..055f1ae 100644 --- a/.gitignore +++ b/.gitignore @@ -11,13 +11,6 @@ backend/node_modules backend/.env frontend/node_modules docker-compose.dev.yml -scripts/dev-script.sh -scripts/docker-release.sh -scripts/git-push.sh -scripts/merge-dev-to-master.sh -scripts/merge-feature-to-dev.sh -scripts/new-feature.sh -scripts/stash.sh -scripts/switch-branch.sh + backup diff --git a/scripts/docker-release.sh b/scripts/docker-release.sh new file mode 100755 index 0000000..d584e68 --- /dev/null +++ b/scripts/docker-release.sh @@ -0,0 +1,36 @@ +#!/bin/bash +set -e + +# --- Konfiguration --- +GHCR_USERNAME="mboehmlaender" +REPO_NAME="stackpulse" + +# --- Branch prüfen --- +BRANCH=$(git rev-parse --abbrev-ref HEAD) +if [[ "$BRANCH" != "master" ]]; then + echo "Fehler: Du musst auf 'master' sein, um ein Release zu machen." + exit 1 +fi + +# --- Versionsnummer abfragen --- +while true; do + read -p "Bitte Versionsnummer für das Docker-Image eingeben (z.B. v0.1): " VERSION_TAG + if [[ -n "$VERSION_TAG" ]]; then break; else echo "Versionsnummer darf nicht leer sein."; fi +done + +# --- Docker: Login --- +if [ -z "$CR_PAT" ]; then + echo "CR_PAT (GitHub Token) nicht gesetzt! Bitte export CR_PAT=" + exit 1 +fi +echo $CR_PAT | docker login ghcr.io -u $GHCR_USERNAME --password-stdin + +# --- Docker: Build & Tag --- +docker build -t ghcr.io/$GHCR_USERNAME/$REPO_NAME:$VERSION_TAG . +docker tag ghcr.io/$GHCR_USERNAME/$REPO_NAME:$VERSION_TAG ghcr.io/$GHCR_USERNAME/$REPO_NAME:latest + +# --- Docker: Push --- +docker push ghcr.io/$GHCR_USERNAME/$REPO_NAME:$VERSION_TAG +docker push ghcr.io/$GHCR_USERNAME/$REPO_NAME:latest + +echo "Docker-Release $VERSION_TAG erfolgreich gebaut und zu GHCR gepusht!" From 429721d9da02af066a0bb43c5292af405e75cf39 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 29 Sep 2025 07:18:22 +0000 Subject: [PATCH 5/8] Update --- scripts/dev-script.sh | 447 -------------------------------- scripts/docker-release.sh | 36 --- scripts/git-push.sh | 48 ---- scripts/merge-dev-to-master.sh | 22 -- scripts/merge-feature-to-dev.sh | 41 --- scripts/new-feature.sh | 55 ---- scripts/stash.sh | 138 ---------- scripts/switch-branch.sh | 87 ------- 8 files changed, 874 deletions(-) delete mode 100755 scripts/dev-script.sh delete mode 100755 scripts/docker-release.sh delete mode 100755 scripts/git-push.sh delete mode 100755 scripts/merge-dev-to-master.sh delete mode 100755 scripts/merge-feature-to-dev.sh delete mode 100755 scripts/new-feature.sh delete mode 100755 scripts/stash.sh delete mode 100755 scripts/switch-branch.sh diff --git a/scripts/dev-script.sh b/scripts/dev-script.sh deleted file mode 100755 index cca4b1e..0000000 --- a/scripts/dev-script.sh +++ /dev/null @@ -1,447 +0,0 @@ -#!/bin/bash -set -e - -# ===================================== -# StackPulse Dev-Skript – Hauptmenü & Aktionen -# ===================================== - -show_menu() { - cat <<'MENU' -Bitte wähle eine Aktion: - - 1) Neues Feature anlegen - 2) Feature-Branch in dev mergen - 3) dev in master mergen - 4) Änderungen committen & pushen - 5) Docker-Release bauen & pushen - 6) Dev-Umgebung starten - 7) Git-Stashes verwalten - 8) Branch wechseln - 0) Beenden -MENU -} - -pause_for_menu() { - echo "" - read -rp "Zurück zum Hauptmenü mit Enter... " _ -} - -create_new_feature() { - local master_branch="master" - local feature_name feature_branch base_commit - - read -rp "Bitte den Namen des neuen Features eingeben: " feature_name - if [[ -z "$feature_name" ]]; then - echo "❌ Fehler: Kein Feature-Name angegeben." - return 1 - fi - - if [[ "$feature_name" =~ [^a-zA-Z0-9._-] ]]; then - echo "❌ Fehler: Ungültiger Branch-Name. Erlaubt sind Buchstaben, Zahlen, Punkt, Unterstrich oder Bindestrich." - return 1 - fi - - feature_branch="feature/$feature_name" - - if ! git diff-index --quiet HEAD --; then - echo "⚠️ Es gibt noch uncommittete Änderungen. Bitte committen oder stashen, bevor ein neuer Branch erstellt wird." - return 1 - fi - - if git show-ref --verify --quiet "refs/heads/$feature_branch"; then - echo "❌ Fehler: Der Branch '$feature_branch' existiert lokal bereits." - return 1 - fi - - if git ls-remote --heads origin "$feature_branch" | grep -q "$feature_branch"; then - echo "❌ Fehler: Der Branch '$feature_branch' existiert bereits auf Remote." - return 1 - fi - - git checkout "$master_branch" - git pull origin "$master_branch" - - git checkout -b "$feature_branch" "$master_branch" - git push -u origin "$feature_branch" - - base_commit=$(git rev-parse --short HEAD) - - echo "✅ Neuer Feature-Branch '$feature_branch' wurde erstellt und auf Remote gepusht." - echo " Basis: $master_branch@$base_commit" -} - -merge_feature_into_dev() { - local dev_branch="dev" - local feature_branch - local -a branch_array - local choice index=1 - - echo "Verfügbare Feature-Branches:" - mapfile -t branch_array < <(git for-each-ref --format='%(refname:lstrip=2)' 'refs/remotes/origin/feature/*') || true - - if [[ ${#branch_array[@]} -eq 0 ]]; then - echo "Keine Feature-Branches gefunden." - return 0 - fi - - for feature_branch in "${branch_array[@]}"; do - echo " $index) $feature_branch" - ((index++)) - done - - read -rp "Bitte Nummer wählen: " choice - if ! [[ "$choice" =~ ^[0-9]+$ ]] || (( choice < 1 || choice > ${#branch_array[@]} )); then - echo "Ungültige Auswahl." - return 1 - fi - - feature_branch=${branch_array[choice-1]} - echo "Ausgewählter Feature-Branch: $feature_branch" - - git checkout "$dev_branch" - git pull origin "$dev_branch" - - git checkout "$feature_branch" - git pull origin "$feature_branch" - - git checkout "$dev_branch" - git merge --no-ff "$feature_branch" -m "Merge $feature_branch into $dev_branch" - - git push origin "$dev_branch" - echo "Feature $feature_branch wurde erfolgreich in $dev_branch gemerged." -} - -merge_dev_into_master() { - local dev_branch="dev" - local master_branch="master" - - git checkout "$master_branch" - git pull origin "$master_branch" - - git checkout "$dev_branch" - git pull origin "$dev_branch" - - git checkout "$master_branch" - git merge --no-ff "$dev_branch" -m "Merge $dev_branch into $master_branch" - - git push origin "$master_branch" - echo "Branch $dev_branch wurde in $master_branch gemerged." -} - -push_changes() { - local branch commit_msg version_tag confirm - - branch=$(git rev-parse --abbrev-ref HEAD) - read -rp "Aktueller Branch: $branch. Ist das korrekt? (y/n): " confirm - if [[ "$confirm" != "y" && "$confirm" != "Y" ]]; then - echo "Abgebrochen." - return 1 - fi - - read -rp "Bitte Commit-Nachricht eingeben (default: 'Update'): " commit_msg - commit_msg=${commit_msg:-Update} - - echo "Änderungen werden gestaged..." - git add . - echo "Commit wird erstellt..." - git commit -m "$commit_msg" || echo "Nichts zu committen" - - if [[ "$branch" == "master" ]]; then - while true; do - read -rp "Bitte Versionsnummer für Master-Release Tag eingeben (z.B. v0.2.0): " version_tag - if [[ -n "$version_tag" ]]; then - break - fi - echo "Versionsnummer darf nicht leer sein." - done - fi - - echo "Push nach origin/$branch..." - git push origin "$branch" - - if [[ "$branch" == "master" ]]; then - git tag -a "$version_tag" -m "Release $version_tag" - git push origin "$version_tag" - echo "Tag $version_tag gesetzt und gepusht." - fi - - echo "Push abgeschlossen." -} - -docker_release() { - local ghcr_username="mboehmlaender" - local repo_name="stackpulse" - local branch version_tag - - branch=$(git rev-parse --abbrev-ref HEAD) - if [[ "$branch" != "master" ]]; then - echo "Fehler: Du musst auf 'master' sein, um ein Release zu machen." - return 1 - fi - - while true; do - read -rp "Bitte Versionsnummer für das Docker-Image eingeben (z.B. v0.1): " version_tag - if [[ -n "$version_tag" ]]; then - break - fi - echo "Versionsnummer darf nicht leer sein." - done - - if [[ -z "$CR_PAT" ]]; then - echo "CR_PAT (GitHub Token) nicht gesetzt! Bitte export CR_PAT=" - return 1 - fi - - echo "$CR_PAT" | docker login ghcr.io -u "$ghcr_username" --password-stdin - docker build -t "ghcr.io/$ghcr_username/$repo_name:$version_tag" . - docker tag "ghcr.io/$ghcr_username/$repo_name:$version_tag" "ghcr.io/$ghcr_username/$repo_name:latest" - - docker push "ghcr.io/$ghcr_username/$repo_name:$version_tag" - docker push "ghcr.io/$ghcr_username/$repo_name:latest" - - echo "Docker-Release $version_tag erfolgreich gebaut und zu GHCR gepusht!" -} - -start_dev_environment() { - local back_pid front_pid - - echo "🚀 Starte StackPulse Dev-Umgebung..." - - pushd backend >/dev/null - npm install - npm start & - back_pid=$! - popd >/dev/null - - pushd frontend >/dev/null - npm install - npm run dev & - front_pid=$! - npm run build - popd >/dev/null - - echo "" - echo "✅ StackPulse läuft lokal:" - echo "Frontend (Vite Dev): http://localhost:5173" - echo "Backend API: http://localhost:4001" - echo "Beenden mit STRG+C" - - wait "$back_pid" "$front_pid" -} - -manage_stash() { - local current_branch action user_input stash_name choice selected_stash - local -A stash_map - local -a stash_list - local i line stash_ref stash_msg - - current_branch=$(git rev-parse --abbrev-ref HEAD) - - echo "Aktueller Branch: $current_branch" - echo "Was möchtest du tun?" - echo "1) Neuen Stash anlegen" - echo "2) Vorhandenen Stash laden (apply)" - echo "3) Vorhandenen Stash löschen" - echo "4) Stash anwenden und löschen (pop)" - read -rp "Auswahl: " action - - case $action in - 1) - read -rp "Gib einen Namen für den Stash ein: " user_input - stash_name="$current_branch - $user_input" - - if git stash list | grep -q "$stash_name"; then - while IFS= read -r line; do - stash_ref=$(echo "$line" | awk -F: '{print $1}') - echo "Lösche vorhandenen Stash: $stash_ref" - git stash drop "$stash_ref" - done < <(git stash list | grep "$stash_name") - fi - - git stash push -u -m "$stash_name" - echo "Stash '$stash_name' wurde angelegt." - ;; - - 2|3|4) - local action_text - case $action in - 2) action_text="laden" ;; - 3) action_text="löschen" ;; - 4) action_text="anwenden & löschen" ;; - esac - - echo "Liste aller Stashes für Branch '$current_branch':" - mapfile -t stash_list < <(git stash list | grep "$current_branch") || true - - if [[ ${#stash_list[@]} -eq 0 ]]; then - echo "Keine Stashes für diesen Branch vorhanden." - return 0 - fi - - i=1 - for line in "${stash_list[@]}"; do - stash_ref=$(echo "$line" | awk -F: '{print $1}') - stash_msg=$(echo "$line" | cut -d':' -f3- | sed 's/^ //') - echo " $i) $stash_ref -> $stash_msg" - stash_map[$i]=$stash_ref - ((i++)) - done - - read -rp "Wähle einen Stash zum ${action_text} (Nummer): " choice - if [[ -z "${stash_map[$choice]}" ]]; then - echo "Ungültige Auswahl!" - return 1 - fi - - selected_stash=${stash_map[$choice]} - - case $action in - 2) - echo "Wende Stash an: $selected_stash" - git stash apply "$selected_stash" - ;; - 3) - echo "Lösche Stash: $selected_stash" - git stash drop "$selected_stash" - ;; - 4) - echo "Wende Stash an und lösche ihn: $selected_stash" - git stash pop "$selected_stash" - ;; - esac - ;; - - *) - echo "Ungültige Auswahl!" - return 1 - ;; - esac -} - -switch_branch() { - local -a unversioned_files=("scripts/dev-script.sh") - local file - local local_branches remote_branches all_branches master_branch dev_branch feature_branches - local -a sorted_branches - local i=1 choice selected_branch - declare -A branch_map - - for file in "${unversioned_files[@]}"; do - if [[ -f "$file" ]]; then - mkdir -p /tmp/git_safe_backup - cp "$file" "/tmp/git_safe_backup/$(basename "$file")" - fi - done - - local_branches=$(git branch | sed 's/* //' | sed 's/^[[:space:]]*//') - remote_branches=$(git branch -r | grep -v 'HEAD' | sed 's|^[[:space:]]*origin/||' | sed 's/^[[:space:]]*//') - all_branches=$(printf "%s\n%s\n" "$local_branches" "$remote_branches" | sort -u) - - master_branch=$(echo "$all_branches" | grep -x 'master' || true) - dev_branch=$(echo "$all_branches" | grep -x 'dev' || true) - feature_branches=$(echo "$all_branches" | grep '^feature/' | sort || true) - - [[ -n "$master_branch" ]] && sorted_branches+=("$master_branch") - [[ -n "$dev_branch" ]] && sorted_branches+=("$dev_branch") - if [[ -n "$feature_branches" ]]; then - while IFS= read -r line; do - [[ -n "$line" ]] && sorted_branches+=("$line") - done <<< "$feature_branches" - fi - - if [[ ${#sorted_branches[@]} -eq 0 ]]; then - echo "Keine Branches gefunden." - return 1 - fi - - echo "Verfügbare Branches:" - for line in "${sorted_branches[@]}"; do - echo " $i) $line" - branch_map[$i]=$line - ((i++)) - done - - read -rp "Wähle einen Branch (Nummer): " choice - if [[ -z "${branch_map[$choice]}" ]]; then - echo "Ungültige Auswahl!" - return 1 - fi - - selected_branch=${branch_map[$choice]} - echo "Wechsle zu Branch: $selected_branch" - - git fetch origin - - if git show-ref --verify --quiet "refs/heads/$selected_branch"; then - git checkout "$selected_branch" - else - git checkout -b "$selected_branch" "origin/$selected_branch" - fi - - git reset --hard "origin/$selected_branch" - git clean -fd - - for file in "${unversioned_files[@]}"; do - if [[ -f "/tmp/git_safe_backup/$(basename "$file")" ]]; then - mkdir -p "$(dirname "$file")" - mv "/tmp/git_safe_backup/$(basename "$file")" "$file" - fi - done - rm -rf /tmp/git_safe_backup - - echo "Branch '$selected_branch' ist nun aktiv. Arbeitsverzeichnis entspricht exakt dem Remote-Stand." - echo "Gesicherte Dateien wurden wiederhergestellt." -} - -main() { - local selection - while true; do - echo "" - show_menu - read -rp "Auswahl: " selection - echo "" - case $selection in - 1) - create_new_feature - pause_for_menu - ;; - 2) - merge_feature_into_dev - pause_for_menu - ;; - 3) - merge_dev_into_master - pause_for_menu - ;; - 4) - push_changes - pause_for_menu - ;; - 5) - docker_release - pause_for_menu - ;; - 6) - start_dev_environment - pause_for_menu - ;; - 7) - manage_stash - pause_for_menu - ;; - 8) - switch_branch - pause_for_menu - ;; - 0) - echo "Auf Wiedersehen!" - exit 0 - ;; - *) - echo "❌ Ungültige Auswahl." - ;; - esac - done -} - -main "$@" diff --git a/scripts/docker-release.sh b/scripts/docker-release.sh deleted file mode 100755 index d584e68..0000000 --- a/scripts/docker-release.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash -set -e - -# --- Konfiguration --- -GHCR_USERNAME="mboehmlaender" -REPO_NAME="stackpulse" - -# --- Branch prüfen --- -BRANCH=$(git rev-parse --abbrev-ref HEAD) -if [[ "$BRANCH" != "master" ]]; then - echo "Fehler: Du musst auf 'master' sein, um ein Release zu machen." - exit 1 -fi - -# --- Versionsnummer abfragen --- -while true; do - read -p "Bitte Versionsnummer für das Docker-Image eingeben (z.B. v0.1): " VERSION_TAG - if [[ -n "$VERSION_TAG" ]]; then break; else echo "Versionsnummer darf nicht leer sein."; fi -done - -# --- Docker: Login --- -if [ -z "$CR_PAT" ]; then - echo "CR_PAT (GitHub Token) nicht gesetzt! Bitte export CR_PAT=" - exit 1 -fi -echo $CR_PAT | docker login ghcr.io -u $GHCR_USERNAME --password-stdin - -# --- Docker: Build & Tag --- -docker build -t ghcr.io/$GHCR_USERNAME/$REPO_NAME:$VERSION_TAG . -docker tag ghcr.io/$GHCR_USERNAME/$REPO_NAME:$VERSION_TAG ghcr.io/$GHCR_USERNAME/$REPO_NAME:latest - -# --- Docker: Push --- -docker push ghcr.io/$GHCR_USERNAME/$REPO_NAME:$VERSION_TAG -docker push ghcr.io/$GHCR_USERNAME/$REPO_NAME:latest - -echo "Docker-Release $VERSION_TAG erfolgreich gebaut und zu GHCR gepusht!" diff --git a/scripts/git-push.sh b/scripts/git-push.sh deleted file mode 100755 index b61143b..0000000 --- a/scripts/git-push.sh +++ /dev/null @@ -1,48 +0,0 @@ -#!/bin/bash -set -e - -# Aktuellen Branch herausfinden -BRANCH=$(git rev-parse --abbrev-ref HEAD) - -# Branch bestätigen -read -p "Aktueller Branch: $BRANCH. Ist das korrekt? (y/n): " CONFIRM -if [[ "$CONFIRM" != "y" && "$CONFIRM" != "Y" ]]; then - echo "Abgebrochen." - exit 1 -fi - -# Commit-Nachricht -read -p "Bitte Commit-Nachricht eingeben (default: 'Update'): " COMMIT_MSG -COMMIT_MSG=${COMMIT_MSG:-Update} - -# Änderungen stagen und committen -echo "Änderungen werden gestaged..." -git add . -echo "Commit wird erstellt..." -git commit -m "$COMMIT_MSG" || echo "Nichts zu committen" - -# Prüfen, ob Branch master ist -if [[ "$BRANCH" == "master" ]]; then - # Versionsnummer verpflichtend abfragen - while true; do - read -p "Bitte Versionsnummer für Master-Release Tag eingeben (z.B. v0.2.0): " VERSION_TAG - if [[ -n "$VERSION_TAG" ]]; then - break - else - echo "Versionsnummer darf nicht leer sein. Bitte eingeben." - fi - done -fi - -# Push Branch -echo "Push nach origin/$BRANCH..." -git push origin "$BRANCH" - -# Tag setzen und pushen, nur bei master -if [[ "$BRANCH" == "master" ]]; then - git tag -a "$VERSION_TAG" -m "Release $VERSION_TAG" - git push origin "$VERSION_TAG" - echo "Tag $VERSION_TAG gesetzt und gepusht." -fi - -echo "Push abgeschlossen." diff --git a/scripts/merge-dev-to-master.sh b/scripts/merge-dev-to-master.sh deleted file mode 100755 index 1fcace4..0000000 --- a/scripts/merge-dev-to-master.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash -# Skript: Dev in Master mergen - -DEV_BRANCH="dev" -MASTER_BRANCH="master" - -# Auf master wechseln und aktuell holen -git checkout $MASTER_BRANCH -git pull origin $MASTER_BRANCH - -# Dev aktuell holen -git checkout $DEV_BRANCH -git pull origin $DEV_BRANCH - -# Merge Dev in Master -git checkout $MASTER_BRANCH -git merge --no-ff $DEV_BRANCH -m "Merge $DEV_BRANCH into $MASTER_BRANCH" - -# Push Master auf Remote -git push origin $MASTER_BRANCH - -echo "Branch $DEV_BRANCH wurde in $MASTER_BRANCH gemerged." \ No newline at end of file diff --git a/scripts/merge-feature-to-dev.sh b/scripts/merge-feature-to-dev.sh deleted file mode 100755 index dc9d7cc..0000000 --- a/scripts/merge-feature-to-dev.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/bash -# Skript: Feature in Dev mergen mit Auswahl der Feature-Branches - -DEV_BRANCH="dev" - -# Auflisten aller Feature-Branches (lokal und remote) -echo "Verfügbare Feature-Branches:" -FEATURE_BRANCHES=$(git branch -r | grep 'origin/feature/' | sed 's|origin/||') -PS3="Bitte wähle einen Feature-Branch zum Mergen: " - -# in ein Array konvertieren -BRANCH_ARRAY=($FEATURE_BRANCHES) - -# Auswahlmenü anzeigen -select CHOSEN_BRANCH in "${BRANCH_ARRAY[@]}"; do - if [[ -n "$CHOSEN_BRANCH" ]]; then - FEATURE_BRANCH=$CHOSEN_BRANCH - break - else - echo "Ungültige Auswahl. Bitte erneut versuchen." - fi -done - -echo "Ausgewählter Feature-Branch: $FEATURE_BRANCH" - -# Dev aktuell holen -git checkout $DEV_BRANCH -git pull origin $DEV_BRANCH - -# Feature-Branch aktuell holen -git checkout $FEATURE_BRANCH -git pull origin $FEATURE_BRANCH - -# Merge Feature in Dev -git checkout $DEV_BRANCH -git merge --no-ff $FEATURE_BRANCH -m "Merge $FEATURE_BRANCH into $DEV_BRANCH" - -# Push Dev auf Remote -git push origin $DEV_BRANCH - -echo "Feature $FEATURE_BRANCH wurde erfolgreich in $DEV_BRANCH gemerged." diff --git a/scripts/new-feature.sh b/scripts/new-feature.sh deleted file mode 100755 index ced79b4..0000000 --- a/scripts/new-feature.sh +++ /dev/null @@ -1,55 +0,0 @@ -#!/bin/bash -# Skript: Neues Feature erstellen - -MASTER_BRANCH="master" - -# Abfrage Feature-Name -read -p "Bitte den Namen des neuen Features eingeben: " FEATURE_NAME - -# Falls nichts eingegeben wurde, Skript abbrechen -if [ -z "$FEATURE_NAME" ]; then - echo "❌ Fehler: Kein Feature-Name angegeben." - exit 1 -fi - -# Validierung: nur erlaubte Zeichen -if [[ "$FEATURE_NAME" =~ [^a-zA-Z0-9._-] ]]; then - echo "❌ Fehler: Ungültiger Branch-Name. Bitte nur Buchstaben, Zahlen, Punkt, Unterstrich oder Bindestrich verwenden." - exit 1 -fi - -FEATURE_BRANCH="feature/$FEATURE_NAME" - -# Check auf uncommittete Änderungen -if ! git diff-index --quiet HEAD --; then - echo "⚠️ Es gibt noch uncommittete Änderungen. Bitte committen oder stashen, bevor ein neuer Branch erstellt wird." - exit 1 -fi - -# Prüfen, ob Branch lokal schon existiert -if git show-ref --verify --quiet refs/heads/$FEATURE_BRANCH; then - echo "❌ Fehler: Der Branch '$FEATURE_BRANCH' existiert lokal bereits." - exit 1 -fi - -# Prüfen, ob Branch remote schon existiert -if git ls-remote --heads origin $FEATURE_BRANCH | grep -q $FEATURE_BRANCH; then - echo "❌ Fehler: Der Branch '$FEATURE_BRANCH' existiert bereits auf Remote." - exit 1 -fi - -# Auf master wechseln und aktualisieren -git checkout $MASTER_BRANCH -git pull origin $MASTER_BRANCH - -# Neuen Feature-Branch erstellen und auschecken -git checkout -b $FEATURE_BRANCH $MASTER_BRANCH - -# Branch auf Remote pushen -git push -u origin $FEATURE_BRANCH - -# Commit-Hash der Basis holen -BASE_COMMIT=$(git rev-parse --short HEAD) - -echo "✅ Neuer Feature-Branch '$FEATURE_BRANCH' wurde erstellt und auf Remote gepusht." -echo " Basis: $MASTER_BRANCH@$BASE_COMMIT" diff --git a/scripts/stash.sh b/scripts/stash.sh deleted file mode 100755 index e4645d1..0000000 --- a/scripts/stash.sh +++ /dev/null @@ -1,138 +0,0 @@ -#!/bin/bash - -# =============================== -# Git Stash Manager mit Branch-Filter und Überschreiben -# =============================== - -# Aktuellen Branch ermitteln -CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD) - -echo "Aktueller Branch: $CURRENT_BRANCH" -echo "Was möchtest du tun?" -echo "1) Neuen Stash anlegen" -echo "2) Vorhandenen Stash laden (apply)" -echo "3) Vorhandenen Stash löschen" -echo "4) Stash anwenden und löschen (pop)" -read -p "Auswahl: " action - -case $action in - 1) - # ========== Neuen Stash anlegen ========== - read -p "Gib einen Namen für den Stash ein: " USER_INPUT - STASH_NAME="$CURRENT_BRANCH - $USER_INPUT" - - # Prüfen, ob Stash-Name schon existiert - EXISTING=$(git stash list | grep "$STASH_NAME") - if [[ -n "$EXISTING" ]]; then - echo "Ein Stash mit dem Namen '$STASH_NAME' existiert bereits." - # Alle passenden Stashes löschen - while IFS= read -r line; do - STASH_REF=$(echo "$line" | awk -F: '{print $1}') - echo "Lösche vorhandenen Stash: $STASH_REF" - git stash drop "$STASH_REF" - done <<< "$EXISTING" - fi - - # Neuen Stash anlegen (inkl. untracked Dateien) - git stash push -u -m "$STASH_NAME" - echo "Stash '$STASH_NAME' wurde angelegt." - ;; - - 2) - # ========== Stash anwenden ========== - echo "Liste aller Stashes für Branch '$CURRENT_BRANCH':" - STASHES=$(git stash list | grep "$CURRENT_BRANCH") - - if [[ -z "$STASHES" ]]; then - echo "Keine Stashes für diesen Branch vorhanden." - exit 0 - fi - - i=1 - declare -A STASH_MAP - while IFS= read -r line; do - STASH_REF=$(echo "$line" | awk -F: '{print $1}') - STASH_MSG=$(echo "$line" | cut -d':' -f3- | sed 's/^ //') - echo "$i) $STASH_REF -> $STASH_MSG" - STASH_MAP[$i]=$STASH_REF - ((i++)) - done <<< "$STASHES" - - read -p "Wähle einen Stash (Nummer): " choice - if [[ -z "${STASH_MAP[$choice]}" ]]; then - echo "Ungültige Auswahl!" - exit 1 - fi - - SELECTED_STASH=${STASH_MAP[$choice]} - echo "Wende Stash an: $SELECTED_STASH" - git stash apply "$SELECTED_STASH" - ;; - - 3) - # ========== Stash löschen ========== - echo "Liste aller Stashes für Branch '$CURRENT_BRANCH':" - STASHES=$(git stash list | grep "$CURRENT_BRANCH") - - if [[ -z "$STASHES" ]]; then - echo "Keine Stashes für diesen Branch vorhanden." - exit 0 - fi - - i=1 - declare -A STASH_MAP - while IFS= read -r line; do - STASH_REF=$(echo "$line" | awk -F: '{print $1}') - STASH_MSG=$(echo "$line" | cut -d':' -f3- | sed 's/^ //') - echo "$i) $STASH_REF -> $STASH_MSG" - STASH_MAP[$i]=$STASH_REF - ((i++)) - done <<< "$STASHES" - - read -p "Wähle einen Stash zum Löschen (Nummer): " choice - if [[ -z "${STASH_MAP[$choice]}" ]]; then - echo "Ungültige Auswahl!" - exit 1 - fi - - SELECTED_STASH=${STASH_MAP[$choice]} - echo "Lösche Stash: $SELECTED_STASH" - git stash drop "$SELECTED_STASH" - ;; - - 4) - # ========== Stash anwenden und löschen (pop) ========== - echo "Liste aller Stashes für Branch '$CURRENT_BRANCH':" - STASHES=$(git stash list | grep "$CURRENT_BRANCH") - - if [[ -z "$STASHES" ]]; then - echo "Keine Stashes für diesen Branch vorhanden." - exit 0 - fi - - i=1 - declare -A STASH_MAP - while IFS= read -r line; do - STASH_REF=$(echo "$line" | awk -F: '{print $1}') - STASH_MSG=$(echo "$line" | cut -d':' -f3- | sed 's/^ //') - echo "$i) $STASH_REF -> $STASH_MSG" - STASH_MAP[$i]=$STASH_REF - ((i++)) - done <<< "$STASHES" - - read -p "Wähle einen Stash zum Anwenden & Löschen (Nummer): " choice - if [[ -z "${STASH_MAP[$choice]}" ]]; then - echo "Ungültige Auswahl!" - exit 1 - fi - - SELECTED_STASH=${STASH_MAP[$choice]} - echo "Wende Stash an und lösche ihn: $SELECTED_STASH" - git stash pop "$SELECTED_STASH" - ;; - - *) - echo "Ungültige Auswahl!" - exit 1 - ;; -esac diff --git a/scripts/switch-branch.sh b/scripts/switch-branch.sh deleted file mode 100755 index 0249a19..0000000 --- a/scripts/switch-branch.sh +++ /dev/null @@ -1,87 +0,0 @@ -#!/bin/bash - -# =============================== -# Dateien sichern, die nicht gepusht werden -# =============================== -UNVERSIONED_FILES=("scripts/docker-release.sh") -for f in "${UNVERSIONED_FILES[@]}"; do - if [[ -f $f ]]; then - mkdir -p /tmp/git_safe_backup - cp "$f" "/tmp/git_safe_backup/$(basename "$f")" - fi -done - -# =============================== -# Alle Branches sammeln -# =============================== -# Alle lokalen Branches holen, führende Sternchen und Leerzeichen entfernen -LOCAL_BRANCHES=$(git branch | sed 's/* //' | sed 's/^[[:space:]]*//') - -# Alle Remote-Branches holen, 'origin/' entfernen, HEAD ignorieren, führende Leerzeichen entfernen -REMOTE_BRANCHES=$(git branch -r | grep -v 'HEAD' | sed 's|origin/||' | sed 's/^[[:space:]]*//') - -# Beide Listen zusammenführen und Duplikate entfernen -ALL_BRANCHES=$(echo -e "$LOCAL_BRANCHES\n$REMOTE_BRANCHES" | sort -u) - -# Master und dev extrahieren, restliche feature-Branches alphabetisch -MASTER_BRANCH=$(echo "$ALL_BRANCHES" | grep -x 'master') -DEV_BRANCH=$(echo "$ALL_BRANCHES" | grep -x 'dev') -FEATURE_BRANCHES=$(echo "$ALL_BRANCHES" | grep '^feature/' | sort) - -# Zusammenführen -SORTED_BRANCHES=() -[[ -n "$MASTER_BRANCH" ]] && SORTED_BRANCHES+=("$MASTER_BRANCH") -[[ -n "$DEV_BRANCH" ]] && SORTED_BRANCHES+=("$DEV_BRANCH") -for branch in $FEATURE_BRANCHES; do - SORTED_BRANCHES+=("$branch") -done - -# Branches nummerieren -echo "Verfügbare Branches:" -i=1 -declare -A BRANCH_MAP -for branch in "${SORTED_BRANCHES[@]}"; do - echo "$i) $branch" - BRANCH_MAP[$i]=$branch - ((i++)) -done - -# Auswahl abfragen -read -p "Wähle einen Branch (Nummer): " choice - -# Validierung -if [[ -z "${BRANCH_MAP[$choice]}" ]]; then - echo "Ungültige Auswahl!" - exit 1 -fi - -SELECTED_BRANCH=${BRANCH_MAP[$choice]} -echo "Wechsle zu Branch: $SELECTED_BRANCH" - -# Remote-Stand holen -git fetch origin - -# Branch wechseln (lokal erstellen, falls nur remote vorhanden) -if git show-ref --verify --quiet refs/heads/$SELECTED_BRANCH; then - git checkout $SELECTED_BRANCH -else - git checkout -b $SELECTED_BRANCH origin/$SELECTED_BRANCH -fi - -# Arbeitsverzeichnis exakt auf Remote-Branch zurücksetzen -git reset --hard origin/$SELECTED_BRANCH -git clean -fd - -# =============================== -# Gesicherte unversionierte Dateien zurückkopieren -# =============================== -for f in "${UNVERSIONED_FILES[@]}"; do - if [[ -f "/tmp/git_safe_backup/$(basename "$f")" ]]; then - mkdir -p "$(dirname "$f")" - mv "/tmp/git_safe_backup/$(basename "$f")" "$f" - fi -done -rm -rf /tmp/git_safe_backup - -echo "Branch '$SELECTED_BRANCH' ist nun aktiv. Arbeitsverzeichnis entspricht exakt dem Remote-Stand." -echo "Unversionierte Dateien wurden wiederhergestellt." From 281aeb40a6be318182fe0cb6eff5d8dde806a992 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 29 Sep 2025 07:19:01 +0000 Subject: [PATCH 6/8] Update --- .gitignore | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 055f1ae..a3adef2 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,13 @@ backend/node_modules backend/.env frontend/node_modules docker-compose.dev.yml - +scripts/dev-script.sh +scripts/docker-release.sh +scripts/git-push.sh +scripts/merge-dev-to-master.sh +scripts/merge-feature-to-dev.sh +scripts/new-feature.sh +scripts/stash.sh +scripts/switch-branch.sh backup From 3b0bd3c63206405b67146338e5f87b42c514b659 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 29 Sep 2025 07:26:32 +0000 Subject: [PATCH 7/8] Update --- .gitignore | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/.gitignore b/.gitignore index a3adef2..3c440d9 100644 --- a/.gitignore +++ b/.gitignore @@ -11,13 +11,5 @@ backend/node_modules backend/.env frontend/node_modules docker-compose.dev.yml -scripts/dev-script.sh scripts/docker-release.sh -scripts/git-push.sh -scripts/merge-dev-to-master.sh -scripts/merge-feature-to-dev.sh -scripts/new-feature.sh -scripts/stash.sh -scripts/switch-branch.sh -backup - +backup \ No newline at end of file From cd7933ebc76760f6a1d973600312a3c64e76050c Mon Sep 17 00:00:00 2001 From: root Date: Mon, 29 Sep 2025 07:30:23 +0000 Subject: [PATCH 8/8] Update --- .gitignore | 3 +- scripts/dev-script.sh | 447 ++++++++++++++++++++++++++++++++ scripts/git-push.sh | 48 ++++ scripts/merge-dev-to-master.sh | 22 ++ scripts/merge-feature-to-dev.sh | 41 +++ scripts/new-feature.sh | 55 ++++ scripts/stash.sh | 138 ++++++++++ scripts/switch-branch.sh | 87 +++++++ 8 files changed, 839 insertions(+), 2 deletions(-) create mode 100755 scripts/dev-script.sh create mode 100755 scripts/git-push.sh create mode 100755 scripts/merge-dev-to-master.sh create mode 100755 scripts/merge-feature-to-dev.sh create mode 100755 scripts/new-feature.sh create mode 100755 scripts/stash.sh create mode 100755 scripts/switch-branch.sh diff --git a/.gitignore b/.gitignore index 3c440d9..a6a463e 100644 --- a/.gitignore +++ b/.gitignore @@ -11,5 +11,4 @@ backend/node_modules backend/.env frontend/node_modules docker-compose.dev.yml -scripts/docker-release.sh -backup \ No newline at end of file +scripts/docker-release.sh \ No newline at end of file diff --git a/scripts/dev-script.sh b/scripts/dev-script.sh new file mode 100755 index 0000000..0821fd7 --- /dev/null +++ b/scripts/dev-script.sh @@ -0,0 +1,447 @@ +#!/bin/bash +set -e + +# ===================================== +# StackPulse Dev-Skript – Hauptmenü & Aktionen +# ===================================== + +show_menu() { + cat <<'MENU' +Bitte wähle eine Aktion: + + 1) Neues Feature anlegen + 2) Feature-Branch in dev mergen + 3) dev in master mergen + 4) Änderungen committen & pushen + 5) Docker-Release bauen & pushen + 6) Dev-Umgebung starten + 7) Git-Stashes verwalten + 8) Branch wechseln + 0) Beenden +MENU +} + +pause_for_menu() { + echo "" + read -rp "Zurück zum Hauptmenü mit Enter... " _ +} + +create_new_feature() { + local master_branch="master" + local feature_name feature_branch base_commit + + read -rp "Bitte den Namen des neuen Features eingeben: " feature_name + if [[ -z "$feature_name" ]]; then + echo "❌ Fehler: Kein Feature-Name angegeben." + return 1 + fi + + if [[ "$feature_name" =~ [^a-zA-Z0-9._-] ]]; then + echo "❌ Fehler: Ungültiger Branch-Name. Erlaubt sind Buchstaben, Zahlen, Punkt, Unterstrich oder Bindestrich." + return 1 + fi + + feature_branch="feature/$feature_name" + + if ! git diff-index --quiet HEAD --; then + echo "⚠️ Es gibt noch uncommittete Änderungen. Bitte committen oder stashen, bevor ein neuer Branch erstellt wird." + return 1 + fi + + if git show-ref --verify --quiet "refs/heads/$feature_branch"; then + echo "❌ Fehler: Der Branch '$feature_branch' existiert lokal bereits." + return 1 + fi + + if git ls-remote --heads origin "$feature_branch" | grep -q "$feature_branch"; then + echo "❌ Fehler: Der Branch '$feature_branch' existiert bereits auf Remote." + return 1 + fi + + git checkout "$master_branch" + git pull origin "$master_branch" + + git checkout -b "$feature_branch" "$master_branch" + git push -u origin "$feature_branch" + + base_commit=$(git rev-parse --short HEAD) + + echo "✅ Neuer Feature-Branch '$feature_branch' wurde erstellt und auf Remote gepusht." + echo " Basis: $master_branch@$base_commit" +} + +merge_feature_into_dev() { + local dev_branch="dev" + local feature_branch + local -a branch_array + local choice index=1 + + echo "Verfügbare Feature-Branches:" + mapfile -t branch_array < <(git for-each-ref --format='%(refname:lstrip=2)' 'refs/remotes/origin/feature/*') || true + + if [[ ${#branch_array[@]} -eq 0 ]]; then + echo "Keine Feature-Branches gefunden." + return 0 + fi + + for feature_branch in "${branch_array[@]}"; do + echo " $index) $feature_branch" + ((index++)) + done + + read -rp "Bitte Nummer wählen: " choice + if ! [[ "$choice" =~ ^[0-9]+$ ]] || (( choice < 1 || choice > ${#branch_array[@]} )); then + echo "Ungültige Auswahl." + return 1 + fi + + feature_branch=${branch_array[choice-1]} + echo "Ausgewählter Feature-Branch: $feature_branch" + + git checkout "$dev_branch" + git pull origin "$dev_branch" + + git checkout "$feature_branch" + git pull origin "$feature_branch" + + git checkout "$dev_branch" + git merge --no-ff "$feature_branch" -m "Merge $feature_branch into $dev_branch" + + git push origin "$dev_branch" + echo "Feature $feature_branch wurde erfolgreich in $dev_branch gemerged." +} + +merge_dev_into_master() { + local dev_branch="dev" + local master_branch="master" + + git checkout "$master_branch" + git pull origin "$master_branch" + + git checkout "$dev_branch" + git pull origin "$dev_branch" + + git checkout "$master_branch" + git merge --no-ff "$dev_branch" -m "Merge $dev_branch into $master_branch" + + git push origin "$master_branch" + echo "Branch $dev_branch wurde in $master_branch gemerged." +} + +push_changes() { + local branch commit_msg version_tag confirm + + branch=$(git rev-parse --abbrev-ref HEAD) + read -rp "Aktueller Branch: $branch. Ist das korrekt? (y/n): " confirm + if [[ "$confirm" != "y" && "$confirm" != "Y" ]]; then + echo "Abgebrochen." + return 1 + fi + + read -rp "Bitte Commit-Nachricht eingeben (default: 'Update'): " commit_msg + commit_msg=${commit_msg:-Update} + + echo "Änderungen werden gestaged..." + git add . + echo "Commit wird erstellt..." + git commit -m "$commit_msg" || echo "Nichts zu committen" + + if [[ "$branch" == "master" ]]; then + while true; do + read -rp "Bitte Versionsnummer für Master-Release Tag eingeben (z.B. v0.2.0): " version_tag + if [[ -n "$version_tag" ]]; then + break + fi + echo "Versionsnummer darf nicht leer sein." + done + fi + + echo "Push nach origin/$branch..." + git push origin "$branch" + + if [[ "$branch" == "master" ]]; then + git tag -a "$version_tag" -m "Release $version_tag" + git push origin "$version_tag" + echo "Tag $version_tag gesetzt und gepusht." + fi + + echo "Push abgeschlossen." +} + +docker_release() { + local ghcr_username="mboehmlaender" + local repo_name="stackpulse" + local branch version_tag + + branch=$(git rev-parse --abbrev-ref HEAD) + if [[ "$branch" != "master" ]]; then + echo "Fehler: Du musst auf 'master' sein, um ein Release zu machen." + return 1 + fi + + while true; do + read -rp "Bitte Versionsnummer für das Docker-Image eingeben (z.B. v0.1): " version_tag + if [[ -n "$version_tag" ]]; then + break + fi + echo "Versionsnummer darf nicht leer sein." + done + + if [[ -z "$CR_PAT" ]]; then + echo "CR_PAT (GitHub Token) nicht gesetzt! Bitte export CR_PAT=" + return 1 + fi + + echo "$CR_PAT" | docker login ghcr.io -u "$ghcr_username" --password-stdin + docker build -t "ghcr.io/$ghcr_username/$repo_name:$version_tag" . + docker tag "ghcr.io/$ghcr_username/$repo_name:$version_tag" "ghcr.io/$ghcr_username/$repo_name:latest" + + docker push "ghcr.io/$ghcr_username/$repo_name:$version_tag" + docker push "ghcr.io/$ghcr_username/$repo_name:latest" + + echo "Docker-Release $version_tag erfolgreich gebaut und zu GHCR gepusht!" +} + +start_dev_environment() { + local back_pid front_pid + + echo "🚀 Starte StackPulse Dev-Umgebung..." + + pushd backend >/dev/null + npm install + npm start & + back_pid=$! + popd >/dev/null + + pushd frontend >/dev/null + npm install + npm run dev & + front_pid=$! + npm run build + popd >/dev/null + + echo "" + echo "✅ StackPulse läuft lokal:" + echo "Frontend (Vite Dev): http://localhost:5173" + echo "Backend API: http://localhost:4001" + echo "Beenden mit STRG+C" + + wait "$back_pid" "$front_pid" +} + +manage_stash() { + local current_branch action user_input stash_name choice selected_stash + local -A stash_map + local -a stash_list + local i line stash_ref stash_msg + + current_branch=$(git rev-parse --abbrev-ref HEAD) + + echo "Aktueller Branch: $current_branch" + echo "Was möchtest du tun?" + echo "1) Neuen Stash anlegen" + echo "2) Vorhandenen Stash laden (apply)" + echo "3) Vorhandenen Stash löschen" + echo "4) Stash anwenden und löschen (pop)" + read -rp "Auswahl: " action + + case $action in + 1) + read -rp "Gib einen Namen für den Stash ein: " user_input + stash_name="$current_branch - $user_input" + + if git stash list | grep -q "$stash_name"; then + while IFS= read -r line; do + stash_ref=$(echo "$line" | awk -F: '{print $1}') + echo "Lösche vorhandenen Stash: $stash_ref" + git stash drop "$stash_ref" + done < <(git stash list | grep "$stash_name") + fi + + git stash push -u -m "$stash_name" + echo "Stash '$stash_name' wurde angelegt." + ;; + + 2|3|4) + local action_text + case $action in + 2) action_text="laden" ;; + 3) action_text="löschen" ;; + 4) action_text="anwenden & löschen" ;; + esac + + echo "Liste aller Stashes für Branch '$current_branch':" + mapfile -t stash_list < <(git stash list | grep "$current_branch") || true + + if [[ ${#stash_list[@]} -eq 0 ]]; then + echo "Keine Stashes für diesen Branch vorhanden." + return 0 + fi + + i=1 + for line in "${stash_list[@]}"; do + stash_ref=$(echo "$line" | awk -F: '{print $1}') + stash_msg=$(echo "$line" | cut -d':' -f3- | sed 's/^ //') + echo " $i) $stash_ref -> $stash_msg" + stash_map[$i]=$stash_ref + ((i++)) + done + + read -rp "Wähle einen Stash zum ${action_text} (Nummer): " choice + if [[ -z "${stash_map[$choice]}" ]]; then + echo "Ungültige Auswahl!" + return 1 + fi + + selected_stash=${stash_map[$choice]} + + case $action in + 2) + echo "Wende Stash an: $selected_stash" + git stash apply "$selected_stash" + ;; + 3) + echo "Lösche Stash: $selected_stash" + git stash drop "$selected_stash" + ;; + 4) + echo "Wende Stash an und lösche ihn: $selected_stash" + git stash pop "$selected_stash" + ;; + esac + ;; + + *) + echo "Ungültige Auswahl!" + return 1 + ;; + esac +} + +switch_branch() { + local -a unversioned_files=("scripts/dev-script.sh") + local file + local local_branches remote_branches all_branches master_branch dev_branch feature_branches + local -a sorted_branches + local i=1 choice selected_branch + declare -A branch_map + + for file in "${unversioned_files[@]}"; do + if [[ -f "$file" ]]; then + mkdir -p /tmp/git_safe_backup + cp "$file" "/tmp/git_safe_backup/$(basename "$file")" + fi + done + + local_branches=$(git branch | sed 's/* //' | sed 's/^[[:space:]]*//') + remote_branches=$(git branch -r | grep -v 'HEAD' | sed 's|^[[:space:]]*origin/||' | sed 's/^[[:space:]]*//') + all_branches=$(printf "%s\n%s\n" "$local_branches" "$remote_branches" | sort -u) + + master_branch=$(echo "$all_branches" | grep -x 'master' || true) + dev_branch=$(echo "$all_branches" | grep -x 'dev' || true) + feature_branches=$(echo "$all_branches" | grep '^feature/' | sort || true) + + [[ -n "$master_branch" ]] && sorted_branches+=("$master_branch") + [[ -n "$dev_branch" ]] && sorted_branches+=("$dev_branch") + if [[ -n "$feature_branches" ]]; then + while IFS= read -r line; do + [[ -n "$line" ]] && sorted_branches+=("$line") + done <<< "$feature_branches" + fi + + if [[ ${#sorted_branches[@]} -eq 0 ]]; then + echo "Keine Branches gefunden." + return 1 + fi + + echo "Verfügbare Branches:" + for line in "${sorted_branches[@]}"; do + echo " $i) $line" + branch_map[$i]=$line + ((i++)) + done + + read -rp "Wähle einen Branch (Nummer): " choice + if [[ -z "${branch_map[$choice]}" ]]; then + echo "Ungültige Auswahl!" + return 1 + fi + + selected_branch=${branch_map[$choice]} + echo "Wechsle zu Branch: $selected_branch" + + git fetch origin + + if git show-ref --verify --quiet "refs/heads/$selected_branch"; then + git checkout "$selected_branch" + else + git checkout -b "$selected_branch" "origin/$selected_branch" + fi + + git reset --hard "origin/$selected_branch" + git clean -fd + + for file in "${unversioned_files[@]}"; do + if [[ -f "/tmp/git_safe_backup/$(basename "$file")" ]]; then + mkdir -p "$(dirname "$file")" + mv "/tmp/git_safe_backup/$(basename "$file")" "$file" + fi + done + rm -rf /tmp/git_safe_backup + + echo "Branch '$selected_branch' ist nun aktiv. Arbeitsverzeichnis entspricht exakt dem Remote-Stand." + echo "Gesicherte Dateien wurden wiederhergestellt." +} + +main() { + local selection + while true; do + echo "" + show_menu + read -rp "Auswahl: " selection + echo "" + case $selection in + 1) + create_new_feature + pause_for_menu + ;; + 2) + merge_feature_into_dev + pause_for_menu + ;; + 3) + merge_dev_into_master + pause_for_menu + ;; + 4) + push_changes + pause_for_menu + ;; + 5) + docker_release + pause_for_menu + ;; + 6) + start_dev_environment + pause_for_menu + ;; + 7) + manage_stash + pause_for_menu + ;; + 8) + switch_branch + pause_for_menu + ;; + 0) + echo "Auf Wiedersehen!" + exit 0 + ;; + *) + echo "❌ Ungültige Auswahl." + ;; + esac + done +} + +main "$@" \ No newline at end of file diff --git a/scripts/git-push.sh b/scripts/git-push.sh new file mode 100755 index 0000000..73caf1d --- /dev/null +++ b/scripts/git-push.sh @@ -0,0 +1,48 @@ +#!/bin/bash +set -e + +# Aktuellen Branch herausfinden +BRANCH=$(git rev-parse --abbrev-ref HEAD) + +# Branch bestätigen +read -p "Aktueller Branch: $BRANCH. Ist das korrekt? (y/n): " CONFIRM +if [[ "$CONFIRM" != "y" && "$CONFIRM" != "Y" ]]; then + echo "Abgebrochen." + exit 1 +fi + +# Commit-Nachricht +read -p "Bitte Commit-Nachricht eingeben (default: 'Update'): " COMMIT_MSG +COMMIT_MSG=${COMMIT_MSG:-Update} + +# Änderungen stagen und committen +echo "Änderungen werden gestaged..." +git add . +echo "Commit wird erstellt..." +git commit -m "$COMMIT_MSG" || echo "Nichts zu committen" + +# Prüfen, ob Branch master ist +if [[ "$BRANCH" == "master" ]]; then + # Versionsnummer verpflichtend abfragen + while true; do + read -p "Bitte Versionsnummer für Master-Release Tag eingeben (z.B. v0.2.0): " VERSION_TAG + if [[ -n "$VERSION_TAG" ]]; then + break + else + echo "Versionsnummer darf nicht leer sein. Bitte eingeben." + fi + done +fi + +# Push Branch +echo "Push nach origin/$BRANCH..." +git push origin "$BRANCH" + +# Tag setzen und pushen, nur bei master +if [[ "$BRANCH" == "master" ]]; then + git tag -a "$VERSION_TAG" -m "Release $VERSION_TAG" + git push origin "$VERSION_TAG" + echo "Tag $VERSION_TAG gesetzt und gepusht." +fi + +echo "Push abgeschlossen." \ No newline at end of file diff --git a/scripts/merge-dev-to-master.sh b/scripts/merge-dev-to-master.sh new file mode 100755 index 0000000..1fcace4 --- /dev/null +++ b/scripts/merge-dev-to-master.sh @@ -0,0 +1,22 @@ +#!/bin/bash +# Skript: Dev in Master mergen + +DEV_BRANCH="dev" +MASTER_BRANCH="master" + +# Auf master wechseln und aktuell holen +git checkout $MASTER_BRANCH +git pull origin $MASTER_BRANCH + +# Dev aktuell holen +git checkout $DEV_BRANCH +git pull origin $DEV_BRANCH + +# Merge Dev in Master +git checkout $MASTER_BRANCH +git merge --no-ff $DEV_BRANCH -m "Merge $DEV_BRANCH into $MASTER_BRANCH" + +# Push Master auf Remote +git push origin $MASTER_BRANCH + +echo "Branch $DEV_BRANCH wurde in $MASTER_BRANCH gemerged." \ No newline at end of file diff --git a/scripts/merge-feature-to-dev.sh b/scripts/merge-feature-to-dev.sh new file mode 100755 index 0000000..2241490 --- /dev/null +++ b/scripts/merge-feature-to-dev.sh @@ -0,0 +1,41 @@ +#!/bin/bash +# Skript: Feature in Dev mergen mit Auswahl der Feature-Branches + +DEV_BRANCH="dev" + +# Auflisten aller Feature-Branches (lokal und remote) +echo "Verfügbare Feature-Branches:" +FEATURE_BRANCHES=$(git branch -r | grep 'origin/feature/' | sed 's|origin/||') +PS3="Bitte wähle einen Feature-Branch zum Mergen: " + +# in ein Array konvertieren +BRANCH_ARRAY=($FEATURE_BRANCHES) + +# Auswahlmenü anzeigen +select CHOSEN_BRANCH in "${BRANCH_ARRAY[@]}"; do + if [[ -n "$CHOSEN_BRANCH" ]]; then + FEATURE_BRANCH=$CHOSEN_BRANCH + break + else + echo "Ungültige Auswahl. Bitte erneut versuchen." + fi +done + +echo "Ausgewählter Feature-Branch: $FEATURE_BRANCH" + +# Dev aktuell holen +git checkout $DEV_BRANCH +git pull origin $DEV_BRANCH + +# Feature-Branch aktuell holen +git checkout $FEATURE_BRANCH +git pull origin $FEATURE_BRANCH + +# Merge Feature in Dev +git checkout $DEV_BRANCH +git merge --no-ff $FEATURE_BRANCH -m "Merge $FEATURE_BRANCH into $DEV_BRANCH" + +# Push Dev auf Remote +git push origin $DEV_BRANCH + +echo "Feature $FEATURE_BRANCH wurde erfolgreich in $DEV_BRANCH gemerged." \ No newline at end of file diff --git a/scripts/new-feature.sh b/scripts/new-feature.sh new file mode 100755 index 0000000..85f3171 --- /dev/null +++ b/scripts/new-feature.sh @@ -0,0 +1,55 @@ +#!/bin/bash +# Skript: Neues Feature erstellen + +MASTER_BRANCH="master" + +# Abfrage Feature-Name +read -p "Bitte den Namen des neuen Features eingeben: " FEATURE_NAME + +# Falls nichts eingegeben wurde, Skript abbrechen +if [ -z "$FEATURE_NAME" ]; then + echo "❌ Fehler: Kein Feature-Name angegeben." + exit 1 +fi + +# Validierung: nur erlaubte Zeichen +if [[ "$FEATURE_NAME" =~ [^a-zA-Z0-9._-] ]]; then + echo "❌ Fehler: Ungültiger Branch-Name. Bitte nur Buchstaben, Zahlen, Punkt, Unterstrich oder Bindestrich verwenden." + exit 1 +fi + +FEATURE_BRANCH="feature/$FEATURE_NAME" + +# Check auf uncommittete Änderungen +if ! git diff-index --quiet HEAD --; then + echo "⚠️ Es gibt noch uncommittete Änderungen. Bitte committen oder stashen, bevor ein neuer Branch erstellt wird." + exit 1 +fi + +# Prüfen, ob Branch lokal schon existiert +if git show-ref --verify --quiet refs/heads/$FEATURE_BRANCH; then + echo "❌ Fehler: Der Branch '$FEATURE_BRANCH' existiert lokal bereits." + exit 1 +fi + +# Prüfen, ob Branch remote schon existiert +if git ls-remote --heads origin $FEATURE_BRANCH | grep -q $FEATURE_BRANCH; then + echo "❌ Fehler: Der Branch '$FEATURE_BRANCH' existiert bereits auf Remote." + exit 1 +fi + +# Auf master wechseln und aktualisieren +git checkout $MASTER_BRANCH +git pull origin $MASTER_BRANCH + +# Neuen Feature-Branch erstellen und auschecken +git checkout -b $FEATURE_BRANCH $MASTER_BRANCH + +# Branch auf Remote pushen +git push -u origin $FEATURE_BRANCH + +# Commit-Hash der Basis holen +BASE_COMMIT=$(git rev-parse --short HEAD) + +echo "✅ Neuer Feature-Branch '$FEATURE_BRANCH' wurde erstellt und auf Remote gepusht." +echo " Basis: $MASTER_BRANCH@$BASE_COMMIT" \ No newline at end of file diff --git a/scripts/stash.sh b/scripts/stash.sh new file mode 100755 index 0000000..7b54f14 --- /dev/null +++ b/scripts/stash.sh @@ -0,0 +1,138 @@ +#!/bin/bash + +# =============================== +# Git Stash Manager mit Branch-Filter und Überschreiben +# =============================== + +# Aktuellen Branch ermitteln +CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD) + +echo "Aktueller Branch: $CURRENT_BRANCH" +echo "Was möchtest du tun?" +echo "1) Neuen Stash anlegen" +echo "2) Vorhandenen Stash laden (apply)" +echo "3) Vorhandenen Stash löschen" +echo "4) Stash anwenden und löschen (pop)" +read -p "Auswahl: " action + +case $action in + 1) + # ========== Neuen Stash anlegen ========== + read -p "Gib einen Namen für den Stash ein: " USER_INPUT + STASH_NAME="$CURRENT_BRANCH - $USER_INPUT" + + # Prüfen, ob Stash-Name schon existiert + EXISTING=$(git stash list | grep "$STASH_NAME") + if [[ -n "$EXISTING" ]]; then + echo "Ein Stash mit dem Namen '$STASH_NAME' existiert bereits." + # Alle passenden Stashes löschen + while IFS= read -r line; do + STASH_REF=$(echo "$line" | awk -F: '{print $1}') + echo "Lösche vorhandenen Stash: $STASH_REF" + git stash drop "$STASH_REF" + done <<< "$EXISTING" + fi + + # Neuen Stash anlegen (inkl. untracked Dateien) + git stash push -u -m "$STASH_NAME" + echo "Stash '$STASH_NAME' wurde angelegt." + ;; + + 2) + # ========== Stash anwenden ========== + echo "Liste aller Stashes für Branch '$CURRENT_BRANCH':" + STASHES=$(git stash list | grep "$CURRENT_BRANCH") + + if [[ -z "$STASHES" ]]; then + echo "Keine Stashes für diesen Branch vorhanden." + exit 0 + fi + + i=1 + declare -A STASH_MAP + while IFS= read -r line; do + STASH_REF=$(echo "$line" | awk -F: '{print $1}') + STASH_MSG=$(echo "$line" | cut -d':' -f3- | sed 's/^ //') + echo "$i) $STASH_REF -> $STASH_MSG" + STASH_MAP[$i]=$STASH_REF + ((i++)) + done <<< "$STASHES" + + read -p "Wähle einen Stash (Nummer): " choice + if [[ -z "${STASH_MAP[$choice]}" ]]; then + echo "Ungültige Auswahl!" + exit 1 + fi + + SELECTED_STASH=${STASH_MAP[$choice]} + echo "Wende Stash an: $SELECTED_STASH" + git stash apply "$SELECTED_STASH" + ;; + + 3) + # ========== Stash löschen ========== + echo "Liste aller Stashes für Branch '$CURRENT_BRANCH':" + STASHES=$(git stash list | grep "$CURRENT_BRANCH") + + if [[ -z "$STASHES" ]]; then + echo "Keine Stashes für diesen Branch vorhanden." + exit 0 + fi + + i=1 + declare -A STASH_MAP + while IFS= read -r line; do + STASH_REF=$(echo "$line" | awk -F: '{print $1}') + STASH_MSG=$(echo "$line" | cut -d':' -f3- | sed 's/^ //') + echo "$i) $STASH_REF -> $STASH_MSG" + STASH_MAP[$i]=$STASH_REF + ((i++)) + done <<< "$STASHES" + + read -p "Wähle einen Stash zum Löschen (Nummer): " choice + if [[ -z "${STASH_MAP[$choice]}" ]]; then + echo "Ungültige Auswahl!" + exit 1 + fi + + SELECTED_STASH=${STASH_MAP[$choice]} + echo "Lösche Stash: $SELECTED_STASH" + git stash drop "$SELECTED_STASH" + ;; + + 4) + # ========== Stash anwenden und löschen (pop) ========== + echo "Liste aller Stashes für Branch '$CURRENT_BRANCH':" + STASHES=$(git stash list | grep "$CURRENT_BRANCH") + + if [[ -z "$STASHES" ]]; then + echo "Keine Stashes für diesen Branch vorhanden." + exit 0 + fi + + i=1 + declare -A STASH_MAP + while IFS= read -r line; do + STASH_REF=$(echo "$line" | awk -F: '{print $1}') + STASH_MSG=$(echo "$line" | cut -d':' -f3- | sed 's/^ //') + echo "$i) $STASH_REF -> $STASH_MSG" + STASH_MAP[$i]=$STASH_REF + ((i++)) + done <<< "$STASHES" + + read -p "Wähle einen Stash zum Anwenden & Löschen (Nummer): " choice + if [[ -z "${STASH_MAP[$choice]}" ]]; then + echo "Ungültige Auswahl!" + exit 1 + fi + + SELECTED_STASH=${STASH_MAP[$choice]} + echo "Wende Stash an und lösche ihn: $SELECTED_STASH" + git stash pop "$SELECTED_STASH" + ;; + + *) + echo "Ungültige Auswahl!" + exit 1 + ;; +esac \ No newline at end of file diff --git a/scripts/switch-branch.sh b/scripts/switch-branch.sh new file mode 100755 index 0000000..8d6cfff --- /dev/null +++ b/scripts/switch-branch.sh @@ -0,0 +1,87 @@ +#!/bin/bash + +# =============================== +# Dateien sichern, die nicht gepusht werden +# =============================== +UNVERSIONED_FILES=("scripts/docker-release.sh") +for f in "${UNVERSIONED_FILES[@]}"; do + if [[ -f $f ]]; then + mkdir -p /tmp/git_safe_backup + cp "$f" "/tmp/git_safe_backup/$(basename "$f")" + fi +done + +# =============================== +# Alle Branches sammeln +# =============================== +# Alle lokalen Branches holen, führende Sternchen und Leerzeichen entfernen +LOCAL_BRANCHES=$(git branch | sed 's/* //' | sed 's/^[[:space:]]*//') + +# Alle Remote-Branches holen, 'origin/' entfernen, HEAD ignorieren, führende Leerzeichen entfernen +REMOTE_BRANCHES=$(git branch -r | grep -v 'HEAD' | sed 's|origin/||' | sed 's/^[[:space:]]*//') + +# Beide Listen zusammenführen und Duplikate entfernen +ALL_BRANCHES=$(echo -e "$LOCAL_BRANCHES\n$REMOTE_BRANCHES" | sort -u) + +# Master und dev extrahieren, restliche feature-Branches alphabetisch +MASTER_BRANCH=$(echo "$ALL_BRANCHES" | grep -x 'master') +DEV_BRANCH=$(echo "$ALL_BRANCHES" | grep -x 'dev') +FEATURE_BRANCHES=$(echo "$ALL_BRANCHES" | grep '^feature/' | sort) + +# Zusammenführen +SORTED_BRANCHES=() +[[ -n "$MASTER_BRANCH" ]] && SORTED_BRANCHES+=("$MASTER_BRANCH") +[[ -n "$DEV_BRANCH" ]] && SORTED_BRANCHES+=("$DEV_BRANCH") +for branch in $FEATURE_BRANCHES; do + SORTED_BRANCHES+=("$branch") +done + +# Branches nummerieren +echo "Verfügbare Branches:" +i=1 +declare -A BRANCH_MAP +for branch in "${SORTED_BRANCHES[@]}"; do + echo "$i) $branch" + BRANCH_MAP[$i]=$branch + ((i++)) +done + +# Auswahl abfragen +read -p "Wähle einen Branch (Nummer): " choice + +# Validierung +if [[ -z "${BRANCH_MAP[$choice]}" ]]; then + echo "Ungültige Auswahl!" + exit 1 +fi + +SELECTED_BRANCH=${BRANCH_MAP[$choice]} +echo "Wechsle zu Branch: $SELECTED_BRANCH" + +# Remote-Stand holen +git fetch origin + +# Branch wechseln (lokal erstellen, falls nur remote vorhanden) +if git show-ref --verify --quiet refs/heads/$SELECTED_BRANCH; then + git checkout $SELECTED_BRANCH +else + git checkout -b $SELECTED_BRANCH origin/$SELECTED_BRANCH +fi + +# Arbeitsverzeichnis exakt auf Remote-Branch zurücksetzen +git reset --hard origin/$SELECTED_BRANCH +git clean -fd + +# =============================== +# Gesicherte unversionierte Dateien zurückkopieren +# =============================== +for f in "${UNVERSIONED_FILES[@]}"; do + if [[ -f "/tmp/git_safe_backup/$(basename "$f")" ]]; then + mkdir -p "$(dirname "$f")" + mv "/tmp/git_safe_backup/$(basename "$f")" "$f" + fi +done +rm -rf /tmp/git_safe_backup + +echo "Branch '$SELECTED_BRANCH' ist nun aktiv. Arbeitsverzeichnis entspricht exakt dem Remote-Stand." +echo "Unversionierte Dateien wurden wiederhergestellt." \ No newline at end of file