TinyPilot: Month 44

Michael Lynch

TinyPilot: 44개월 차

원문은 Michael Lynch님이 에 게재했습니다. 이 블로그 구독하기

한 줄 요약

릴리스의 크리티컬 패스에서 나를 제외하기

하이라이트

  • 내가 직접 어떤 릴리스 작업도 수행하지 않은 최초의 TinyPilot 릴리스를 완료했다.
  • 위임을 통해 릴리스를 진행하면서 릴리스 프로세스에 문서화되지 않았거나 제대로 설계되지 않은 단계가 많다는 것을 파악할 수 있었다.
  • Zig로 바이트코드 인터프리터를 만드는 작업을 계속 즐기고 있다.

목표 평가

매달 초에 달성하고 싶은 목표를 정한다. 목표별 달성 결과는 다음과 같다:

TinyPilot Pro 2.6.3 출시

  • 결과: 릴리스를 출시했다.
  • 평점: A

우연히 나에게만 집중되어 있던 릴리스 단계를 드러내려고 했기 때문에, 이번은 내가 직접 어떤 릴리스 단계도 수행하지 않은 첫 번째 릴리스였다. 팀은 변경 로그와 릴리스 공지 작성 등을 포함해 공유된 문서를 기반으로 모든 단계를 수행했다.

TinyPilot Pro 릴리스 프로세스 내부 문서화

  • 결과: 릴리스를 커버할 만큼은 문서화했지만, 아직 개선할 부분이 남아 있다.
  • 평점: B+

릴리스 프로세스를 문서화하는 것은 아주 좋은 연습이었다. 문서화되지 않은 프로세스뿐만 아니라 프로세스의 약점도 드러났다.

릴리스 프로세스 중 비판적으로 검토하지 않았던 부분이 많았다. 직접 문서화하려고 앉아 보니, 불필요하게 노동 집약적이거나 오류가 발생하기 쉽거나 바퀴를 재발명하는 단계가 여러 개 있었다.

2023년 세금 신고

  • 결과: 대부분의 서류는 모았지만 아직 신고하지는 않았다.
  • 평점: B

결국 TinyPilot 릴리스에 신경이 분산되어 아직 신고하지 못했다. 그래도 올해 안에는 신고하면 정부가 고마워할 것 같으니, 아마 해야 할 것이다.

TinyPilot 통계

지표2024년 1월2024년 2월변동
순 방문자7,80013,000+5,200 (+67%)
판매 수익$100,008.98$82,517.42-$17,491.56 (-17%)
엔터프라이즈 구독$290.70$290.700
로열티$3,313.11$3,373.65+$60.54 (+2%)
총수익$103,612.79$86,181.77-$17,431.02 (-17%)
이익$79,764.14$24,199.09-$55,565.05 (-70%)

연간 회고가 주목을 받으면서 방문자가 크게 늘었지만, TinyPilot 판매에는 크게 영향을 미치지 않은 것 같다. 판매가 17% 감소했는데, 이는 주로 1월이 이례적으로 실적이 좋았기 때문이다. 월 $75-95k 정도가 우리의 일반적인 판매 범위다.

외주 제조업체로 전환하면서 현금 기준 이익 수치가 한 달 단위에서는 사실상 무의미해졌기 때문에, 월간 이익을 보고하는 새로운 방식이 필요하다. 매달 이익은 3~4개월마다 지불하는 제조 비용 청구서 시점에 크게 좌우된다.

그럼에도 3개월 이동 평균 이익은 내가 보기에 적당하다고 생각하는 $10-20k 범위로 다시 돌아왔다.

알고 보니 우리 릴리스 과정은 25단계였다

원래 TinyPilot 소프트웨어 릴리스는 전적으로 내 담당이었다. 제품이 성숙해지고 프로세스에 단계가 추가되면서 릴리스는 10~20시간짜리 작업이 되었다.

시작한 지 약 18개월쯤 되었을 때, 가장 어려운 릴리스 작업들을 팀원들에게 위임했다. 여기에는 대부분의 수동 테스트가 포함됐다. 덕분에 릴리스당 내 작업 시간은 3~5시간으로 줄었고, 위임을 잘했다고 느꼈다.

지난 TinyPilot 릴리스에서는 모든 것을 위임하는 데 도전했다. 내가 없을 때에도 릴리스가 진행될 수 있도록 하고 싶었다.

내가 여전히 맡고 있던 작업들에 대한 지침을 작성하기 시작했는데, 몇 단계 정도만 문서화하면 될 줄 알았다.

매 릴리스마다 내가 여전히 하고 있던 일을 모두 나열해 보니, 매 릴리스마다 25개의 개별 작업이 있다는 것을 깨달았다:

