토픽과 카테고리를 재배열하는 스크립트 프레임워크

대규모 Discourse 사이트의 재배치를 스크립트로 자동화하기 위해, 사이트 리더십 팀과 협력하여 YAML 설정 파일에서 구동되는 여러 Ruby 스크립틀릿을 패키징하는 간단한 프레임워크를 작성했습니다. 이를 통해 스테이징 사이트에서 백업을 복원하고, 스크립트를 실행한 후 피드백을 받아 YAML 몇 줄을 수정하고, 다시 백업을 복원하여 새 설정으로 스크립트를 실행하는 과정을 반복할 수 있습니다.

제 사이트에는 약 600줄에 달하는 설정이 있으며, 이를 UI를 통해 수동으로 조작하는 것은 불가능합니다. 한 번만 하더라도 벅찰 텐데, 올바르게 설정하기 위해 여러 번 반복하는 것은 더더욱 말도 안 되는 일입니다. 이전에는 대규모 변경을 제안했을 때 실제로 포기해야 했던 경험이 있기 때문에 잘 알고 있습니다. 반면, 이 스크립트를 사용하면 사이트가 약 50만 개의 게시물과 100개 이상의 카테고리를 가지고 있음에도 불구하고 반복마다 단 몇 분 만에 전체 사이클을 완료할 수 있습니다. 이를 통해 사이트 리더십 팀으로부터 빠른 피드백을 받을 수 있으며, 사이트를 빠르게 마이그레이션할 준비도 갖출 수 있습니다.

더 자세한 문서 코드가 포함된 저장소의 README 파일에 있습니다:

:warning: 이 스크립트는 오류 검사를 하지 않습니다. 라이브 사이트에서 실행하는 것은 매우 위험합니다. 이 스크립트는 스테이징 사이트에서 실행하여 결과를 검증한 후 라이브 환경에 적용하도록 설계되었습니다. 저 역시 이 방식으로 실행할 계획입니다. 라이브 사이트에서 직접 실행하다가 문제가 발생하면 모든 결과를 스스로 감당해야 합니다. :warning:

문서에 따르면, 설정 파일은 다음과 같은 형태를 가질 수 있습니다:

---
- describe:
    context: Old Name
    category: 7
    name: New Name
    description: New description of category
    slug: new-slug
- movePosts:
    context: move only faq posts from the Support category to the Documentation category
    source: 3 # Support category ID
    target: 6 # Documentation category ID
    withTag: faq
    hide: false # do not hide the Support category when done
- movePosts:
    context: consolidate How-To category into documentation with how-to tag
    source: 8 # How-To category ID
    target: 6 # Documentation category ID
    addTag: how-to
    hide: true # hide the old How-To category, visible only to Admin

실행 중 진행 상황 출력이 다음과 같이 표시될 수 있습니다.

==========
Move hidden categories out of the way so they don't clutter admin view
setHiddenCategory: {:category=>11}
==========
Rename Old Name to New Name
describe: {:category=>7, :name=>"New Name", :description=>"New description of category", :slug=>"new-slug"}
==========
move only faq posts from the Support category to the Documentation category
movePosts: {:source=>3, :withTag=>"faq", :target=>6}
==========

사용하려면 YAML 파일을 /var/discourse/shared/app/tmp/rearrange.yaml에 넣고 다음을 실행하십시오:

cd /var/discourse
./launcher enter app
git clone https://github.com/johnsonm/discourse-site-rearranger.git script/discourse-site-rearranger
ruby script/discourse-site-rearranger/rearrange.rb /shared/tmp/rearrange.yaml

그러나, 이 스크립트가 필요한 모든 작업을 완벽하게 수행하지는 않을 가능성이 있습니다. 이는 사실 스크립트 기반 사이트 수정의 더 많은 측면을 몇 줄의 코드로 자동화하는 새로운 작업을 쉽게 추가할 수 있게 해주는 프레임워크입니다. 몇 줄의 코드로 하나의 메서드를 정의하기만 하면, YAML 파일에서 이를 적절히 호출할 수 있습니다.

사이트의 조직을 개선하는 방법에 대해 고민해 보았지만 UI 사용에 주저하고 있거나, 스테이징 사이트에서 테스트한 내용을 라이브 환경에서 변경할 때 동일하게 재현할 수 있을지 신뢰할 수 있는지 고민하고 계신가요? 한 번 살펴보고 여러분의 생각을 들려주세요!

5개의 좋아요

