μ§νμν©μ μκ°ννμ¬ μ¬λμΌλ‘ 보μ¬μ£Όλ νμ΄μ¬ λΌμ΄λΈλ¬λ¦¬ (νμ΄μ¬ 3.9μ΄μ)

μ€μΉ λ°©λ²
pip install slack-progress-bar-kjh
κ°μ
- μ¬λμΌλ‘ μμ
μ§ν μν©μ μκ°ννμ¬ λ³΄μ¬μ€ μ μμ
- μ¬λ 컀μ€ν
μ΄λͺ¨μ§λ₯Ό νμ©νμ¬ λ€μνκ² νν κ°λ₯ (무μμ΄λ κ°λ₯, λμ¬λ ꡴리λ λͺ¨μ΅, λͺ¨λμ± μλ λͺ¨μ΅ λ±...)
- μ΄λ€ μμ
μ΄ μ§ν μ€μΈμ§ ν¨κ» 보μ¬μ€ μ μμ
μ¬μ© λ°©λ²
- Slack Apps APIμ μ μνμ¬ 'Create New App'μ ν΄λ¦ν ν, μ§μμ λ°λΌ μ μ±μ μ²μλΆν° λ§λμΈμ.
- 'Features -> OAuth & Permissions'λ‘ μ΄λνμ¬ λ€μ μ€μ½νλ₯Ό 'Bot Token Scopes'μ μΆκ°νμΈμ:
chat:write
, channels:manage
, groups:write
, im:write
, mpim:write
.
- 'Settings -> Install App'λ‘ μ΄λνμ¬ 'Install to Workspace'λ₯Ό ν΄λ¦νμΈμ. κ·Έλ° λ€μ 'Allow'λ₯Ό ν΄λ¦νμΈμ.
- κ°μ νμ΄μ§μμ μμ±λ 'Bot User OAuth Token'μ 볡μ¬νμ¬
SlackProgressBarKjh
ν΄λμ€μ token
νλμ μ¬μ©νμΈμ.
- Slack μν¬μ€νμ΄μ€λ‘ μ΄λνμ¬ νμ IDλ₯Ό μ°ΎμΌμΈμ(νλ‘νμ ν΄λ¦ν λ€μ '[...] -> Copy Member ID'λ₯Ό ν΄λ¦νμ¬ μ°Ύμ μ μμ΅λλ€). μ΄λ₯Ό
SlackProgressBarKjh
ν΄λμ€μ user_id
νλμ μ¬μ©νμΈμ. (νμμ λ°λΌ μ±λIDλ μ¬μ© κ°λ₯)
- μμμ μ°Ύμ
token
κ³Ό user_id
λλ μ±λ IDλ₯Ό μ¬μ©νμ¬ μ§ν νμμ€μ μμ±νκ³ μ
λ°μ΄νΈνμΈμ.
- 컀μ€ν
μ΄λͺ¨μ§λ₯Ό μΆκ°νμΈμ. [κΈ°λ³Έ μ΄λͺ¨μ§ gif λ€μ΄λ‘λ]
- β» νμ 컀μ€ν
μ΄λͺ¨μ§ (μ΄λ¦μ κ°μμΌ ν¨)
- :walking_amongus: # κ±·κ³ μλ μ΄λͺ¨μ§
- :left_spot: # μ§λκ° κ³³
- :right_spot: # μμ§ μ κ° κ³³
- :dead_amongus: # μλ£ μ μ΄λͺ¨μ§
- :monster_amongus: # λͺ©ν μ§μ
import os
from slack_progress_bar_kjh import SlackProgressBarKjh
BOT_TOKEN = os.getenv('BOT_TOKEN')
os.getenv('SLACK_MEMBER_ID')
progress_bar = SlackProgressBarKjh(token=self.BOT_TOKEN, user_id=self.SLACK_MEMBER_ID, total=100)
for i in range(100):
try:
time.sleep(0.1)
progress_bar.update(i+1)
progress_bar.chat_update(f"{i}λ² μμ
μλ£")
progress_bar.get_progress()
except Exception:
progress_bar.error()
1.Dockerλ₯Ό νμ©νμ¬ μ ν¨μ€ λΉλ μν© μ€μκ° μΆμ
(μ€μ μμ
Dockerfileκ³Ό ꡬλΆνκΈ° μν΄ Jenkins ν΄λμ μμ±, μ ν¨μ€μμ Jenkinsfile pathλ₯Ό λ³κ²½ν΄μ£Όμ΄μΌ ν¨)
1-1.μ ν¨μ€ μ컀 λ
Έλμ Dockerλ‘ λΉλ μν©μ μΆμ νλ μλΉμ€λ₯Ό λ§λ¦
- Jenkins/Dockerfile μμ±
# Dockerfile
# Dockerfile
FROM python:3.9-slim
# Set working directory
WORKDIR /app
# Copy necessary files
COPY Jenkins/progress_tracker.py /app/
# Install dependencies
RUN pip install slack-progress-bar-kjh flask
# Expose port if needed
EXPOSE 5000
# Command to run the script
CMD ["python", "progress_tracker.py"]
- Jenkins/progress_tracker.py μμ±
import os
from flask import Flask, request
from slack_progress_bar_kjh import SlackProgressBarKjh
app = Flask(__name__)
BOT_TOKEN = os.getenv('BOT_TOKEN')
SLACK_MEMBER_ID = os.getenv('SLACK_MEMBER_ID')
progress_bar = SlackProgressBarKjh(token=BOT_TOKEN, user_id=SLACK_MEMBER_ID, total=100)
progress_state = {'progress': 0}
@app.route('/update-all', methods=['POST'])
def update_all():
data = request.json
progress = data.get('progress')
message = data.get('message')
update_progress(progress, message)
return "Progress all updated", 200
@app.route('/update-progress', methods=['POST'])
def update_progress_route():
data = request.json
progress = data.get('progress')
update_progress(progress=progress)
return "Only progress updated", 200
@app.route('/update-message', methods=['POST'])
def update_message():
data = request.json
message = data.get('message')
update_progress(message=message)
return "Only message updated", 200
@app.route('/add-progress', methods=['POST'])
def add_progress():
data = request.json
progress = data.get('progress')
add_progress_to_state(progress)
return "Add progress updated", 200
@app.route('/get-progress', methods=['GET'])
def get_progress():
return progress_state['progress']
def update_progress(progress=None, message=None):
if progress is not None:
progress_state['progress'] = progress
progress_bar.update(progress)
if message is not None:
progress_bar.chat_update(message)
def add_progress_to_state(progress=0):
progress_bar.add_progress(progress)
progress_state['progress'] = progress_bar.get_progress()
if __name__ == "__main__":
app.run(host='0.0.0.0', port=5000)
- Jenkins/Jenkinsfile μμ±
// Jenkinsfile
pipeline {
agent any
environment {
BOT_TOKEN = credentials('SLACK_BOT_TOKEN') // Slack Bot Token
SLACK_MEMBER_ID = credentials('SLACK_MEMBER_ID') // Slack ID
TRACKER_IMAGE = 'progress-tracker:latest' // λΉλν Docker μ ν¨μ€ νΈλ컀 μ΄λ―Έμ§ μ΄λ¦
}
stages {
stage('Jenkins Tracker - Build Docker Image') {
steps {
script {
// μ ν¨μ€ μ§ν μν© μΆμ 컨ν
μ΄λ μ΄λ―Έμ§ λΉλ
sh '''
sudo yum install -y python3 python3-pip
docker build -t ${TRACKER_IMAGE} -f Jenkins/Dockerfile .
'''
}
}
}
stage('Jenkins Tracker - Start Tracker') {
steps {
script {
// μ ν¨μ€ μ§ν μν© μΆμ 컨ν
μ΄λ μμ
sh '''
sudo docker run -d --name progress_tracker \
-e BOT_TOKEN=${BOT_TOKEN} \
-e SLACK_MEMBER_ID=${SLACK_MEMBER_ID} \
-p 5000:5000 ${TRACKER_IMAGE}
sleep 5
'''
}
}
}
stage('Build') {
steps {
script {
// μ΄κΈ°ν λ¨κ³ μ§νλ₯ μ
λ°μ΄νΈ
sh '''
curl -X POST -H "Content-Type: application/json" \
-d '{"progress": 10, "message": "μ¬λκ³Ό"}' \
http://localhost:5000/update
'''
// μ§νλ₯ μ
λ°μ΄νΈ
sh '''
curl -X POST -H "Content-Type: application/json" \
-d '{"progress": 20, "message": "μ ν¨μ€"}' \
http://localhost:5000/update
'''
// μ§νλ₯ μ
λ°μ΄νΈ
sh '''
curl -X POST -H "Content-Type: application/json" \
-d '{"progress": 30, "message": "μ°λμ"}' \
http://localhost:5000/update
'''
// μ§νλ₯ μ
λ°μ΄νΈ
sh '''
curl -X POST -H "Content-Type: application/json" \
-d '{"progress": 40, "message": "ν
μ€νΈνκ³ "}' \
http://localhost:5000/update
'''
// μ§νλ₯ μ
λ°μ΄νΈ
sh '''
curl -X POST -H "Content-Type: application/json" \
-d '{"progress": 50, "message": "μλ"}' \
http://localhost:5000/update
'''
// μ§νλ₯ μ
λ°μ΄νΈ
sh '''
curl -X POST -H "Content-Type: application/json" \
-d '{"progress": 60, "message": "μ€ μ
λλ€."}' \
http://localhost:5000/update
'''
// μ§νλ₯ μ
λ°μ΄νΈ
sh '''
curl -X POST -H "Content-Type: application/json" \
-d '{"progress": 70, "message": "μ"}' \
http://localhost:5000/update
'''
// μ§νλ₯ μ
λ°μ΄νΈ
sh '''
curl -X POST -H "Content-Type: application/json" \
-d '{"progress": 80, "message": "λλ κ²"}' \
http://localhost:5000/update
'''
// μ§νλ₯ μ
λ°μ΄νΈ
sh '''
curl -X POST -H "Content-Type: application/json" \
-d '{"progress": 90, "message": "κ°μμ."}' \
http://localhost:5000/update
'''
}
}
}
stage('Complete and Cleanup') {
steps {
script {
// Build μ±κ³΅ ν μ΅μ’
μ§νλ₯ μ
λ°μ΄νΈ
sh '''
curl -X POST -H "Content-Type: application/json" \
-d '{"progress": 100, "message": "ν
μ€νΈ λ!!!"}' \
http://localhost:5000/update
'''
}
}
post {
always {
// Docker 컨ν
μ΄λ μ’
λ£ λ° μ 리
sh '''
docker stop progress_tracker
docker rm progress_tracker
'''
}
}
}
}
}
2.docker build μ€μκ° μ§ν μν© μΆμ νκΈ°
(μ€μ μμ
Dockerfileκ³Ό ꡬλΆνκΈ° μν΄ Jenkins ν΄λμ μμ±, μ ν¨μ€μμ Jenkinsfile pathλ₯Ό λ³κ²½ν΄μ£Όμ΄μΌ ν¨)
2-1.μμ μλ 컨ν
μ΄λ μμ± νμ
2-2.sh "(docker build --progress=plain -t test:latest . 2>&1) | tee Jenkins/build.log"λ‘ bulid.logμ λ‘κ·Έλ₯Ό κΈ°λ‘νκ³ μ€μκ°μΌλ‘ κ°μν΄μ μμ 컨ν
μ΄λμκ² μλ €μ£Όλ μλΉμ€ μΆκ°
# docker-compose.yml
# Dockerfile.tracker
# Dockerfile.monitor