릴리스 후보 테스트

  1. 릴리스 후보 빌드 생성
  2. 변경 로그 초안 작성
  3. 보안 권고 초안 작성(해당되는 경우)
  4. 릴리스 공지 초안 작성
  5. 기능 변경 사항을 반영하도록 테스트 계획 업데이트
  6. Voyager 기기에서 릴리스 후보 테스트
  7. 출시된 빌드에서 릴리스 후보로 업데이트 테스트
  8. DIY 기기에서 릴리스 후보 테스트
  9. 물리적 기기를 대상으로 자동화된 종단 간 테스트 실행
  10. 테스트 결과 검토
  11. 릴리스 게시 여부 결정

릴리스 게시

  1. 보안 권고 게시(해당되는 경우)
  2. 변경 로그 게시
  3. TinyPilot Pro 프로덕션 릴리스 게시
  4. 최신 버전으로의 업데이트가 정상적으로 동작하는지 확인
  5. TinyPilot 팀에 릴리스 공지
  6. 변경 로그에 이미지 해시 추가
  7. 최소 48시간 동안 버그 리포트 모니터링

릴리스 알리기

  1. TinyPilot Community 릴리스 게시
  2. 릴리스 공지 블로그 게시물 게시
  3. EU 유통사에 릴리스 공유
  4. 제조업체에 릴리스 공유
  5. 내부 플레이북의 링크 업데이트
  6. 공개 메일링 리스트에 릴리스 공지 발송
  7. TinyPilot 트위터에 블로그 게시물 공유

나는 수동 테스트가 필요한 세 가지 작업만 문서화하고 위임한 상태였다. 하지만 나머지 22개는 여전히 내가 하고 있었다.

목록을 보면 릴리스 하나에 25단계라니 많아 보인다. 그리고 실제로는 특정 작업 안에 수십 개의 하위 단계가 있기 때문에 25단계보다 훨씬 많다.

수동 단계가 이렇게 많으면 더 자동화하는 것이 답처럼 느껴지지만, 딱히 자동화할 만한 대상이 보이지 않는다. 변경 로그에 이미지 해시를 추가하거나 내부 플레이북의 링크를 업데이트하는 단계 같은 것을 자동화할 수는 있지만, 연간 수동 작업 2시간을 아끼자고 자동화 작업에 10시간을 들여야 할 것이다.

내게 더 중요한 교훈은 릴리스에 작업을 추가할 때 신중해야 하며, 현재 있는 작업들의 필요성을 따져봐야 한다는 것이다.

출시 전 버그는 어떻게 잡을까?

릴리스 작업을 위임하는 것은 일반적인 위임보다 더 어려웠는데, 내가 어떻게 결정을 내리는지 설명할 수 있다 하더라도 팀원들에게 그 결정을 내릴 맥락이 부족하다는 것을 깨달았기 때문이다.

예로 최종 테스트 중에 마주친 버그를 하나 공유하겠다.

보통 기기를 네트워크에 연결하면 라우터가 할당하는 로컬 IP 주소를 그대로 사용한다. 일부 TinyPilot 사용자는 기기가 고정된 예측 가능한 IP 주소를 요청하기를 원한다. 이번 릴리스에서는 TinyPilot 웹 인터페이스에서 고정 IP 주소를 할당하는 기능을 추가했다.

출시 전 테스트에서 이 기능은 이렇게 보였다:

TinyPilot의 새로운 고정 IP 기능에 대한 출시 전 테스트 녹화

고객 서비스 팀이 테스트를 실행했고 아무 문제가 없다고 보고했다. 테스트 계획에서 예상한 대로 페이지가 새 IP 주소에서 로드됐다. 지원 엔지니어링 팀이 테스트 영상을 검토했고 기능이 올바르게 동작한다고 보고했다.

내가 영상을 검토했을 때 심각한 문제를 발견했다. 웹 인터페이스가 새 주소에서 로드되기 전 몇 순간 동안 사용자에게 이런 무서운 오류 화면이 나타났다:

개발팀은 사용자가 이 오류 메시지를 잠깐이라도 마주하는 것을 원하지 않았다

개발팀에 이를 보여주자 팀원들은 크게 낙심했다.

우리는 사용자를 동적 IP에서 고정 IP로 안내하는 UI에 수주간의 개발 시간을 투자했었다. DNS 캐싱, 로컬 TLS 인증서, 교차 도메인 요청에 대한 브라우저 보안 보호 등 복잡한 문제 때문에 특히 어려운 작업이었다. 많은 테스트와 오케스트레이션 코드를 거친 끝에 개발팀은 마침내 제대로 됐다고 생각했지만, TinyPilot 사무실에서는 원활하게 동작하지 않았던 것이다.

