포스트

[Automation] 피그마 플러그인과 n8n을 활용한 디자인 시스템 배포 자동화

[Automation] 피그마 플러그인과 n8n을 활용한 디자인 시스템 배포 자동화

최근 사이드 프로젝트 ‘풀’을 진행하면서 피그마 플러그인과 n8n을 활용해 디자인 시스템 배포를 자동화한 경험을 공유합니다. 장기 프로젝트인 만큼 개발 생산성을 고려해 디자인 시스템을 적극 활용하기로 했습니다. 하지만 디자이너 1명이 본업과 병행하며 디자인 시스템 구축과 화면 디자인을 모두 맡기에 버거워하는 상황이었습니다. 개발자로서 도울 수 있는 방법은 없을까? 생각했고, 디자인 토큰 변경 시마다 반복되는 수작업을 자동화하면 어떨까 생각했습니다.

🤔 문제 상황

디자인 토큰(컬러, 폰트 등)에 변경사항이 생길 때마다 다음과 같은 과정이 반복되었습니다.

기존 워크플로우:

  1. 디자이너가 피그마에서 디자인 토큰 변경
  2. 디스코드로 개발자들에게 수동 알림
  3. 개발자들이 피그마에 접속해 변경사항 확인
  4. 해당 부분 코드 수동 수정
  5. 반복…

문제점:

  • 약 10분씩 소요되는 반복 작업
  • 수작업으로 인한 휴먼 에러 가능성 (누락, 오타 등)
  • 디자이너의 추가 부담 (알림 업무)
  • 개발자의 집중력 분산

특히 컬러 값을 손으로 수정하다 보면 가끔 잘못 입력하는 경우가 있었고, 나중에 앱을 사용하다가 “폰트가 조금 이상한데?” 싶어서 확인해보면 휴먼 에러인 경우가 있었습니다.

🎯 목표 및 기술 스택 선택

자동화 목표

  • 디자인 토큰 변경 시 자동으로 iOS 코드 생성 및 PR 생성
  • 사람의 개입은 최소화 (검토만 필요)
  • 팀원들도 쉽게 유지보수 가능한 구조

기술 스택 선택

사용한 기술 스택으로는 피그마 플러그인과 평소 사용해보고 싶던 n8n을 선택했습니다. n8n은 GUI를 통한 노드 기반 워크플로우 툴로 확장성과 유지보수성이 높아 추후 다른 사람이 유지보수할 때에도 편리합니다. 또한 n8n은 비용을 지불하고 Saas로 사용하는 방식도 있지만, 서버에 셀프 호스팅하여 사용하는 방식도 있어 AWS EC2 인스턴스 프리티어를 활용해 무료로 사용할 수 있었습니다.

🛠 구현: 전체 자동화 플로우

전체 아키텍처

전체 플로우는 다음과 같이 구성했습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[피그마 플러그인 실행]
         ↓
[Variables & Styles 추출]
         ↓
[JSON 파싱 및 변환]
         ↓
[AWS EC2 (n8n) 웹훅 전송]
         ↓
[n8n 워크플로우 처리]
    ├─ XCAssets 생성
    ├─ Swift Enum 코드 생성
    └─ GitHub API로 PR 생성
         ↓
[디스코드 알림 전송]
         ↓
[CodeRabbit AI 리뷰]
         ↓
[사람의 검토 + CI 빌드 확인]
         ↓
[PR 머지]

1. 피그마 플러그인

역할: Variables(컬러 라이트/다크 모드)와 Styles(폰트) 데이터 추출

플러그인을 실행하면 현재 피그마 파일의 Variables와 Styles 목록을 불러와 JSON으로 파싱한 뒤, n8n 웹훅으로 전송합니다.

2. n8n 워크플로우 (39개 노드)

n8n 워크플로우는 총 39개의 노드로 구성되어 있지만, 핵심은 다음 3개입니다.

2-1. XCAssets 변환 노드 (JS 함수)

역할: JSON → .colorset 형식의 XCAssets 변환

라이트/다크 모드 컬러를 각각 처리하고, HEX를 RGB로 변환하며, 카테고리별 디렉토리 구조(Primary/500.colorset 등)를 생성합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// HEX → RGB 변환 함수
function hexToRGB(hex, alpha) {
  const cleanHex = hex.replace('#', '');
  return {
    red: `0x${cleanHex.substring(0, 2).toUpperCase()}`,
    green: `0x${cleanHex.substring(2, 4).toUpperCase()}`,
    blue: `0x${cleanHex.substring(4, 6).toUpperCase()}`,
    alpha: Number(alpha).toFixed(3)
  };
}

// XCAssets Contents.json 생성
const colorJson = {
  colors: [
    {
      idiom: "universal",
      color: {
        "color-space": "srgb",
        components: lightComponents
      }
    },
    {
      appearances: [{ appearance: "luminosity", value: "dark" }],
      idiom: "universal",
      color: {
        "color-space": "srgb",
        components: darkComponents
      }
    }
  ],
  info: { version: 1, author: "xcode" }
};

2-2. Git 업데이트 노드

역할: GitHub REST API를 통해 파일 생성/업데이트

이미 존재하는 파일에 대해서는 update 요청을, 없는 파일은 create 요청을 보내도록 구성했습니다. HTTP Request 노드를 활용해 GitHub API와 통신합니다.

2-3. Swift Enum 생성 노드 (JS 함수)

역할: 디자인 토큰 → Swift 코드 변환

PoolColor enum을 생성하고, 카테고리별 중첩 enum을 만들어 타입 세이프하고 간편하게 컬러를 사용할 수 있도록 합니다.

