레이블이 github인 게시물을 표시합니다. 모든 게시물 표시
레이블이 github인 게시물을 표시합니다. 모든 게시물 표시

docker build image apt-update error

# 잘 되던 docker 이미지 빌드 중 Dockerfile 에서 패키지 업데이트시
RUN apt-get update
...
#6 10.23 Reading package lists...
#6 10.24 W: The repository 'http://security.debian.org/debian-security stretch/updates Release' does not have a Release file.
#6 10.24 W: The repository 'http://deb.debian.org/debian stretch Release' does not have a Release file.
#6 10.24 W: The repository 'http://deb.debian.org/debian stretch-updates Release' does not have a Release file.
#6 10.24 E: Failed to fetch http://security.debian.org/debian-security/dists/stretch/updates/main/binary-amd64/Packages  404  Not Found
#6 10.24 E: Failed to fetch http://deb.debian.org/debian/dists/stretch/main/binary-amd64/Packages  404  Not Found
#6 10.24 E: Failed to fetch http://deb.debian.org/debian/dists/stretch-updates/main/binary-amd64/Packages  404  Not Found
#6 10.24 E: Some index files failed to download. They have been ignored, or old ones used instead.
------
executor failed running [/bin/sh -c apt-get update && apt-get install -y net-tools htop lsof wget curl rsync vim tar man-db traceroute]: exit code: 100

# 기본 이미지를 변경하면 잘 동작한다. 
FROM golang:1.17-stretch  -> FROM golang:1.19

# 참고로 데이안 계열 이미지 suffix 로 붙는 이름(코드네임)
-없는경우 debian latest
-bullseye: debian 11 
-buster: debian 10.4
-stretch: debian 9
-jessie: debian 8

commit does not belong to any branch

# 잘못된 email 주소가 있어 수정하기 위해 아래 포스팅한 rebase 스크립트를 실행했다.
# rebase 후 tag 를 푸시하지 않았고 no branch(브랜치가 없는) 커밋으로 남게 됐다.
# git log 에는 보이지 않지만 tig cli 툴로 보면 최초 커밋 이전에 수정전 커밋이 no-branch 상태로 추가되어 보인다.

# tig 에서 봤을때 tag 커밋은 no branch 상태로 email 도 수정되지 않은 상태였다.
# 깃헙에서 no-branch 커밋을 보면 다음과 같은 메시지가 나온다.
https://github.com/xxxx/commit/{커밋해시} 
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

# 또 다음 명령으로 커밋이 포함된 브랜치를 찾아도 결과가 없다.
git branch --contain {커밋해시}

# 문제는 tig 로 보면 no-branch 커밋들이 최초 커밋 이전에 중복되어 보인다는 것이다.

# [해결방법]
# 다시 위 포스팅의 rebase 스크립트(이름,email 값 변경해서)를 실행했다.
# mater, develop 강제 푸시해도 변경사항이 없다고 나왔지만, tag 는 강제 푸시가 됐다.
git push --tags -f

# tig 에서 다시 확인해보니 email 수정된 tag 커밋이 제대로 반영됐다.(해결!)

# [로컬 refs 제거방법]
# 추가로 no branch (tag) 커밋들은 다음과 refs/.. 로만 표시된다.
refs/original/refs/tags/1.0.0
refs/original/refs/tags/1.0.1

# refs 는 로컬에 남아 있는 참조 정보라 지워도 된다.
# refs 지우기
# 방법1
# 다음과 같이 일일히 삭제하면 된다.
git update-ref -d refs/original/refs/tags/1.0.0
git update-ref -d refs/original/refs/tags/1.0.1

# 방법2
# 아래 경로의 파일들을 삭제해도 된다. 하지만 .git 내용을 직접 수정하는거 권장되지 않는다.
rm -rf .git/refs/original

# 방법3
# 삭제해야할 refs 가 많다면 이미 remote(origin) 에는 푸시됐으니 로컬에서 새로 클론 받자.
git clone http://{저장소}

# 참고로 이제 tig 에선 no branch 상태의 커밋들이 보이진 않지만
# https://github.com/xxxx/commit/{커밋해시} 에는 여전히 no branch 커밋들을 확인할 수 있다.
# rebase 가 수정된 새로운 커밋을 생성하는거고 이전의 no branch 커밋들은 유효하지 않은 상태로 github 저장소에 계속 남아 있는 것으로 보인다.
# 이 부분은 제거가 안돼서 저장소를 새로 만들어야 하는것 같다.

github action ubuntu sh syntax error

# github action 중 다음 스크립트를 실행하는데
- name: build script
  run: |
    echo "execute script..."
    sh ysoftman.sh lemon

# ysoftman.sh 내용
if [[ ${1} == "lemon" ]]; then
    echo "ok"
else
    echo "no"
fi

