프로젝트

일반

사용자정보

Actions

새기능 #5837

완료됨

[구축] pms-slack-sync - PMS 이슈를 슬랙 리스트에 자동 동기화하는 모듈

이호영이(가) 약 한달 전에 추가함. 4일 전에 수정됨.

상태:
완료
우선순위:
보통
담당자:
시작시간:
2026/07/29
완료기한:
진척도:

0%

추정시간:
난이도:

설명

운영 문서

설치 / 재배포 / 로그 확인 / 문제 해결은 모두 위키를 참고한다.

https://wiki.iten.co.kr/50.%EC%9A%B4%EC%98%81:%EC%82%AC%EB%82%B4%EC%8B%9C%EC%8A%A4%ED%85%9C:pms-slack-sync

이 이슈는 개발 환경과 소스 기준만 기록한다.


개요

PMS(Redmine)에 이슈를 등록하거나 수정하면 슬랙 #cs요청-문자온개선-mjon 채널의 PMS 추적기 리스트가 자동으로 따라오는 모듈이다. PMS 등록 후 슬랙 리스트에 같은 내용을 손으로 한 번 더 입력하던 이중 작업을 없앤다.

방향은 PMS → 슬랙 단방향이며 PMS가 기준이다. 슬랙 리스트에서 고친 값은 다음 동기화 때 PMS 값으로 덮어써진다.


소스 기준

항목
저장소 http://vcs.iten.co.kr/in_project/pms-slack-sync
브랜치 master
기준 커밋 bb1d35a
총 커밋 61
서버 배포 위치 /home/docker/rm_9011_compose_2022_0603/pms-slack-sync

개발 / 실행 환경

항목 버전 · 값
언어 Python 3.12
베이스 이미지 python:3.12-slim
런타임 의존성 httpx 0.27.2 (이것 하나뿐)
테스트 도구 pytest 8.3.3, respx 0.21.1
저장소(DB) SQLite (파이썬 표준 라이브러리, ORM 미사용)
컨테이너 Docker Compose v1 (docker-compose, 하이픈)
실행 사용자 UID 10001 (비-root)
노출 포트 없음
배포 서버 192.168.0.176

웹 프레임워크를 넣지 않았다. 1단계는 폴링 전용이라 들어오는 요청을 받을 일이 없다.

기존 redmine 도커 스택에 컨테이너 하나를 추가한 형태이며, 같은 네트워크(backend_app)를 쓰기 때문에 PMS를 외부 주소가 아니라 http://redmine:80 으로 직접 호출한다.


연동 기준

Redmine REST API

항목
대상 프로젝트 문자온(11) + 하위 48, 33, 49, 44, 47
조회 주기 60초
조회 조건 updated_on >= 마지막 조회 시각, status_id=* (종료 이슈 포함)
필요 권한 관리자 (사용자 목록 조회에 필요)

Slack Lists API

2025년 9월 공개된 API를 사용한다.

항목
사용 메서드 slackLists.items.list / .info / .create / .update, users.lookupByEmail
대상 리스트 PMS 추적기 (F088BD47D1R)
필요 스코프 lists:read, lists:write, users:read, users:read.email
슬랙 플랜 Lists 기능은 유료 플랜에서만 동작

동기화 항목

동기화하는 필드

리스트 컬럼 PMS 항목 비고
업무 제목
상태 상태 이름이 같은 옵션으로 매칭
우선순위 우선순위 낮음=★ ~ 즉시=★★★★★
설명 이슈 링크
담당자 담당자 이메일로 슬랙 계정 매칭

동기화하지 않는 필드

수정자, 등록시간, 마지막 편집 시간은 슬랙이 자동으로 채우는 타입이라 API로 값을 넣을 수 없다. 동기화된 항목의 수정자는 봇으로 표시되고, 등록시간은 리스트에 행이 생긴 시각이 된다. PMS의 실제 값은 설명 링크로 확인한다.

상태 매핑

PMS 상태와 슬랙 옵션을 이름 그대로 맞췄다. 아래 4개는 사용 빈도가 낮아 의도적으로 슬랙 리스트에 만들지 않았다. 해당 상태의 이슈는 상태 칸이 빈 채로 동기화된다.

  • 일시 중단 / 거절 / 원격지원 진행 / 원격지원 완료

구조

app/
  config.py     환경변수 로딩·검증
  urls.py       이슈 URL 생성·파싱 (호스트 검증)
  redmine.py    Redmine REST 클라이언트
  slack.py      Slack Lists API 클라이언트 (재시도·레이트리밋)
  schema.py     리스트 컬럼 스키마 조회
  transform.py  이슈 → 셀 값 변환 (순수 함수)
  users.py      Redmine ↔ 슬랙 사용자 매칭
  mapping.py    이슈번호 ↔ 리스트 행 ID 저장소
  sync.py       생성/수정 판단, 실패 격리
  poller.py     주기 폴링, 워터마크 관리
  main.py       조립 및 기동

scripts/
  bootstrap.py    기존 리스트 항목을 이슈에 연결 (최초 1회 / 복구용)
  dump_schema.py  리스트 스키마 덤프 (조사용, 읽기 전용)

테스트

  • 단위·통합 테스트 198개 통과
  • 외부 호출은 respx로 대체해 네트워크 없이 실행된다. 자격증명 없이 python -m pytest 로 바로 돌릴 수 있다

현재 상태

  • 기존 리스트 항목 299건 매핑 연결 완료
  • DRY_RUN=true 로 기동해 검증 중 (이 상태에서는 슬랙에 아무것도 쓰지 않고 무엇을 쓸 예정인지만 로그로 남긴다)
  • 검증 후 DRY_RUN=false 로 전환 예정

남은 작업 (선택)

2단계 — 웹훅 도입. 현재는 폴링이라 최대 1분 지연이 있다. 실시간이 필요하면 Redmine에 redmine_webhook 플러그인을 설치하면 된다. 다만 현재 redmine 컨테이너는 plugins 디렉토리가 볼륨 마운트되어 있지 않아 이미지 재빌드 또는 볼륨 추가 + 마이그레이션이 필요하고, 운영 중단을 수반한다. 1분 지연이 문제되지 않으면 하지 않아도 된다.

Actions #1

이호영이(가) 5일 전에 변경

완료

Actions #2

이호영이(가) 4일 전에 변경

  • 상태을(를) 진행에서 완료(으)로 변경되었습니다.
Actions

내보내기 Atom PDF