diff --git a/README.md b/README.md index 21c9649..927df5e 100644 --- a/README.md +++ b/README.md @@ -98,10 +98,10 @@ PostgreSQL: хост, порт, база, пользователь, пароль ## Установка сервера одной командой На Linux-сервере (amd64 или arm64, systemd): ```sh -wget -qO- https://raw.githubusercontent.com/iRedTea/lpra/main/server-install.sh | sudo sh +wget -qO- https://gitlab.com/itzRedTea/lpra/-/raw/main/server-install.sh | sudo sh ``` Скрипт `server-install.sh`: -- качает бинарник сервера под архитектуру машины из [последнего релиза](https://github.com/iRedTea/lpra/releases/latest) +- качает бинарник сервера под архитектуру машины из [последнего релиза](https://gitlab.com/itzRedTea/lpra/-/releases/permalink/latest) и папку `dist/` (бинарники агентов) из ветки `main`, кладёт всё в `/opt/lpra`; - ставит службу systemd `lpra-server` (порт спросит, по умолчанию `8091`); - по желанию настраивает nginx: спросит домен, создаст сайт на порт 80 (при необходимости поставит nginx), @@ -112,7 +112,7 @@ wget -qO- https://raw.githubusercontent.com/iRedTea/lpra/main/server-install.sh Вопросы задаются в терминале, даже когда скрипт идёт через `| sudo sh`. Без терминала ответы берутся из переменных: `LPRA_PORT`, `LPRA_NGINX` (y/n), `LPRA_DOMAIN`, `LPRA_EMAIL`, `LPRA_CERTBOT` (y/n), `LPRA_UFW` (y/n): ```sh -wget -qO- https://raw.githubusercontent.com/iRedTea/lpra/main/server-install.sh | sudo LPRA_NGINX=y LPRA_DOMAIN=lpra.example.com sh +wget -qO- https://gitlab.com/itzRedTea/lpra/-/raw/main/server-install.sh | sudo LPRA_NGINX=y LPRA_DOMAIN=lpra.example.com sh ``` Повторный запуск той же командой - **обновление**: бинарник и `dist/` заменяются, база (`/opt/lpra/lpra.db` и её ключ `lpra.db.key`), настройки службы и nginx остаются. После установки откройте `/setup` - мастер @@ -213,10 +213,10 @@ curl -fsSL https://panel.example/install.sh | sudo HOST=https://panel.example EN - Открытие терминала и SSH, перенос файлов на другие машины, смена пользователя пишутся в `audit`. ## Скриншоты -image +image -image +image -image +image -image +image diff --git a/docs/gitlab-migration.md b/docs/gitlab-migration.md new file mode 100644 index 0000000..ff157c7 --- /dev/null +++ b/docs/gitlab-migration.md @@ -0,0 +1,144 @@ +# Перенос проекта с GitHub на GitLab с сохранением истории и дат + +Инструкция для локального репозитория, когда GitHub недоступен (аккаунт заблокирован) и +переносить приходится из своей копии. Так был перенесён `lpra`: 195 коммитов, 8 тегов, +3 релиза - хэши и даты совпали. + +## Что сохраняется, а что нет + +| Что | Сохраняется? | +|---|---| +| Даты коммитов (автора и коммита) | **Да, точно.** Они хранятся внутри коммита; push той же истории не меняет ни одного хэша | +| Ветки и теги | Да, если они есть локально (см. шаг 2) | +| Дата создания проекта | **Нет.** На gitlab.com она всегда - день создания проекта, задним числом не ставится. Начало проекта видно по первому коммиту | +| Релизы | Создаются заново, **с исходной датой** (`--released-at`); файлы релизов - заново собрать или взять свои копии | +| Issues, PR, звёзды, Actions | Нет: при заблокированном GitHub их не выгрузить | + +**Нельзя:** `rebase`, `squash`, `filter-branch`, `filter-repo`, `commit --amend` по старым +коммитам, «Import from GitHub» с чужой копии - всё это переписывает коммиты и их даты. + +## 0. Один раз: вход в GitLab + +```sh +brew install glab +glab auth login --hostname gitlab.com --web --git-protocol https +``` + +Вход через браузер даёт права и на push, и на релизы. Git берёт пароль у glab - для каждого +репозитория это настраивается в шаге 4 (или один раз для всех: +`git config --global credential.https://gitlab.com.helper '!glab auth git-credential'`). + +SSH-ключ тоже подойдёт, но в GitLab у ключа должен быть **Usage type: Authentication & Signing** +(с типом «Signing» по SSH не пускает). + +## 1. Пустой проект в GitLab + +https://gitlab.com/projects/new → **Create blank project** → имя, владелец `itzRedTea`. +**Снять галочку «Initialize repository with a README»** - иначе в проекте появится свой первый +коммит, и историю придётся склеивать. + +Или из терминала: + +```sh +glab repo create itzRedTea/ИМЯ --public # или --private; README не создаётся +``` + +## 2. Проверить, что всё есть локально + +```sh +cd ~/CodeRepos/ИМЯ +git status # незакоммиченное закоммитить или убрать +git branch -a # ветки: свои и remotes/origin/* +git tag -l # теги +``` + +- Ветки, которых нет локально, но есть `remotes/origin/X`, тоже переносятся (шаг 3). +- **Теги, созданные на GitHub при публикации релиза, могут не быть локально** - если их не + делали `git fetch --tags`. Такой тег создаётся заново на нужном коммите (шаг 5). Коммит + ищется по дате публикации релиза: последний коммит перед ней + (`git log --format='%h %cd %s' --date=iso --until='ДАТА'`). + +Снимок до переноса - для сверки: + +```sh +git log --branches --remotes=origin --tags --format='%H %aI %cI' | sort > /tmp/before.txt +git show-ref --tags | sort > /tmp/tags-before.txt +``` + +## 3. Отправить историю + +```sh +git remote rename origin github # GitHub остаётся под своим именем +git remote add origin https://gitlab.com/itzRedTea/ИМЯ.git +H='!glab auth git-credential' +git -c credential.helper= -c "credential.helper=$H" push origin --all # все локальные ветки +git -c credential.helper= -c "credential.helper=$H" push origin 'refs/remotes/github/*:refs/heads/*' # ветки, что были только на GitHub +git -c credential.helper= -c "credential.helper=$H" push origin --tags +``` + +Вторая команда push может сказать про `HEAD` - это не ветка, сообщение можно не смотреть. + +## 4. Сверить и переключиться + +Сверка - по свежей копии из GitLab: + +```sh +rm -rf /tmp/check && git clone -q https://gitlab.com/itzRedTea/ИМЯ.git /tmp/check +cd /tmp/check && git log --remotes=origin --tags --format='%H %aI %cI' | sort > /tmp/after.txt +git show-ref --tags | sort > /tmp/tags-after.txt +diff /tmp/before.txt /tmp/after.txt && echo "коммиты и даты совпали" +diff /tmp/tags-before.txt /tmp/tags-after.txt && echo "теги совпали" +``` + +Пустой `diff` - история перенесена один в один. Дальше работать с GitLab: + +```sh +cd ~/CodeRepos/ИМЯ +git config --local credential.https://gitlab.com.helper '!glab auth git-credential' +git fetch origin && git branch -u origin/main main +``` + +## 5. Релизы с исходными датами + +Дата - время публикации релиза на GitHub (UTC). Файлы - свои копии или сборка из коммита +релиза во временной папке: + +```sh +git worktree add --detach /tmp/rel-1.2.0 1.2.0 # тег или хэш коммита релиза +cd /tmp/rel-1.2.0 && ./build.sh # как проект собирается +glab release create 1.2.0 bin/файл1 bin/файл2 \ + -R itzRedTea/ИМЯ --name "Release 1.2.0" \ + --released-at "2026-10-15T16:34:53Z" \ + --notes "Перенесено с GitHub, дата публикации исходная." +# тега нет (его делал GitHub) - добавить: --ref <полный хэш коммита> +git worktree remove /tmp/rel-1.2.0 +``` + +Создавать по порядку, от старых к новым. Последним GitLab считает релиз с самой поздней +датой. Ссылки на файлы: + +- конкретный релиз: `https://gitlab.com/itzRedTea/ИМЯ/-/releases/ТЕГ/downloads/ФАЙЛ` +- последний: `https://gitlab.com/itzRedTea/ИМЯ/-/releases/permalink/latest/downloads/ФАЙЛ` + +## 6. Ссылки в самом проекте + +Найти и заменить всё, что смотрит на GitHub: + +```sh +grep -rn "github.com\|githubusercontent" --exclude-dir=.git . +``` + +| GitHub | GitLab | +|---|---| +| `https://raw.githubusercontent.com/USER/ИМЯ/main/ПУТЬ` | `https://gitlab.com/itzRedTea/ИМЯ/-/raw/main/ПУТЬ` | +| `https://github.com/USER/ИМЯ/releases/latest/download/ФАЙЛ` | `https://gitlab.com/itzRedTea/ИМЯ/-/releases/permalink/latest/downloads/ФАЙЛ` | +| `https://api.github.com/repos/USER/ИМЯ/releases/latest` (`tag_name`) | `https://gitlab.com/api/v4/projects/itzRedTea%2FИМЯ/releases/permalink/latest` (`tag_name`) | +| `https://api.github.com/repos/USER/ИМЯ/contents/ПАПКА?ref=main` | `https://gitlab.com/api/v4/projects/itzRedTea%2FИМЯ/repository/tree?path=ПАПКА&ref=main` (поле `path`) | +| картинки `github.com/user-attachments/...` | скачать, пока открываются, в `docs/` и ссылаться на файлы | + +Путь Go-модуля (`module github.com/...` в `go.mod`) можно не трогать: это только имя. + +## 7. После переноса + +- Описание проекта в GitLab: «Перенесён с GitHub, начат ДД.ММ.ГГГГ» - раз дата создания новая. +- Токены, которые светились в чатах и логах, - отозвать и выпустить новые. diff --git a/docs/screenshots/1.png b/docs/screenshots/1.png new file mode 100644 index 0000000..1e58fa7 Binary files /dev/null and b/docs/screenshots/1.png differ diff --git a/docs/screenshots/2.png b/docs/screenshots/2.png new file mode 100644 index 0000000..6d9cd03 Binary files /dev/null and b/docs/screenshots/2.png differ diff --git a/docs/screenshots/3.png b/docs/screenshots/3.png new file mode 100644 index 0000000..e3537eb Binary files /dev/null and b/docs/screenshots/3.png differ diff --git a/docs/screenshots/4.png b/docs/screenshots/4.png new file mode 100644 index 0000000..7bc9958 Binary files /dev/null and b/docs/screenshots/4.png differ diff --git a/server-install.sh b/server-install.sh index 4b4d728..b35f141 100755 --- a/server-install.sh +++ b/server-install.sh @@ -1,9 +1,9 @@ #!/bin/sh # LPRA server: install or update in one command. # -# wget -qO- https://raw.githubusercontent.com/iRedTea/lpra/main/server-install.sh | sudo sh +# wget -qO- https://gitlab.com/itzRedTea/lpra/-/raw/main/server-install.sh | sudo sh # -# Takes the server binary for this machine from the latest GitHub release and +# Takes the server binary for this machine from the latest GitLab release and # the agent binaries (dist/) from the main branch, puts them in /opt/lpra, # sets up the systemd service and, if asked, nginx with a domain and a # certificate from certbot. Run again to update: the binary and dist/ are @@ -16,7 +16,10 @@ # and where to. set -eu -REPO=${LPRA_REPO:-iRedTea/lpra} +REPO=${LPRA_REPO:-itzRedTea/lpra} +GL=https://gitlab.com +# The project in the API's paths: its path with "/" as %2F. +API="$GL/api/v4/projects/$(printf '%s' "$REPO" | sed 's|/|%2F|g')" DIR=${LPRA_DIR:-/opt/lpra} SERVICE=lpra-server UNIT=/etc/systemd/system/$SERVICE.service @@ -75,14 +78,14 @@ confirm() { TMP=$(mktemp -d) trap 'rm -rf "$TMP"' EXIT INT TERM -TAG=$(fetch "https://api.github.com/repos/$REPO/releases/latest" 2>/dev/null | +TAG=$(fetch "$API/releases/permalink/latest" 2>/dev/null | tr ',' '\n' | sed -n 's/.*"tag_name": *"\([^"]*\)".*/\1/p' | head -n 1) || TAG= if [ -n "$TAG" ]; then say "последний релиз: $TAG" - BIN_URL="https://github.com/$REPO/releases/download/$TAG/lpra-server-linux-$ARCH" + BIN_URL="$GL/$REPO/-/releases/$TAG/downloads/lpra-server-linux-$ARCH" else - warn "не узнать номер релиза у GitHub API - беру latest" - BIN_URL="https://github.com/$REPO/releases/latest/download/lpra-server-linux-$ARCH" + warn "не узнать номер релиза у GitLab API - беру latest" + BIN_URL="$GL/$REPO/-/releases/permalink/latest/downloads/lpra-server-linux-$ARCH" fi say "скачиваю сервер (linux/$ARCH)" dl "$BIN_URL" "$TMP/lpra-server" || die "не скачался $BIN_URL" @@ -90,12 +93,13 @@ chmod +x "$TMP/lpra-server" say "скачиваю dist/ из ветки main" mkdir -p "$TMP/dist" -URLS=$(fetch "https://api.github.com/repos/$REPO/contents/dist?ref=main" 2>/dev/null | - sed -n 's/.*"download_url": *"\([^"]*\)".*/\1/p') || URLS= +# The files of dist/ on main, by the API's list of the folder. +URLS=$(fetch "$API/repository/tree?path=dist&ref=main&per_page=100" 2>/dev/null | tr '{},' '\n\n\n' | + sed -n 's|^"path": *"\(dist/[^"]*\)"$|'"$GL/$REPO"'/-/raw/main/\1|p') || URLS= if [ -z "$URLS" ]; then - warn "не получить список dist/ у GitHub API - беру агентов linux amd64 и arm64" - URLS="https://raw.githubusercontent.com/$REPO/main/dist/agent-linux-amd64 -https://raw.githubusercontent.com/$REPO/main/dist/agent-linux-arm64" + warn "не получить список dist/ у GitLab API - беру агентов linux amd64 и arm64" + URLS="$GL/$REPO/-/raw/main/dist/agent-linux-amd64 +$GL/$REPO/-/raw/main/dist/agent-linux-arm64" fi for u in $URLS; do f=${u##*/}