# 원하는 결과가 나오지 않아 action 로그를 보니 다음과 같이 syntax 에러가 찍혀 있었다.
ysoftman.sh: 1: [[: not found

# 원인은 ubutun 위에서 action 이 실행되고 있었고,
# ubuntun 에서 sh -> /bin/dash 로 /bin/bash 문법과 호환되지 않아서다.
# 해결을 위해 /bin/bash 로 실행~
/bin/bash ysoftman.sh lemon

argo-cd git sync interval

argo-cd 가 git 의 변경사항을 감지해 싱크하는게 바로 안되는것 같아 찾아보니
application details > sync policy 에는 다음과 같이 3가지 항목만 설정만 보인다.
application 별로 sync interval 은 설정할 수 없는것 같다.
대신 application 구분 없이 github 을 기본 3분단위로 polling 한다.

argo-cm(configmap) 에 timeout.reconciliation: 180s 등으로 설정할 수 있다.

git push Repository not found

# git push 할때 정확한 URL 로 pull 도 되지만, 다음과 같이 Repository not found 가 발생하는 경우가 있다.
git push
remote: Repository not found.
fatal: repository 'https://github.com/ysoftman/test_cod.git/' not found

# 해당 사용자에게 쓰기권한(push)을 부여하면 된다.
깃헙 저장소 > setting > collaborators > manage access > add people > 사용자 선택 후 write 나 admin role 으로 추가하면 된다.

# 흠, not found 대신 push 권한이 없다고 알려주면 좋을텐데~

git lfs(Large File Storage) command

git lfs(Large File Storage) 는 dataset,audio,video 같은 용량이 큰 파일을 저장해주는 서비스이다.

github 은 파일 1개 용량이 100MB 넘는 파일을 푸시를 막고 있다.

100MB 넘은 파일을 push하면 다음과 같은 에러가 발생한다.
remote: error: File aaa.zip is 100.59 MB; this exceeds GitHub's file size limit of 100.00 MB
remote: error: GH001: Large files detected. You may want to try Git Large File Storage
! [remote rejected] master -> master (pre-receive hook declined)

https://github.com/settings/billing > git lfs data 를 보면 계정당 1GB 용량까지는 무료고 그 이상은 유료다.

# git lfs 설치
brew install git lfs

# 현재 계정 lfs 초기화
git lfs install

# 초기화 하면 ~/.gitconfig 설정에 다음 내용이 추가된다.
[filter "lfs"]
  clean = git-lfs clean -- %f
  smudge = git-lfs smudge -- %f
  process = git-lfs filter-process
  required = true

# 이제 github 프로젝트 디렉토리로 이동한다.
# 트랙된 파일들은 LFS 로 저장되고 관리된다.
git lfs track "*.jpg"
git lfs track "*.zip"
git lfs track "*.tar.gz"

# 트랙되고 있는 패턴 보기
git lfs track

# .gitattributes 에 다음과 같이 설정되니 이 파일을 직접 수정해도 된다.
cat .gitattributes
*.jpg filter=lfs diff=lfs merge=lfs -text
*.tar.gz filter=lfs diff=lfs merge=lfs -text
*.zip filter=lfs diff=lfs merge=lfs -text

# .gitattributes 파일을 커밋해야 github 에서 lfs 로 트랙할 수 있다.
git add .gitattributes 
git commit -a -m "add lsf settings"
git push

# 이제 파일을 커밋 및 푸시
git add xelloss.jpg
git add pizza_or_not_pizza.zip
git commit -a -m "lsf test"
git push

# 커밋된 트랙 파일들 보기
git lfs ls-files

# github 에서 파일을 클릭하면 다음과 같이 LFS 에 저장되어있다고 나오며 download 할 수 있다.


github 인증 방식 변경

2021-08-13 부터 github 인증 방식이 변경돼, 푸시하면 다음과 같이
PAT(personal access token)를 사용하라고 나온다.

remote: Support for password authentication was removed on August 13, 2021. Please use a personal access token instead.
remote: Please see https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations/ for more information.
fatal: unable to access 'https://github.com/ysoftman/test_code/': The requested URL returned error: 403

PAT 생성, 토큰 생성 후 한번만 보이기 때문에 복사해둔다.

# 혹시 기존 암호가 저장되어 있으면 삭제한다. (나중에 PAT 값으로 새로 생성된다.)
Keychain Access.app  -> github.com 삭제

# 이제 푸시할때 password 를 물어보는데 이때 암호 대신 PAT 를 입력한다.
git push
Username for 'https://github.com': ysoftman
Password for 'https://ysoftman@github.com': 토큰값

github Invalid webhook signature error

# drone ci 에서 사용할 github webhook 생성했는데, 400 응답에 다음 에러 발생했다.
{"message":"Invalid webhook signature"}

# drone 용 webhook 설정시 필요 없는 secret 설정을 했고,
# 이후 secret 부분을 삭제하고 webhook 업데이트만 했는데 계속 에러가 발생했다.
# 이전 잘못된 secret 가 drone db 에 저장되어 있기 때문이다.

# 다음 링크를 보면 drone webhook 은 수동으로 설정할 수 없다고 한다.
# drone 이 secret 없는 webhook 에 응답해 secret 을 설정할 수 있도록해야 한다.

# 해결 방법
1. 기존 github webhook 을 수정하면 안되고 삭제 후 github webhook 새로 만든다. 이때 secret 는 비워둔다.
2. drone -> repositories -> 저장소 -> settings -> disable repository 후 다시 저장소를 찾아 active 시킨다.
3. drone 저장소 재시작 후 github webhook 의 secret 값이 자동 채워진다. 이제 push 하면 성공한다.


#####

# 추가로 github webhook 에서 다음과 같이 타임아웃 에러 발생시
We couldn’t deliver this payload: timed out

# drone 로그 메시지를 확인해보면
# drone configuration (.drone.yml) 파일을 찾지 못하는 경우 일 수 있으니
docker logs -f drone
{"commit":"xxxxx","error":"Not Found","event":"push","level":"warning","msg":"trigger: cannot find yaml","ref":"refs/heads/test123","repo":"ysoftman/test-drone","time":"2022-03-17T07:48:41Z"}

# drone -> 저장소 -> settings -> configuration 파일을 변경하자.

drone ci 사용하기

# golang 으로 만들고 docker 환경으로 실행되는 drone ci 를 사용해보자.

# 우선 로컬에서 테스트하기 때문에 
# (reverse proxy 로 ngrok 도메인 -> localhost 로 터널링 해주는) ngrok 설치
brew install ngrok

# http://fe9b41d98488.ngrok.io -> http://localhost:80 포워딩을 위해 실행
# 참고 https (tls) 터널링은 유료 버전만 가능하고, 그외 동시접속 제한이 있다.
ngrok http 80

# github oauth 로 drone 앱(서버)를 등록
# github -> settings -> developers -> oauth apps 에서 신규 생성한다.
# homepage url : http://dd441e3e9f16.ngrok.io
# callback url : http://dd441e3e9f16.ngrok.io/login

# oauth app 생성후
# client -> DRONE_GITHUB_CLIENT_ID
# client secret -> DRONE_GITHUB_CLIENT_SECRET 로 사용한다.
# generate a new client secret(생성후 한번 볼 수 있어 복붙해둬야 한다) -> DRONE_GITHUB_CLIENT_SECRET 값으로 사용

# drone <-> runner 간 RPC 통신을 위한 secret 생성 -> DRONE_RPC_SECRET 값으로 사용
openssl rand -hex 16                         
d087c94b8155367b1982238df930c2f2

# drone 도커 이미지 다운로드
docker pull drone/drone:1

# 실행
# github enterprise 는 깃헙 서버 환경 변수 설정 필요
# --env=DRONE_GITHUB_SERVER=https://github.ysoftman.com \
# 볼륨 연결로 /data/database.sqlite -> 호스트의 /var/lib/drone/database.sqlite 로 저장
docker run \
  --volume=/var/lib/drone:/data \
  --env=DRONE_DATABASE_DRIVER=sqlite3 \
  --env=DRONE_DATABASE_DATASOURCE=/data/database.sqlite \
  --env=DRONE_GITHUB_CLIENT_ID=깃헙_클라이언트_id \
  --env=DRONE_GITHUB_CLIENT_SECRET=깃헙_클라이언트_secret \
  --env=DRONE_RPC_SECRET=d087c94b8155367b1982238df930c2f2 \
  --env=DRONE_SERVER_HOST=127.0.0.1 \
  --env=DRONE_SERVER_PROTO=http \
  --env=DRONE_WEBHOOK_ENDPOINT=http://dd441e3e9f16.ngrok.io/hook \
  --env=DRONE_WEBHOOK_SECRET=d087c94b8155367b1982238df930c2f2 \
  --env=DRONE_REPOSITORY_FILTER=ysoftman,bill \
  --publish=80:80 \
  --publish=443:443 \
  --restart=always \
  --detach=true \
  --name=drone \
  drone/drone:1

# 이제 다음 url 로 github authorize 하면 깃헙으로 로그인상태로 drone ci 를 사용할 수 있다.
http://dd441e3e9f16.ngrok.io

# DRONE_REPOSITORY_FILTER 으로 특정 저장소에만 drone과 연결 할 수 있다.
# 설정 변경 후 사용자별로 로그아웃 후 다시 로그인 해야 반영된다.

#####

# 상황에 맞는 여러 runner(러너)가 있다.
# docker(임시 컨테이너를 생성해 실행할때 사용) 러너 설치
docker pull drone/drone-runner-docker:1
docker run -d \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e DRONE_RPC_PROTO=http \
  -e DRONE_RPC_HOST=dd441e3e9f16.ngrok.io \
  -e DRONE_RPC_SECRET=d087c94b8155367b1982238df930c2f \
  -e DRONE_RUNNER_CAPACITY=2 \
  -e DRONE_RUNNER_NAME=${HOSTNAME} \
  -e DRONE_DEBUG=true \
  -e DRONE_TRACE=true \
  -p 3000:3000 \
  --restart always \
  --name runner \
  drone/drone-runner-docker:1

# exec(docker 와 같은 고립된 환경이 아닌 drone 서버 장비에서 쉘 환경에서 명령을 실행할 때 사용) 러너를 설치
curl --proxy "필요한 경우 프록시 설정" -L https://github.com/drone-runners/drone-runner-exec/releases/latest/download/drone_runner_exec_linux_amd64.tar.gz | tar zx
sudo install -t /usr/local/bin drone-runner-exec
mkdir -p /home/ysoftman/.drone-runner-exec
touch /home/ysoftman/.drone-runner-exec/config
cat > /etc/drone-runner-exec/config << eof
DRONE_RPC_PROTO=http
DRONE_RPC_HOST=dd441e3e9f16.ngrok.io
DRONE_RPC_SECRET=d087c94b8155367b1982238df930c2f
DRONE_LOG_FILE=/home/ysoftman/.drone-runner-exec/log.txt
eof
drone-runner-exec service install
drone-runner-exec service start

# drone-runner-exec 서비스 상태 확인
systemctl status drone-runner-exec.service

# docker 환경 변수 확인
docker inspect -f "{{.Config.Env}}" drone  | tr " " "\n"


# ssh(ssh 로 서버에 접속해 명령을 실행하는 용도) 러너 설치
docker pull drone/drone-runner-ssh
docker run -d \
  -e DRONE_RPC_PROTO=http \
  -e DRONE_RPC_HOST=dd441e3e9f16.ngrok.io \
  -e DRONE_RPC_SECRET=d087c94b8155367b1982238df930c2f \
  -p 3000:3000 \
  --restart always \
  --name runner \
  drone/drone-runner-ssh

# 루트 경로에 .drone.yml 를 작성한다.
# 파일명은 drone ci settings 에서 변경 가능하다.
---
kind: pipeline
type: exec
name: default

platform:
  os: linux
  arch: amd64

trigger:
  event:
    - push
steps:
  - name: 작업1
    commands:
      - echo hello world1
  - name: 작업2
    commands:
      - echo hello world2
  - name: 슬랙 알림
    # environment:
    #   noti_msg: "Branch: ${DRONE_BRANCH}\nAuthor: ${DRONE_COMMIT_AUTHOR}\nLink: ${DRONE_COMMIT_LINK}"
    #   build_status: "✅ build ${DRONE_BUILD_NUMBER} succeeded. Good job."
    commands:
      - echo "파이프 종료"
      - export HTTP_PROXY="http://프록시서버"
      - export noti_msg="Branch ${DRONE_BRANCH}\nAuthor ${DRONE_COMMIT_AUTHOR}\nLink ${DRONE_COMMIT_LINK}"
      - export build_status="✅ build ${DRONE_BUILD_NUMBER} succeeded. Good job."
      - echo $DRONE_BUILD_STATUS
      - if [[ $DRONE_BUILD_STATUS == "failure" ]]; then build_status="❌ build ${DRONE_BUILD_NUMBER} failed. Fix me please."; fi
      - |
        curl https://hooks.slack.com/services/..... -d "payload={\"channel\": \"#billtest\", \"text\": \"파이프 라인 시작\n$noti_msg\n$build_status\"}"
# ---
# kind: pipeline
# type: ssh
# name: default
# # 접속할 대상 서버
# server:
#   host: ysoftman-server.com
#   user: deploy
#   password:
#     from_secret: password
# steps:
#   - name: 작업1
#     commands:
#       - echo hello world1
#   - name: 작업2
#     commands:
#       - echo hello world2
# ---
# kind: pipeline
# type: docker
# name: slack notification
# # 사내환경등에서 외부 접속이 안되는 경우 프록시 환경 변수 설정
# environment:
#  HTTP_PROXY: "http://프록시주소"
#  HTTPS_PROXY: "http://프록시주소"
# steps:
#   - name: 슬랙 알림
#     # 사내환경등에서 외부 이미지 다운로드가 안되는 경우 알맞게 변경
#     image: plugins/slack
#     settings:
#       # https://my.slack.com/services/new/incoming-webhook 참고
#       webhook: https://hooks.slack.com/services/.....
#       channel: ysoftman-test
#       template: >
#         {{#success build.status}}
#           build {{build.number}} succeeded. Good job.
#         {{else}}
#           build {{build.number}} failed. Fix me please.
#         {{/success}}
#         Branch: {{ build.branch }}
#         Author: {{ build.author }}
#         Link: {{ build.link }}

# 이제 drone DRONE_WEBHOOK_ENDPOINT 변수로 설정된 url 을
# github 저장소 webhook url 을 추가해 push 되면 drone 에 알리도록 한다.
http://dd441e3e9f16.ngrok.io/hook

# 참고로 위의 HTTP_PROXY 와 같은 환경변수를 사용할때 
# ${HTTP_PROXY} 는 안되고 {} 를 제거한 $HTTP_PROXY 로 사용해야 한다.

#####

# drone cli 툴 사용 https://docs.drone.io/cli/install/
# 설치
brew install drone-cli

# aaaaabbbbb11111 는 drone > User Settings > token 로 확인
# 접속할 drone 서버 환경 변수 설정
export DRONE_SERVER=http://dd441e3e9f16.ngrok.io
export DRONE_TOKEN=aaaaabbbbb11111

# 접속 여부 확인
drone info

# .drone.yml 작업 수행(커밋 전에 미리 로컬에서 테스트할 수 있다.)
# drone exec 현재 type: docker 만 실행된다.
# .drone.yml 을 다음과 같이 만들고
kind: pipeline
type: docker
name: default

steps:
- name: build
  image: golang:1.13
  commands:
  - echo "aaa"

# 실행
# .drone.yml syntax 체크등에 활용할 수 있다.
drone exec

github notification

# 사내 Github PR review, push 등이 email 알림으로 오는데,
# email 은 잘 보지도 않고 쌓이기만 해서(메일 정리하는것도 일)
# 깃헙 email 알림을 비활성화
(깃헙 개인 settings -> Notifications -> Email notification preferences)

# notifier-for-github 크롬 익스텐션을 사용하면 깃헙 알림이 아이콘으로 표시된다.

# Root URL 설정 - 기본 https://github.com
# github enterprise 라면 https://github.회사.com 와 같이 설정한다.

# Token 설정
# github enterprise 라면 https://github.회사.com/settings/tokens
(깃헙 개인 settings -> Settings Developer settings -> Personal access tokens -> repo, notification 체크해서 생성)
# 또는 익스텐션 옵션 설정 "create token" 링크로 로그인하면
# 다음과 같이 repo, notification 체크된 상태로 토큰 설정을 할 수 있다.

# 이제 알림이 있다면 크롬에서 다음과 같이 알림 개수가 표시된다.

# notifier-for-github 익스텐션 background console 을 보면
# https://github.회사.com/api/v3/notifications?page=1&per_page=1
# 과 같이 요청하는것으로 보인다.

# 참고 - github notification api
# 사용자명(ysoftman)과 토큰(abc123456789)으로 사용할 수 있다.
curl 'https://github.com/api/v3/notifications?page=1&per_page=1' -u ysoftman:abc123456789


Jenkins github REAMD.md 수정시 빌드 제한

# git 저장소에 README.md 같은 파일 커밋발생시 원치않은 jenkins 빌드가 발생한다.
# 이를 막기 위해선 해당 jenkins 잡에서 아래화면처럼 exclude 영역을 추가하면 된다.
소스 코드 관리 -> git -> additional behaviours -> polling ignores commits in certain
paths -> excluded regions

# 특정 디렉토리의 모든 파일 제외
docs/.*


# 참고로 아직 pipeline 잡에서는 exclude regions 기능에 문제가 있어 보인다.

jenkins github credential 실패시 확인사항

[문제]
github.aaa.com 에서 github.bbb.com 으로 마이그레이션
github.bbb.com 계정으로 developer settings -> personal access token 을 생성
jenkins -> credentials -> ysoftman bbb secrect key (personal access token 를 사용한다.) 생성
jenkins -> 환경설정 -> github 에 다음과 같이 설정하고
API URL : https://github.bbb.com/api/v3
Credentials : ysoftman bbb secrect key
Test connection 실행하면 다음과 같이 실패한다.
Failed to validate the account

[원인 및 해결]
/var/jenkins/jenkins.log 로그를 보면 403(bad request)로 실패한다.
그런데 jenkins 서버 터미널로 테스트 하면 github.bbb.com 에 잘 접속된다.
curl http://ysoftman:토큰@github.bbb.com/api/v3

원인은 jenkins 에 설정된 프록시 서버 문제로
jenkins -> plugin manager -> 고급 -> http 프록시 설정에 no proxy host 에 github.bbb.com 추가하면 접속 된다.
jenkins job 까지 프록시 설정을 반영하기 위해선 http://젠킨스주소/restart 로 재시작해야 한다.

[추가로]
tomcat 상으로 jenkins 가 구동되는 경우, jenkins 만 재시작하면 안된다.
tomcat 데몬이 올라갈때의 no_proxy 설정이 유지되기 때문에
bash 상에서 다음과 같이 no_proxy 설정 후 tomcat 을 재시작해야 한다.
export no_proxy=github.aaa.com,github.bbb.com

github jenkins webhook 사용

# github repository(저장소)에서 commit, push 등 이벤트가 발생할 경우 jenkins 로 알리는 webhook(웹훅)을 사용할 수 있다.

# 우선 jenkins 에서 github plugin 이 설치되어 있어야 한다.
https://wiki.jenkins.io/display/JENKINS/GitHub+Plugin

# 방법1
# jenkins job(잡) -> 구성 -> 빌드유발 -> Poll SCM 체크
# 이 방법은 주기적 폴링(체크)해야 하기 때문에 추천하지 않는다.

# 방법2
# github 저장소 설정에 jenkins hook url 을 설정한다.
github 저장소 -> setings -> integration&services -> add services -> jenkins(github plugin) -> jenkins hook url

# 그리고 jenkins job(잡) -> 구성 -> 빌드유발 에서 다음 항목을 체크한다.
GitHub hook trigger for GITScm polling

# 참고로 jenkins(github plugin) deprecated 되서 사용하지 않는것이 좋다.
Note: GitHub Services are being deprecated. Please contact your integrator for more information on how to migrate or replace a service with webhooks or GitHub Apps.

# 방법3
# 위 방법2은 github 저장소 설정에 jenkins(github plugin)를 다수 등록 수 없다.
# 그래서 2개 이상의 jenkins 서버를 사용하기 위해 웹훅으로 설정해야 한다.
# github 설정에서 web hook 추가
github 저장소 -> settings -> hooks -> webhooks -> add webhook
# 마지막은 /으로 끝나야 동작한다.
Payload URL : https://젠키스도메인/github-webhook/
Content type : application/x-www-form-urlencoded
Secret: 빈값
Let me select individual events.
Pull requests, Pushes ... 등 웹훅이 필요한 상황 체크
Recent Deliveries 에서 체크할 ping 결과를 테스트 할 수 있다.

# 그리고 jenkins job(잡) -> 구성 -> 빌드유발 에서 다음 항목을 체크한다.
GitHub hook trigger for GITScm polling

# pipeline 으로 구성한 잡의 경우 별도의 설정 없이 /github-webhook 으로 요청이 들오면 파이프라인이 시작된다.

# 이제 github(jenkins 잡에서 설정한 브랜치)에 푸시(github 에서 설정한 이벤트들) 이벤트가 발생하면 잡을 트리거할 수 있다.

github CODEOWNERS 설정

# 저장소 docs/CODEOWNERS 를 다음과 같이 설정하면
# github 에서 Pull-Requests 을 생성할때 리뷰어가 자동 지정된다.
vi doc/CODEOWNERS
*.h  @ysoftman @bill
*.cpp @ysoftman

# 한가지 주위할 점은 계정이름에 . 있다면 - 로 변경해야 한다.
*.cpp @ysoftman.123 <--- error
*.cpp @ysoftman-123 <--- ok

# 참고 https://blog.github.com/2017-07-06-introducing-code-owners/

github pages 배포와 github 장애

github-pages 내용을 변경하고 푸시까지 성공했는데,

https://ysoftman.github.io/

변경 내용이 반영되지 않는 문제가 발생했다.

github-page -> environment -> deploy activity 에도
오늘(2018-10-22) 배포 기록이 없다.
하루 종일 브랜치명을 바꿔보고, 수차례 커밋을 해봐도 변경사항이 반영되지 않았다.

혹시나 해서 자동 로그인된 github.com 를 다시로그인 하려는데, 로그인 되지 않는다.
뭐지? 안내문구에 다음 URL 을 들어가 보니

https://status.github.com/messages



아침부터 데이터 스토리지 다운 이슈가 있었다고 한다.

https://thenextweb.com/dd/2018/10/22/github-is-down-because-of-data-storage-issues/

깃헙 홈페이지에 명시를 해주던가 해야지, 하루종일 삽질만 했네.ㅠ



jenkins multibranch pipeline 환경 설정

# 우선 github 계정에 personal access token 을 생성한다.
settings -> developer settings -> personal access token 에서
scopes 선택시, repo 권한 admin:repo_hook 권한을 체크한다.

# jenkins multibranch pipeline 사용하기
# 다음 플러그인들을 설치 한다.
Blue Ocean : 파이프라인 작성을 UI 적으로 사용(관련 플러그인들이 함께 설치된다.)
Pipeline: Stage View Plugin
GitHub API Plugin
GitHub Authentication plugin
GitHub Branch Source Plugin
GitHub Pipeline for Blue Ocean
GitHub plugin

# API endpoint : jenkins 관리 -> 시스템설정 에서 다음 항목을 설정해야 한다.
# github github servers -> api urls
api urls : https://developer.github.com/v3/

# github github servers -> credentials
# github 저장소 접근 id, pw(personal access token) 으로 추가.
# 추가 후 해당 credential 의 ID(123-456-789) 값을 jenkinsfile 에 명시한다.
environment {
   ysoftman = credentials('123-456-789')
}

# github enterprise servers -> api endpoint
api endpoint : https://developer.github.com/v3/
name : ysoftman github

# multibranch pipeline 생성
jenkins -> new item -> multibranch pipeline : ysoftman_multibranch_pipeline

# github 브랜치 설정
# ysoftman_multibranch_pipeline -> configure -> branch sources
# API endpoint : 위 시스템 설정에한 넣은 값 선택
# Credentials : 위 시스템 설정에한 넣은 값 선택
# Owner : https://github.com/ysoftman/test_code 의 경우 ysoftman
# Repository : owner 의 저장소 리스트를 볼 수 있고 이중 하나를 선택할 수 있다.
# Behaviours : 선택한 저장소의 All branches 를 스캔할 수 있다.


# orphaned item strategy -> discard old item 을 선택하면 삭제된 브랜치나 태그들은 모두 파이프라인에서 바로 제거 된다.
# 아래 처럼 유지 기간을 입력하면 삭제 되더라도 7일까지만 유지하고 지나면 삭제한다.
# 참고로 0 값은 설정할 수 없고 빈값으로 설정해야 바로 제거 된다.
# Days to keep old items: 빈값
# Max # of old items to keep: 빈값


# 파이프라인 스크립트(jenkinsfile) 작성
# jenkinsfile 는 groovy(자바동작타입스크립트언어)사용 스크립트 사용한다.
# jenkinsfile 파일 작성방법
https://jenkins.io/doc/book/pipeline/

# 스크립트에 문제가 있다면 다음과 같은 에러가 발생한다.
GitHub has been notified of this commit’s build result
java.lang.NoSuchMethodError: No such DSL method 'cleanWs' found among steps

# 위 에러 예시는 cleanWs() 함수를 사용할수 없는 경우로
# Workspace Cleanup Plugin 플러그인을 설치해야 한다.

# 참고로 jenkinsfile 은 에러가 있을 경우
# build history -> replay 에서 스크립트를 수정해 테스트할 수 있다.
# 테스트 후 문제가 없다면 github 저장소로 커밋/push 하자.

sourcetree 삭제된 원격 브랜치가 보이는 문제

# 터미널에서 원격 브랜치를 파악한 결과와
git ls-remote | grep ysoftman

# sourcetree 에서 
원격 -> origin -> feautre -> ysoftman... 

# 브랜치 내용이 다른 경우가 있다.
# 실제 github 기준으로 보면 sourcetree 내용이 잘못된것을 알 수 있다.

# 이와 관련해서 문의한 내용이 있다.


# 로컬에 stable 브랜치가 생기는 이유는 로컬에서 삭제하지 않고 github 에서 삭제해서다.

# prune 옵션 설명
Deletes all stale remote-tracking branches under <name>. These stale branches have already been removed from the remote repository referenced by <name>, but are still locally available in "remotes/<name>".
With --dry-run option, report what branches will be pruned, but do not actually prune them.

# 다음과 같이 prune 옵션으로 stable 브랜치들을 지워서 갱신하면 된다.
git remote prune origin


# 위 명령을 실행하면 실제 원격 브랜치에 없는 것들은 로컬에서 pruned 된다.
# 이제 sourcetree 리프레시 다시 확인하면 실제 없는 브랜치들이 사라진것을 확인 할 수 있다.

git push 된 커밋 사용자 name, email 변경

# 현재 저장소 ./git/config 에 user(name, email) 을 설정하지 않은 상태에서
# 전역 ~/.gitconfig 에 설정된 회사 user(name, email) 로
# 오랫 동안 commit , push 하고 있었다.
# github 에선 등록되지 않은 email 로 contribution 카운트가 누락된다.
# 이미 push 된 커밋들의 author(user name, email)를 변경할 수 있다.
# 참고 https://www.git-tower.com/learn/git/faq/change-author-name-email


#####


# [첫번째 방법]
# 잘못된 author 로 커밋이 일어나기 전의 커밋으로 rebase 한다.
# 잘못된 커밋 해시 이후 부터 head 까지의 커밋들을 수정할 수 있다.
# -i, --interactive 사용자가 rebase 하기전에 수정할 수 있도록 한다.
# --preserve-merge 를 옵션을 사용하지 않으면 하나의 브랜치 커밋들로 변경된다.
git rebase -i --preserve-merge 잘못된_커밋_이전_커밋_해시

# 최초 커밋부터 잘못되었다면
git rebase -i --root

# 이제 rebase 커밋 이후의 모든 커밋들이 vim 에디터로 보인다.
# 위쪽 부터가 오랜된 커밋이다.
# github 커밋 기록을 보면서 잘못된 커밋은 pick -> edit 또는 e 로 변경해 저정한다.


# 이제 터미널에서 커밋마다 author 만 수정한다.
# 참고로 --abort 로 rebase 취소할 수 있다.
git commit --amend --author="ysoftman <ysoftman@gmail.com>" --no-edit

# rebase 계속 진행(다음 커밋으로 이동)
git rebase --continue

# 위 두과정을 커밋이 없을때까지 반복한다.
# 더이상 진행할 커밋이 없으면 다음과 같은 메시지 나온다.
Successfully rebased and updated refs/heads/master.

# master, develop, feature 등 로컬의 브랜치 마다 강제 push 한다
git push -f

# 혹시 로컬에 rebase 전 상태로 clone 받은 곳이 있고, 여기서 git pull 하면
# 이곳에선 rebase 수정전 커밋들이 그대로 남아있고 수정한 커밋들이 추가되는 형상이 된다.
# 여기서 push 하면 다시 수정한 커밋들이 푸시되니 이런 clone 은 삭제하자.


#####


# [두번째 방법]
# 우선 git pull 받아 최신 상태로 업데이트한다.
https://git-scm.com/docs/git-filter-branch
# 다음 스크립트를 이용해 한번에 변경할 수 도 있다.(완전 편함~ㅋ)
git filter-branch --env-filter '
WRONG_EMAIL="wrong@example.com"
NEW_NAME="ysoftman"
NEW_EMAIL="ysoftman@gmail.com"
if [ "$GIT_COMMITTER_EMAIL" = "$WRONG_EMAIL" ]
then
    export GIT_COMMITTER_NAME="$NEW_NAME"
    export GIT_COMMITTER_EMAIL="$NEW_EMAIL"
fi
if [ "$GIT_AUTHOR_EMAIL" = "$WRONG_EMAIL" ]
then
    export GIT_AUTHOR_NAME="$NEW_NAME"
    export GIT_AUTHOR_EMAIL="$NEW_EMAIL"
fi
' --tag-name-filter cat -- --branches --tags

# pull 표시가 나더라도 pull 없이 강제 push 한다.
# master, develop, feature, tag 등 로컬의 브랜치들을 강제 push 한다.
git push origin master -f
git push origin develop -f
git push --tags -f

# git filter-branch 를 실행해서 다음과 백업이 있어 실행하지 못한다면
# git filter-branch 뒤에 -f 로 강제(백업 덮어쓰기)할 수 있다.
Cannot create a new backup.
A previous backup already exists in refs/original/
Force overwriting the backup with -f

# 로컬에 refs/original/refs/... 참조가 보이면 삭제한다.
# 업데이트할 참조가 많다면 새로 clone 받는것이 편할 수 있다.
git update-ref -d refs/original/refs/heads/master
git update-ref -d refs/original/refs/heads/develop


#####


# 실제 커밋(contribute) 수 보다 적게 표시되는 상황


# author 수정 후 정상 카운트 되는 contributions


#####

# rebase 이전의 커밋들이 보일 수 있다.
# 이를 표시하지 않으려면 해당 release 혹윽 태그를 삭제해야 한다.
git tag -d ysoftman-release-1
git tag -d ysoftman-hotfix-1


#####


# 참고로 여러 커밋을 합치는 경우 위 vim 커밋 수정화면에서
# 방법1
# 합칠 커밋들을 s 또는 squash 로 변경해 저장한다.
# s 로 표시한 커밋과 s 바로 이전 커밋이 vim 편집 화면이 열리고 커밋 메시지를 수정하고 저장하면 s -> s 이전 커밋으로 합쳐진다.
# 방법2
# 합칠 커밋들을 f 또는 fixup 로 변경해 저장한다.
# f 로 표시한 커밋 메시지는 vim 편집 화면 없이 삭제되며 f -> f 이전 커밋으로 합쳐진다.

github api 사용하기

# 사용자의 모든 저장소 정보
curl -s --user "ysoftman:password123" https://api.github.com/user/repos

# 해당 저장소에서 사용되는 언어별 사용 bytes
 curl -s --user "ysoftman:password123" https://api.github.com/repos/ysoftman/test_code/languages

# github api 를 이용해 이슈 정보 파악하기
# https://developer.github.com/v3/issues/
# 이슈번호 : 10
curl -s --user "ysoftman:password123" https://api.github.com/repos/ysoftman/test_code/issues/10

# git release 정보 파악하기
# https://developer.github.com/v3/repos/releases/
curl -s --user "ysoftman:password123" https://api.github.com/repos/ysoftman/test_code/releases

github pages 사용하기

[github pages ?]
github 에서 무료로 호스팅하는 웹페이지로 github.io 도메인을 사용한다.
페이지의 저장소는 1GB 사용할 수 있어 다양하게 활용될 수 있다.

[github pages 생성]
1. "계정명.github.io"(ysoftman.github.io) 이름의 저장소를 생성
2. index.html 파일을 저장소 루트 경로에 추가
3. 이제 https://ysoftman.github.io/ 접속하면 index.html 내용이 보인다.

[github page 자동 페이지 생성]
ysoftman.github.io 저장소 -> settings -> github pages -> overwrite site -> launch automatic page generator
실행하면 다양한 기능(header,footer,theme...)을 손쉽게 설정할 수 있다.
내용은 markdown 형식으로 작성하고 publish page 하면 저장소에 images, css, html 등이 자동 생성(수정)되는것을 알수 있다.

[jekyll 사용하기]
지킬박사와 하아드에서 '지킬'을 뜻함~ㅋ
지킬은 ruby 오픈소스로 디렉토리 전체를 웹페이지로 변경해주는 툴이다.
사실 github pages 뒷단에서는 지킬 이 돌고 있다고 한다.

# jekyll 설치
gem install jekyll

# 기타 설치
gem install bundler
gem install minima

# 디렉토리 내용을 자동 생성
cd test
jekyll build

자동생성후 test/에서 jekylly serve 하면 http://localhost:4000 으로 서비스할 수 있다.
또는 자동생성된 파일들을 github page 로 올려 사용해도 된다.

참고
https://jekyllrb-ko.github.io/