코드에서 Heroku에 대한 수동 재배포를 트리거하는 방법 - 문서화되지 않은 Gatsby 설정을 업데이트하는 킬러 기능

요약: Gatsby 서비스용 Heroku 빌드를 다시 트리거하여 Strapi CMS 데이터를 수집할 수 있습니다. **kolkrabbi.heroku.com이라는 Heroku의 문서화되지 않은 이상한 하위 도메인에서 POST 요청만 실행하면 됩니다. API 호출 세부 정보 및 Strapi CMS 예제 구현에 대해서는 아래를 참조하십시오.

그래서 프리랜서 업무 중 하나인 Conversation Starter로부터 요청을 받았습니다(저는 낮에는 Craftworkz에서 기술 책임자로, 밤에는 IT 프리랜서로 일하고 있습니다) 관리할 헤드리스 CMS 시스템을 설정하고 싶다는 요청을 받았습니다. 놀라운Gatsby 프레임워크로 구축된 기존 웹 사이트에 대한 블로그 게시물을 호스팅합니다.

Strapi을 CMS 시스템으로 즉시 사용하기로 결정했습니다. 주로 커뮤니티에서 좋은 평가를 받았고 사용할 수 있는 많은tutorials 때문이었습니다.

개발은 순조롭게 진행되었지만 배포 시간이 도래했습니다. Strapi와 Gatsby 웹사이트는 모두 Heroku dynos에서 원활하게 실행되지만 Gatsby(컨텐츠의 정적 호스팅) 특성으로 인해 CMS에 게시된 블로그 게시물 기사가 변경될 때마다 웹사이트를 다시 빌드해야 합니다.

Heroku에서 기존 배포를 간단히 다시 빌드하는 것이 간단하고 잘 문서화되어 있다고 생각할 수 있습니다. 맞습니까?

글쎄요.

오랜 검색 끝에 Strapi CMS에서 Gatsby 리포지토리로 빈 git 커밋을 푸시하여 새 빌드를 트리거하는 것을 고려하더라도 내 문제에 대한 해결책으로 안내할 탐색 경로를 찾았습니다. 바로 Heroku 자체의 수동 재배포 버튼입니다.



글쎄, 이건 좋지 않아! 제가 딱 필요로 했던 기능입니다. 그러나 이것은 공식 Heroku 문서 어디에도 문서화되어 있지 않습니다(찾을 수 있는 링크를 보내주십시오).

신뢰할 수 있는 Chrome 개발 도구를 사용하여 운 좋게도 API 호출을 직접 문서화할 수 있었고 또 운이 좋았습니다. 이상한 일을 많이 하지 않고도 복제하기가 매우 쉬웠습니다. 여기서 유일한 이상한 점은 kolkrabbi.heroku.com이라는 알려지지 않은 Heroku 하위 도메인을 호출해야 한다는 것입니다.

API 호출은 다음과 같습니다.

POST https://kolkrabbi.heroku.com/apps/<HEROKU_APP_ID>/github/push

Headers: {
    "Authorization": "Bearer <USER_AUTH_TOKEN>"
}

Body: {
    "branch": "master"
}


어디에:

  • HEROKU_APP_ID = heroku apps:info --json 명령을 사용하여 가져올 수 있는 앱의 UUID

  • USER_AUTH_TOKEN = 자신의 사용자 액세스 토큰. https://dashboard.heroku.com/account으로 이동하여 API 키 섹션
  • 으로 이동합니다.
  • 그런 다음 호출 본문 내에서 빌드할 분기를 선택할 수 있습니다.

  • 애플리케이션의 여러 인스턴스(예: 개발 및 프로덕션)가 있는 경우 다른 앱 ID를 갖게 됩니다.

    그리고 케이크의 체리로서 여기에도 제 Strapi 구성을 게시하겠습니다. 아이디어는 Article 모델 인스턴스가 생성, 업데이트 또는 삭제될 때마다 Heroku 빌드 기능이 트리거되어 Gatsby가 새로운 변경 사항을 수집할 수 있다는 것입니다.

    ./api/articles/models/article.js

    'use strict';
    
    const axios = require('axios');
    
    /**
     * Lifecycle callbacks for the `Article` model.
     */
    
    var deployUrl = `https://kolkrabbi.heroku.com/apps/${process.env.HEROKU_APP_ID}/github/push`
    
    var axiosConfig = {
        headers: {
            "Authorization": `Bearer ${process.env.CS_HEROKU_BUILD_TOKEN}`,
            "Content-Type": "application/json"
        }
    }
    
    async function callDeployEndpoint(deployUrl, branch) {
        await axios
            .post(deployUrl, {
                "branch": branch
            }, axiosConfig)
            .then((res) => {
                strapi.log.debug(`Executed build trigger for branch ${branch} `);
            })
            .catch((error) => {
                strapi.log.error(`Caught error for branch ${branch}: `, error);
            });
    }
    
    async function triggerDeploy() {
        strapi.log.debug('Triggered redeploy');
        strapi.log.debug('axiosConfig: ', axiosConfig);
        await callDeployEndpoint(deployUrl, "master");
    
    }
    
    module.exports = {
        lifecycles: {
            async afterCreate(data) {
                await triggerDeploy();
            },
            async afterUpdate(data) {
                await triggerDeploy();
            },
            async afterDestroy(data) {
                await triggerDeploy();
            },
        }
    };
    

    좋은 웹페이지 즐겨찾기