출력 예시:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public enum PoolColor {
  public enum ColorFamily: String, CaseIterable {
    case grays
    case backgrounds
  }

  public enum Grays {
    public static let gray = Color(PoolColor.ColorFamily.grays, name: "gray")
    public static let gray2 = Color(PoolColor.ColorFamily.grays, name: "gray2")
    public static let gray3 = Color(PoolColor.ColorFamily.grays, name: "gray3")
  }

  public enum Backgrounds {
    public static let tertiary = Color(PoolColor.ColorFamily.backgrounds, name: "tertiary")
    public static let secondary = Color(PoolColor.ColorFamily.backgrounds, name: "secondary")
    public static let primary = Color(PoolColor.ColorFamily.backgrounds, name: "primary")
  }
}

public extension Color {
  static let grays = PoolColor.Grays.self
  static let backgrounds = PoolColor.Backgrounds.self
}

// 사용 예시
// Color.backgrounds.secondary <- Color
// PoolColor.Backgrounds.secondary <- Color

3. PR 생성 및 검증

GitHub REST API를 통해 자동으로 PR을 생성하고, 다음과 같은 검증 단계를 거칩니다.

  1. 디스코드 알림: 서버 채널에 PR 링크 자동 전송
  2. CodeRabbit AI 요약: 변경사항 자동 요약으로 어느 부분이 바뀌었는지 빠르게 확인
  3. 검토 (사람이 직접): PR Files Changed에서 실제 변경사항 확인
  4. CI 빌드: GitHub Actions를 통해 빌드가 정상적으로 되는지 확인
  5. 머지: 모든 검증 완료 후 머지

이렇게 하여 자동화와 안정성을 모두 확보할 수 있습니다.

❌ 예상치 못한 문제와 해결

문제: CORS 에러

피그마 플러그인에서 n8n 서버로 웹훅을 전송했는데 전송되지 않는 문제가 발생했습니다. manifest.json 파일에서 networkAccess.allowedDomains에 도메인을 추가했지만 여전히 해결되지 않았습니다.

원인: 피그마 플러그인은 샌드박스한 iframe 환경에서 동작하는데, 보안상의 이유로 Origin 값이 ‘null’로 전송됩니다. 이는 다른 도메인에서의 요청을 기본적으로 막는 CORS 정책에 의해 발생하는 문제였습니다.

해결: nginx 를 프록시 서버로 활용해 특정 엔드포인트(/api/post-color)에 대해 다음과 같이 CORS 헤더를 설정해 정상적으로 n8n 서버로 전달할 수 있었습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
location /api/post-color {
    # Origin이 null일 때도 허용
    add_header 'Access-Control-Allow-Origin' "null" always;
    add_header 'Access-Control-Allow-Methods' 'POST, GET, OPTIONS' always;
    add_header 'Access-Control-Allow-Headers' 'Content-Type' always;

    # OPTIONS preflight 요청 처리
    if ($request_method = OPTIONS) {
        return 204;
    }

    # n8n 서버로 프록시
    proxy_pass http://localhost:5678/webhook/...;
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto https;
}

예상 외의 부가 작업들

처음 계획할 땐 피그마 플러그인과 n8n만 구축하면 끝일 줄 알았습니다. 하지만 실제로는 다음 작업들이 추가로 필요했습니다.. 모두 쉽지 않은 작업이었지만 좋은 경험이라고 생각합니다.

  • 도메인 구매
  • HTTPS 적용 (Let’s Encrypt)
  • nginx 설정
  • certbot 인증서 갱신 자동화

✨ 성과 및 결과

1. 휴먼 에러 제거 수작업으로 인한 누락이나 오타가 완전히 사라졌습니다. 이전에는 가끔 컬러 값을 잘못 입력해서 나중에 발견하는 경우가 있었는데, 이제는 그런 일이 발생하지 않습니다.

2. 디자이너 부담 경감 자동 알림 발송으로 인해 알림에 필요한 커뮤니케이션 비용이 감소했고, 신기하고 편하다는 긍정적인 피드백을 받았습니다. 최근 디자이너 두 분이 더 합류했는데, 도입 배경에 대한 ADR과 플러그인 가이드 문서를 제공해 쉽게 적응하고 사용중입니다.

3. 유지보수성 n8n의 노드 기반 구조 덕분에 수정이 매우 간편했습니다. 예를 들어, 처음에는 AI 노드를 사용해 코드를 생성했는데 응답의 일관성이 떨어지는 문제가 있었습니다. 이를 JS 함수 노드로 변경할 때 노드 연결만 바꿔주면 되어서 직관적이고 빠르게 수정할 수 있었습니다.

💡 배운 점과 인사이트

기술적 학습

자동화 도구 확장 GitHub Actions만 다뤄봤던 저에게 n8n은 새로운 경험이었습니다. GitHub 내부에 국한되지 않고 더 넓은 범위의 워크플로우를 자동화할 수 있다는 점을 배웠습니다.

피그마 생태계 이해 피그마 API와 플러그인 개발 경험을 쌓으면서, 디자인 도구와 개발 도구를 연결하는 방법을 이해하게 되었습니다.

인프라 운영 AWS EC2, nginx, HTTPS 구성 등 서버 운영의 전반적인 흐름을 경험했습니다. 특히 CORS 문제를 해결하면서 브라우저 환경에서의 애로사항을 겪어보고 배울 수 있었습니다.

🔮 향후 계획

현재는 iOS 버전으로만 자동화가 구성되어 있지만, Android 동료들에게도 도움을 주기 위해 Android 버전으로도 확장할 계획입니다. 그 다음 폰트/컬러 외 다른 디자인 토큰 또한 자동화하고, 컴포넌트 관련 불편함 또한 개선해보고 싶습니다.

최종적으로는 AI와 자동화를 활용해 프론트 개발의 생산성을 극대화하는게 목표입니다.

참고

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.