이 스크립트는 메인 사이트의 클론으로 테스트 사이트를 생성하는 데 사용하고 있습니다. 높은 시각적 충실도는 목적의 일부이지만, 변경 사항을 검토하는 동안 실수로 잘못된 사이트에 게시물을 올리기 쉬울 수 있고, 그렇게 실수로 올린 게시물은 테스트 사이트를 새로고침할 때마다 사라져 버릴 수 있습니다.

처음에는 공개 피드백을 요청할 때 테스트 사이트를 읽기 전용으로 설정했습니다. 하지만 사이트가 읽기 전용 모드일 때 로그인이 비활성화되어 있어, 로그인해 달라고 요청했을 때 사용자가 로그인할 수 없었습니다.

그래서 사람들이 로그인해서 이리저리 둘러볼 수 있도록 하되, 실수로 잘못된 사이트에 게시물을 올리는 것을 방지하기 위해 publicCategoriesReadonly라는 새로운 액션을 추가했습니다. 이 액션은 익명 사용자에게도 표시되는 카테고리를 :admins만 작성할 수 있고, :everyone에게는 :readonly로 설정합니다. 이제 사이트 전체는 읽기 전용 모드가 아니지만, 공개 카테고리는 읽기 전용 상태입니다.

슬러그를 사용하여 카테고리를 해시태그로 참조할 수 있습니다. 이 스크립트는 카테고리 내용을 함께 이동하고 슬러그를 변경할 수 있도록 하며, 이렇게 하면 재베이크(rebake) 후 이전 게시물의 링크가 더 이상 작동하지 않게 됩니다. (재베이크 전에는 퍼malink 리다이렉트 덕분에 링크가 정상적으로 작동했습니다.)

현재 이 스크립트를 업데이트하여 마이그레이션 전후의 태그를 추적하고, 게시물 내 변경된 카테고리에 대한 참조를 다시 매핑하도록 했습니다.

Retort를 설치했던 분들을 위해, 지원되는 플러그인으로 전환할 수 있도록 프레임워크에 migrateRetortToReactions 액션을 추가했습니다.

2개의 좋아요

와! 정말 좋은 소식입니다. 누군가가 rake task로 만들어서 reactions 플러그인에 제출해 주면 좋겠네요.

조금 후에 확인해 보겠습니다.

1개의 좋아요

플러그인에서 rake task로 구현하는 건 꽤 좋은 아이디어인 것 같습니다.

저는 CDCK CLA에 서명했으므로, 결과물에 대한 제 저작권 관련 권리가 방해가 되지 않도록 했고, 플러그인 자체와 동일한 라이선스를 적용할 수 있습니다.

또한 제가 뭔가 잘못 이해했을 수도 있습니다. 만약 문제점을 발견하신다면 알려주시면 감사하겠습니다. 앞으로 몇 주 안에 제 사이트에서 해당 스크립트를 실행할 계획이 있기 때문입니다. :smiley:

더 큰 차원에서 말씀드리자면, 이 프레임워크가 Discourse 설치 지원 관련 작업에 유용하다고 생각하시되 더 많은 오류 처리가 필요하시다면, PR을 환영합니다. 저는 단순히 CLA에 서명하고, 해당 프레임워크의 유용한 부분이 공식 Discourse에 통합될 수 있다는 데 동의하는 사람으로부터만 PR을 받기를 원합니다. 그 부분은 귀하께서 이미 충족하고 계신 것으로 알고 있습니다…

2개의 좋아요

Retort 토픽에서 @angus가 UI 기반 변환을 지원하는 브랜치를 가지고 있다는 것을 알게 되었습니다. 이 부분은 제가 완전히 놓치고 있었습니다.

제 스크립트는 언젠가 변경될 수도 있는 내부 구조(internals)를 건드리고 있습니다. 이 스크립트로 변환 작업을 마친 후에는 해당 내부 구조가 변경되어도 저는 알지 못할 것입니다. 처음에는 "올바른 방법"으로 해보려 했지만, Reactions 플러그인이 이를 허용하는 인터페이스를 노출하지 않는다는 것을 발견했습니다. @angus는 더 장기적인 관점을 취하고 있습니다:

@pfaffman, rake 작업을 만들 계획이라면, 제가 사용한 “뒷문(back door)” 방식을 사용하지 않고 created_by와 silent 값을 전달할 수 있도록 인터페이스를 수정하는 내용도 함께 포함된 PR으로 만드는 것이 좋을 것입니다. 그렇게 되면 rake 작업은 커맨드라인 마이그레이션용으로 사용될 수 있을 뿐만 아니라, @angus가 UI 기반 마이그레이션을 수행할 수 있도록 하는 효과도 동시에 거둘 수 있습니다.