그렇다면 내가 과정을 일일이 관리하지 않고도 이런 버그를 어떻게 잡을 수 있을까? 서로 다른 팀이 기능이 어떻게 동작하기를 기대하는지에 대한 간극은 어떻게 피할 수 있을까?

우리는 개발팀이 새로운 기능을 출시하거나 기존 동작을 변경할 때, 출시 전 테스트 영상을 검토해 기대한 대로 동작하는지 확인하도록 프로세스를 조정하기로 했다.

어떤 버그를 수정할지는 어떻게 결정할까?

릴리스 프로세스 위임에서 다음 과제는 출시 전 테스트 중에 발견한 버그를 릴리스 매니저가 어떻게 처리해야 하는지를 정하는 것이었다. 릴리스를 연기해야 할까? 아니면 버그를 그대로 둔 채 릴리스를 출시해야 할까?

릴리스가 나에게 집중되어 있을 때는 출시할지 수정할지에 대한 결정이 더 쉬웠다. 팀 간 맥락을 모두 알고 있었기 때문이다. 개발팀과 계속 소통하고 있어 버그를 수정하는 데 얼마나 걸리는지, 그 과정에서 다른 것을 망가뜨릴 위험이 얼마나 되는지를 알고 있었다. 또한 프로덕트 오너로서 버그가 고객에게 얼마나 영향을 미칠지도 이해하고 있었다. 버그 수정 비용에 비해 기능이 충분히 중요하다면 릴리스를 연기해 버그를 수정했다.

릴리스 매니저가 내가 아니라면 버그 수정을 위해 릴리스를 언제 연기해야 할지 어떻게 결정할 수 있을까?

우리의 새로운 전략은 릴리스 매니저가 결정을 내리지 않고, 다른 팀으로부터 모든 정보를 모아 프로덕트 오너가 결정하도록 하는 것이다. 이렇게 하면 결정에 필요한 정보를 모으는 과정과 결정 자체를 분리할 수 있다. 이는 나만 할 수 있는 릴리스 작업을 최소화하려는 우리의 목표에 부합한다.

사이드 프로젝트

세상에서 가장 빠른 (미완성) 이더리움 구현을 만들었다

지난달에 언급했듯이 Zig와 인터프리터, 이더리움에 대해 더 배우는 재미있는 방법을 찾았다 — Zig로 이더리움 바이트코드 인터프리터를 만들고 있다.

Zig는 개발자에게 성능에 대한 높은 수준의 제어권을 주기 때문에, 인터프리터 작업 초기에 한 일 중 하나는 내 구현과 공식 Go 구현을 비교하기 위해 지속적 통합에 벤치마크를 설정하는 것이었다.

한동안 내 Zig 버전은 Go 버전보다 성능이 약간 뒤처졌다. 그러다 벤치마킹 스크립트를 리팩터링했더니 성능이 알 수 없이 급락했다.

공식 Go 구현이 내 Zig 구현을 압도하고 있었다(수치가 낮을수록 좋다)

Ziggit이라는 Zig 포럼에 도움을 요청했고, 알고 보니 벤치마킹 스크립트와 Zig 코드 모두에 버그가 있었다. 그 간단한 버그 두 개를 고치자 내 Zig 버전은 Go 버전을 단숨에 앞질렀다.

내 Zig 이더리움 구현은 이제 공식 Go 구현보다 30~40% 더 빠르다.

간단한 버그 몇 개를 고친 뒤, 내 Zig 이더리움 구현이 공식 구현보다 30~40% 더 빠르다(수치가 낮을수록 좋다)

공정하게 말하자면 내 버전은 이더리움의 약 3%만 구현했으니 불공정한 이점이 있는 셈이지만, 여전히 재미있는 프로젝트다.

마무리

무엇을 해냈나?

  • TinyPilot Pro 2.6.3을 출시했다.
  • TinyPilot 릴리스 프로세스에서 문서화되지 않은 단계들을 파악하고 대부분을 문서화했다.

배운 점

  • 작업에 팀 간 협업이 필요할 때 작업 위임은 더 어려워진다.
    • 일부 결정은 궁극적으로 프로덕트 오너가 내려야 하지만, 팀은 결정에 필요한 관련 정보를 모으는 과정과 결정을 내리는 과정을 분리하도록 프로세스를 조정할 수 있다.

다음 달 목표

  • TinyPilot 릴리스 문서의 빈틈을 메운다.
  • 2023년 세금 신고를 완료한다.

이 글은 muse-spark-1.2-contributor 모델을 사용해 번역했습니다.

댓글