diff --git a/%EB%B9%8C%EB%93%9C%EC%99%80-%EB%B0%B0%ED%8F%AC.md b/%EB%B9%8C%EB%93%9C%EC%99%80-%EB%B0%B0%ED%8F%AC.md new file mode 100644 index 0000000..76af6fd --- /dev/null +++ b/%EB%B9%8C%EB%93%9C%EC%99%80-%EB%B0%B0%ED%8F%AC.md @@ -0,0 +1,105 @@ +# 빌드와 배포 + +## 1. 프로젝트 구성 + +| 파일 | 내용 | +|---|---| +| `Program.cs` | 전체 소스 (잠금 화면, 암호 관리, 키 읽기, 메인 창, 대화 상자) | +| `AssemblyInfo.cs` | 어셈블리 제목·버전 특성 | +| `WindowsKeyInfo.csproj` | SDK 형식 프로젝트, `net48`, C# 7.3, WinExe, AnyCPU(32비트 우선 안 함) | +| `.gitignore` | `bin/`, `obj/`, `.vs/`, `*.user`, `*.suo`, `WindowsKeyInfo_*.txt` 제외 | +| `README.md` | 기능·빌드 방법 요약 | + +## 2. 빌드 방법 + +### Visual Studio / dotnet + +``` +dotnet build -c Release +``` + +**알려진 문제 — 어셈블리 특성 중복:** `.csproj`에 `GenerateAssemblyInfo=true`가 켜져 있어 빌드할 때 제목·버전 특성이 자동으로 만들어지는데, `AssemblyInfo.cs`에도 같은 특성이 있습니다. 그래서 `dotnet build`에서 **CS0579(중복 특성) 오류**가 날 수 있습니다. 원본을 그대로 두기로 해서 아직 고치지 않았습니다. 오류가 나면 둘 중 하나로 해결합니다. + +- `AssemblyInfo.cs`를 프로젝트에서 빼기 (버전·제목은 `.csproj` 값 사용) +- `.csproj`에서 `false`로 바꾸기 + +### 릴리스 exe를 만든 방법 (Mono 컴파일러) + +v1.0.0 릴리스 exe는 Linux 환경에서 Mono 컴파일러(`mcs`)로 .NET Framework 4.8 참조 어셈블리를 대상으로 빌드했습니다. 이 방식은 `.csproj`를 쓰지 않아서 위 중복 문제가 생기지 않습니다. + +``` +mcs -nostdlib -lib:/usr/lib/mono/4.8-api \ + -r:mscorlib.dll -r:System.dll -r:System.Core.dll \ + -r:System.Windows.Forms.dll -r:System.Drawing.dll \ + -langversion:7 -optimize+ -platform:anycpu -target:winexe \ + -out:WindowsKeyInfo.exe AssemblyInfo.cs Program.cs +``` + +결과물은 일반 .NET Framework exe라 Windows에서 그대로 실행됩니다. 다만 Visual Studio로 만든 파일과 바이트 단위로 같지는 않습니다. + +## 3. 저장소 + +| 저장소 | 주소 | 용도 | +|---|---|---| +| Gitea | `https://gitea.joynala.com/diadmin/WindowsKey` | 주 저장소, 릴리스, 위키 | +| GitHub | `https://github.com/RyuJongJin/WindowsKey` | 사본 | + +두 저장소의 main 브랜치는 같은 커밋 `46f4021`을 가리킵니다. + +PC의 로컬 저장소는 `M:\WindowsKey\src`이고, 원격 이름 `gitea`로 Gitea와 연결돼 있습니다. + +## 4. GitHub에 올린 과정 + +1. 처음에는 Claude GitHub 앱이 이 저장소에 접근할 수 없었습니다. GitHub 설정에서 앱의 저장소 접근에 WindowsKey를 추가해 해결했습니다. +2. 최초 커밋과 이후 커밋은 정상으로 푸시됐습니다. +3. **릴리스와 태그는 작업 환경에서 생성이 막혀 있었습니다(HTTP 403).** 그래서 GitHub 릴리스는 웹 화면에서 직접 만드는 방식으로 진행했습니다. + - 웹에서 태그를 고르지 않고 Publish를 누르면 "tag name can't be blank" 오류가 납니다. **Tag: Select tag → `v1.0.0` 입력 → Create new tag** 를 먼저 해야 합니다. +4. 커밋 메시지 오타(`Shif`)를 고치려고 마지막 커밋을 수정해 **강제 푸시**했습니다 (`483a3cb` → `46f4021`). 다른 PC에 예전 기록이 있으면 `git fetch` 후 `git reset --hard origin/main`으로 맞춥니다. + +## 5. Gitea에 올린 과정 + +작업 환경에서는 `gitea.joynala.com`에 직접 접속할 수 없었습니다. 그래서 `M:\WindowsKey`에 아래 파일을 준비하고 PC에서 스크립트를 실행했습니다. + +| 파일 | 내용 | +|---|---| +| `WindowsKey.bundle` | 저장소 전체(커밋 기록 포함)를 묶은 git bundle | +| `WindowsKeyInfo.exe` | 릴리스에 붙일 실행파일 | +| `gitea_push_release.ps1` | 푸시·태그·릴리스·첨부를 처리하는 PowerShell 스크립트 | +| `gitea_push_release.cmd` | 위 스크립트 실행용 (더블클릭) | + +스크립트 순서: + +1. Gitea 액세스 토큰 입력 (화면에 안 보임, 파일에 저장 안 함, 공백·제어 문자 자동 제거) +2. 저장소 존재 확인 +3. bundle에서 `M:\WindowsKey\src`로 클론, 원격 `gitea` 설정 +4. main 브랜치 푸시 (토큰은 그 명령에서만 HTTP 헤더로 사용) +5. `v1.0.0` 태그를 PC에서 만들어 푸시 +6. 그 태그로 릴리스 생성 +7. 릴리스에 `WindowsKeyInfo.exe` 첨부 + +여러 번 실행해도 되도록, 이미 끝난 단계는 건너뜁니다. 다음 버전을 올릴 때는 스크립트 맨 위 `$Tag`, `$Title`, `$Notes`만 바꿔서 다시 쓰면 됩니다. + +### Gitea 토큰 만들기 + +Gitea 로그인 → 우측 상단 프로필 → **설정** → **애플리케이션** → **새 토큰 생성**, 권한은 **repository 읽기 및 쓰기**. 작업이 끝나면 토큰을 삭제하는 것을 권장합니다. + +### 위키 + +위키 페이지는 Claude 앱의 브라우저 창에서 `diadmin` 계정으로 로그인한 상태로 직접 만들었습니다. 같은 내용의 원본 Markdown 파일이 `M:\WindowsKey\wiki`에 있고, `gitea_wiki.cmd`를 실행하면 토큰으로 다시 올릴 수도 있습니다 (있는 페이지는 내용을 갱신). + +## 6. 겪은 오류와 해결 + +| 오류 | 원인 | 해결 | +|---|---|---| +| GitHub `add_repo`: 저장소에 접근 권한 없음 | Claude GitHub 앱에 저장소가 연결 안 됨 | GitHub 설정에서 앱 저장소 접근에 WindowsKey 추가 | +| GitHub 릴리스 생성 HTTP 403 | 작업 환경에서 릴리스 API 차단 | 웹 화면에서 직접 생성 | +| GitHub 태그 푸시 HTTP 403 | 작업 환경에서 태그 푸시 차단 | 웹 릴리스 화면에서 태그 생성 | +| GitHub 웹: "tag name can't be blank" | 태그를 고르지 않고 Publish | Tag 선택 → Create new tag 후 Publish | +| Gitea 접속 403 (프록시) | 작업 환경 네트워크 허용 목록 밖 | PC에서 스크립트 실행 | +| Gitea: "Specified value has invalid Control characters" | 토큰 붙여넣기 때 줄바꿈 등이 섞임 | 스크립트에서 제어 문자 자동 제거 | +| Gitea 릴리스 생성 HTTP 500 | 서버가 태그를 직접 만드는 과정에서 실패 | 태그를 PC에서 만들어 푸시한 뒤, 있는 태그로 릴리스 생성 | +| `dotnet build` 패키지 복원 실패 | 작업 환경에서 NuGet 접속 불가 | Mono `mcs`로 빌드 | + +## 7. 참고 + +Gitea API 응답의 저장소 주소가 `http://192.168.88.15:3180/...`로 나옵니다. Gitea 설정의 `ROOT_URL`이 내부 주소로 되어 있기 때문입니다. 작업에는 영향이 없었지만, 웹에 보이는 링크나 복제 주소가 내부 IP로 표시될 수 있습니다. 외부 주소로 보이게 하려면 Gitea `app.ini`의 `ROOT_URL`을 `https://gitea.joynala.com/`로 바꿉니다.