2025. 2. 24. 18:43ㆍ개발자 과정/Kotlin
깃허브에선 기여도(contribution)라는 것이 있다.
그리고 이것을 우리는 잔디심기 라고 표현한다.
근데 문득 그런 생각이 들었다. 잔디가 많이 심어져 있는 것을 미덕으로 생각한다면,
진짜 "잔디만" 잔뜩 심어진 것은 미덕일까? 그럼 자동으로 잔디를 심어주는 봇을 만든다면 어떨까?
사실 말도 안되는 소리긴 하지만, 재밌을거 같으니 일단 만들어나 봤다.
1. 우선 더미 리포지토리를 하나 생성한다.
2. 해당 리포지토리를 클론해 로컬로 받아온다.
3. 봇을 구현한다.
main
class RunnablePlanter(
directory:String
){
private val modify=Modify("$directory/contribute.kt")
private val gitController=GitController(directory)
fun runnable() = runBlocking {
launch {
while (true) {
try {
modify.modifyFile()
gitController.gitProcess()
println("다음 실행까지 대기 중... (12시간)")
delay(12 * 60 * 60 * 1000L) // 12시간 대기
} catch (e: Exception) {
println("오류 발생: ${e.message}")
}
}
}
}
}
fun main(){
val runnableGitcro=RunnablePlanter(System.getenv("DIRECTORY"))
runnableGitcro.runnable()
}
백그라운드에서 돌아가야 하기에, 코루틴을 사용한다. 전체적인 로직의 흐름을 이곳에서 관리한다.
Modify
class Modify(
private val filePath: String
) {
private fun generateRandomString(count: Int = 30): String {
return (1..count)
.joinToString("\n\n") {
CodeDummy.dummyCodeSnippets.random()
}
}
fun modifyFile() {
val file = File(filePath)
val now = LocalDateTime.now()
val randomText = generateRandomString()
// 파일 내용을 지우고 새로 쓰기
file.writeText("$now\n[$randomText]")
println("파일 수정 완료: $now\n[$randomText]")
}
}
클론받은 더미 리포지토리의 kt파일을 열어서 무작위 더미 코드를 넣는 다. count를 통해 어느만큼 채워 넣을 것인지 조절할 수 있다.
CodeDummy
더미 코드는 길어서 그냥 첨부해 올린다.
GitController
class GitController(
private val repoPath: String
) {
fun gitProcess() {
val processCommands = listOf(
"git fetch origin",
"git checkout -B edit", // 새 브랜치 생성 (기존에 있으면 덮어씀)
"git add --renormalize .",
"git commit -m \"오늘의 코드: ${LocalDateTime.now()}\"",
"git push origin edit --force"
)
processCommands.forEach { command ->
val process = ProcessBuilder("cmd", "/c", command) // Linux/Mac용 (Windows는 "cmd", "/c" 사용)
.directory(File(repoPath)) // 실행 경로 지정
.redirectErrorStream(true)
.start()
process.inputStream.bufferedReader().use { reader ->
reader.lines().forEach { println(it) } // 실행 로그 출력
}
process.waitFor()
}
println("//////////////////////////////////////////////////\n" +
"PUSH 완료! GitHub Action Trigger")
}
}
커멘드를 통해 깃허브에 코드를 푸시하는 기능을 한다.
커멘드 라인을 잘 보면, 브랜치를 생성하여 그곳에다 푸시를 하는 것을 볼 수 있다.
이것은 보다 자연스러운 구조를 만들어, 자동화 감지를 피해보려는 의도이다.
4. 워크플로우를 작성한다
파일을 더미코드를 채워 수정하고, 브랜치를 생성하여 푸시했다면,
해당 브랜치를 통해 트리거를 작동하는 워크 플로우가 필요하다.
name: Auto Merge Edit to Main
on:
push:
branches:
- edit # edit 브랜치에 push 발생 시 실행
permissions:
contents: write
pull-requests: write
jobs:
merge:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: 0 # 전체 히스토리 가져오기
- name: Configure Git
run: |
git config --global user.name ""
git config --global user.email ""
- name: Authenticate GitHub Token
run: |
git remote set-url origin https://x-access-token:${{ secrets.TOKEN }}@"URL"
- name: Force Sync Main with Edit
run: |
git fetch origin
git checkout edit
git branch -f main edit # main 브랜치를 edit과 동일하게 만듦
git checkout main
git push --force origin main # main 브랜치를 강제로 덮어쓰기
edit브랜치에서 푸시가 감지되면, main 브랜치는 edit을 기준으로 하여 강제 덮어쓰기 한다.
5. 마무리
기존에 인터넷에 있는 방법들은 워크 플로우의 스케줄러를 사용하여 더미 커밋을 하는 것인데,
이 봇은 직접 코드 스니펫을 작성하여 실제 코드 작성처럼 보이는 눈속임을 했다는 것에 의의가 있다.
역시 하등 도움 안는거 할때가 제일 재밌다.
'개발자 과정 > Kotlin' 카테고리의 다른 글
퉁퉁퉁퉁퉁퉁퉁퉁퉁 사후르 게임을 만들어 보자 (0) | 2025.04.28 |
---|---|
깃허브 파종기 MK.2 (리모트 컨트롤, 문자알림, 디스코드 웹훅) (0) | 2025.02.28 |
(kotlin-spring) twilio 문자 인증/문자 전송 서비스 만들기 (0) | 2025.02.12 |
springboot기초(외전)-추상화는 곧 가독성이다. (0) | 2025.01.08 |
springboot기초(4)-멤버를 추가해보자 (3) | 2024.10.03 |