Docs Menu
Docs Home
/ /
Atlas App Services

튜토리얼: 트리거, 함수 및 값을 사용하여 서버리스 GitHub 기여 추적기 빌드

이 페이지의 내용

  • 전제 조건
  • 새 앱 만들기
  • 새 GitHub 기여자를 환영합니다.
  • 엔드포인트 만들기
  • 엔드포인트 함수의 인증 설정 업데이트
  • GitHub Webhook에 엔드포인트 연결
  • GitHub 액세스 토큰 받기
  • 토큰을 값으로 저장
  • GitHub API 클라이언트 설치
  • 엔드포인트 로직 작성
  • 엔드포인트 테스트
  • 주간 커뮤니티 보고서 생성
  • 보고서를 생성해야 하는 리포지토리 지정
  • 보고서를 생성하는 함수 만들기
  • 매주 보고서 생성 및 저장
  • 보고서 알림 보내기
  • 보고서 Atlas Triggers 테스트
  • 다음 단계
  • 계속 구축하기
  • 문서 탐색
  • 피드백 보내기
  • 커뮤니티 참여하기

예상 완료 시간: 30분

이 튜토리얼에서는 Atlas App Services를 사용하여 GitHub 리포지토리를 모니터링하고 기여도를 추적하는 서버리스 애플리케이션을 빌드합니다.

빌드하는 App Services App에는 다음과 같은 몇 가지 기능이 있습니다.

  • MongoDB Atlas 컬렉션에서 프로젝트에 기여한 사용자를 추적하세요.

  • 새로운 기여자가 pull 요청을 열거나 이슈를 제기할 때 환영하는 댓글을 남기세요.

  • 리포지토리에 대한 기여도를 요약하는 주간 보고서를 생성하여 보냅니다.

이 튜토리얼을 완료하면 다음 작업을 수행하는 방법을 알게 됩니다.

이 튜토리얼을 시작하려면 먼저 다음이 필요합니다.

  • Github 리포지토리 입니다. 빌드 한 앱은 이 리포지토리 에 대한 기여를 추적 합니다. 새 리포지토리 를 만들 수 있습니다. 또는 관리자 액세스 이 있는 기존 리포지토리를 사용하세요.

  • MongoDB Atlas cluster. 아직 클러스터 가 없는 경우, MongoDB Atlas 에 등록하고 무료로 클러스터를 생성하세요.

또한 이 튜토리얼에서는 배포 초안 워크플로를 사용하지 않습니다. 배포 초안은 단일 단위로 배포하거나 삭제할 수 있는 앱 변경 사항의 collection입니다. 배포 초안을 비활성화하지 않은 경우 변경 사항을 초안에 저장한 다음 수동으로 배포해야 할 수 있습니다.

먼저 App Services에서 애플리케이션을 만들어야 합니다.

앱을 만들려면 다음을 수행합니다.

  1. cloud.mongodb.com에서 Atlas 프로젝트를 엽니다.

  2. 상단 탐색에서 App Services 을 클릭합니다.

  3. Create a New App를 클릭합니다.

  4. 앱의 이름을 github-tracker-tutorial 으로 지정합니다.

  5. cluster를 선택하여 새 앱에 연결합니다.

  6. Create App Service를 클릭합니다.

Github 리포지토리 웹훅Github 을 사용하여 앱을 리포지토리에 연결합니다. . 웹훅은 리포지토리에서 새 커밋이나 pull 요청과 같은 이벤트가 발생할 때마다 앱에 이를 알립니다. 각 이벤트는 응답으로 무엇인가를 수행할 수 있는 서버리스 함수를 실행합니다.

이 튜토리얼에서는 Github REST API 사용합니다. 를 사용하여 리포지토리 에서 첫 번째 pull 요청 또는 이슈를 열 때마다 기여자에게 환영 메시지를 보냅니다.

웹훅은 앱이 제어하는 URL로 이벤트에 대한 요청을 전송하는 방식으로 작동합니다. 웹훅 요청을 수신하고 처리하려면 앱에서 고유한 URL이 있는 사용자 지정 엔드포인트를 노출해야 합니다.

엔드포인트를 생성하려면 다음을 수행합니다.

  1. 왼쪽 탐색 메뉴에서 HTTPS Endpoints을 클릭합니다.

  2. Add An Endpoint를 클릭합니다.

  3. 엔드포인트 경로의 이름을 /greetNewContributors 으로 지정합니다.

  4. Operation Type 아래에서 엔드포인트 콜백 URL을 복사합니다. 나중에 GitHub 웹훅을 설정하는 데 필요합니다.

  5. HTTP 메서드는 POST 로 설정된 상태로 둡니다.

  6. 권한 부여를 위해 Require a Secret 를 선택합니다.

  7. 새 시크릿 이름을 입력하고 Create 을 클릭하여 새 시크릿을 생성합니다. 그런 다음 시크릿 값으로 tutorial 을(를) 입력합니다. 이를 위해서는 들어오는 모든 요청이 요청 URL에 쿼리 매개변수 secret=tutorial 을(를) 포함해야 합니다.

  8. 엔드포인트에 대한 새 Realm 함수 을 만들고 이름을 endpoints/greetNewContributors 으로 지정합니다.

  9. 지금은 다른 작업을 수행하지 않고 수신 호출에만 응답하는 기본 핸들러를 설정합니다. 다음 코드를 함수 본문에 복사합니다.

    exports = async function greetNewContributors(request, response) {
    return response
    .setStatusCode(200)
    .setBody("Successfully received a GitHub webhook event")
    }
  10. Save 을 클릭하고 엔드포인트를 배포합니다.

이제 앱에서 엔드포인트를 만들었으므로 GitHub 웹훅이 수락되도록 엔드포인트의 함수에 대한 인증 설정을 변경해야 합니다.

함수의 인증 설정을 업데이트하려면 다음을 수행합니다.

  1. 왼쪽 탐색 메뉴에서 Functions을 클릭합니다.

  2. 엔드포인트 함수를 찾아 선택합니다.

  3. Settings를 클릭합니다.

  4. Authentication 에서 인증 방법을 System 로 변경합니다.

  5. 함수를 배포하려면 Save 을 클릭합니다.

엔드포인트 기능을 사용할 준비가 되면 GitHub 리포지토리에서 엔드포인트로 이벤트를 전송하는 웹훅을 설정해야 합니다.

리포지토리에 웹훅을 만들려면 다음과 같이 하세요:

  1. 리포지토리 설정을 열고 왼쪽 탐색 메뉴에서 Webhooks 을(를) 선택합니다.

  2. Payload URL 웹훅 추가 그리고 를 방금 생성한 엔드포인트의 URL secret 로 설정하다 하고 쿼리 매개변수를 시크릿 값으로 설정하다 합니다(예: ?secret=tutorial. 페이로드 URL 은 다음과 유사하게 표시되며, 앱의 배포서버 모델 에 따라 일부 차이점이 있습니다. URL 끝에 ?secret=tutorial 가 추가되었습니다.

    https://us-west-2.aws.data.mongodb-api.com/app/<App ID>/endpoint/greetNewContributors?secret=tutorial
  3. 웹훅 콘텐츠 유형을 application/json 으로 설정합니다.

  4. Secret 은 비워 둡니다. 여기에 입력된 모든 값은 HTTPS 엔드포인트에서 무시되므로 이전 단계에서 페이로드 URL 에 시크릿을 쿼리 매개변수로 추가합니다.

  5. 개별 이벤트를 선택하도록 선택하고 IssuesPull requests 에 대한 이벤트만 전송하도록 웹훅을 구성합니다.

  6. Add webhook 을 클릭하여 새 웹훅을 저장합니다.

웹훅이 엔드포인트를 성공적으로 호출하는지 확인하려면 App Services 의 애플리케이션 로그 에서 Endpoint 유형의 항목이 있는지 확인합니다. 왼쪽 탐색 메뉴에서 Logs 을 클릭하면 해당 페이지로 이동할 수 있습니다.

웹훅의 요청 로그 를 확인할 수도 Github Recent Deliveries 있습니다. 웹훅 설정 페이지의 아래에 있는 에서 성공한 각 요청 옆에는 녹색 확인 표시가 있습니다.

핑 이벤트에 대한 사용자 지정 엔드포인트의 응답을 보여주는 GitHub의 로그 항목입니다. 응답의 상태 코드는 200이며 응답 본문에는 "GitHub webhook 이벤트를 성공적으로 수신했습니다"라고 표시됩니다.

이제 웹훅이 GitHub에서 엔드포인트로 이벤트를 전송하도록 설정되었습니다. 하지만 GitHub API로 엔드포인트의 이벤트에 응답하려면 액세스 토큰이 필요합니다. 이 튜토리얼에서는 개인 액세스 토큰을 사용하지만, GitHub 앱을 설정하여 해당 토큰을 대신 사용할 수도 있습니다.

개인 액세스 토큰을 생성하려면 다음을 수행합니다.

  1. GitHub 사용자 설정(리포지토리 설정이 아님)을 열고 왼쪽 탐색 메뉴에서 Developer settings 을 선택합니다.

  2. 왼쪽 탐색 메뉴에서 Personal access tokens 을(를) 선택한 다음 Generate new token 을(를) 클릭합니다.

  3. 설명이 포함된 이름과 합리적인 만료 시간을 사용하여 토큰을 구성합니다. 튜토리얼이므로 7일 후에 토큰을 만료하는 것이 좋습니다.

  4. repo 범위를 선택합니다.

  5. Generate token를 클릭합니다.

  6. 토큰을 다시 액세스할 수 있는 안전한 곳에 복사합니다. 이 점 이후에는 Github에서 토큰을 다시 표시하지 않습니다.

앱으로 돌아가서 방금 생성한 개인 액세스 토큰을 저장할 새 값을 추가합니다. 함수에 토큰을 하드코딩하지 않고도 엔드포인트에서 값을 참고할 수 있습니다.

값을 생성하려면 다음을 수행합니다.

  1. 왼쪽 탐색 메뉴에서 Values을 클릭합니다.

  2. Create New Value를 클릭합니다.

  3. 값의 이름을 GitHubAccessToken 으로 지정합니다.

  4. 유형을 Value 으로 설정된 상태로 둡니다.

  5. 개인 액세스 토큰을 값의 입력에 붙여넣습니다. 값은 유효한 JSON이어야 하므로 주위에 따옴표를 넣어야 합니다.

  6. Save를 클릭합니다.

엔드포인트는 Github 의 REST API 와 상호 작용 하여 댓글을 남깁니다. 내장 context.http 클라이언트 또는 외부 라이브러리를 사용하여 API 에 직접 HTTP 요청을 쓰기 (write) 하고 보낼 수 있습니다. 그러나 이 튜토리얼에서는 Github 이라는 의 공식 Node.js 라이브러리를 사용 API합니다. 를 래핑합니다. 설치가 완료되면 앱의 모든 함수에서 라이브러리를 가져올 수 있습니다.

앱에 옥토킷 라이브러리를 추가하려면 다음과 같이 하세요:

  1. 왼쪽 탐색 메뉴에서 Functions을 클릭합니다.

  2. 0}Dependencies 탭을 선택합니다.

  3. Add Dependency를 클릭합니다.

  4. 패키지 이름 입력: @octokit/request.

  5. Add를 클릭합니다.

  6. App Services에서 패키지를 설치할 때까지 기다립니다. 설치는 몇 초 안에 완료되지만 최대 1분 정도 걸릴 수 있습니다.

이제 액세스 토큰이 있고 옥토킷을 설치했으므로 이벤트를 수신할 때 실제로 어떤 작업을 수행하도록 엔드포인트 함수를 업데이트할 수 있습니다. 구체적으로, 함수는 다음을 수행해야 합니다.

  • 수신 웹훅 이벤트 구문 분석

  • MongoDB에 기여도 기록

  • GitHub API를 통해 댓글 추가

  • GitHub에 유용한 응답을 다시 보내기

함수를 업데이트하려면 다음을 수행합니다.

  1. 왼쪽 탐색 메뉴에서 Functions을 클릭합니다.

  2. endpoints/greetNewContributors 을(를) 클릭하여 엔드포인트 함수 편집기를 엽니다.

  3. 기본 함수를 다음 코드로 바꿉니다.

    functions/endpoints/greetNewContributors.js
    exports = async function greetNewContributors(request, response) {
    // Parse the webhook event from the incoming request.
    const event = JSON.parse(request.body.text());
    // Don't do anything unless this is a new issue or pull request
    if (event.action !== "opened") {
    return response.setStatusCode(200);
    }
    // Get data from the GitHub webhook event.
    // Based on the webhook configuration the event will be one of the following:
    // - issues: https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#issues
    // - pull_request: https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#pull_request
    const sender = event.sender;
    const repo = event.repository;
    const contribution = event.issue || event.pull_request;
    const contribution_url = event.issue
    ? event.issue.url
    : event.pull_request.issue_url;
    const issue_number = contribution.number;
    // Record this contribution in the user's contributor document.
    // If this user hasn't contributed to the repo before, create a document for them.
    const atlas = context.services.get("mongodb-atlas");
    const contributors = atlas.db("community").collection("contributors");
    const contributor = await contributors.findOneAndUpdate(
    // Look up the user by their GitHub login
    { login: sender.login },
    // Add this issue or pull request to their list of contributions
    {
    $push: {
    contributions: {
    date: new Date(),
    type: event.issue ? "issue" : "pull_request",
    url: contribution_url,
    },
    },
    },
    // If they haven't contributed before, add them to the database
    { upsert: true, returnNewDocument: true }
    );
    // Send a welcome message to first time contributors on their issue or pull request
    const isFirstTimeContributor = contributor.contributions.length === 1;
    if (isFirstTimeContributor) {
    const octokit = require("@octokit/request");
    await octokit.request(
    "POST /repos/{owner}/{repo}/issues/{issue_number}/comments",
    {
    headers: {
    authorization: `token ${context.values.get("GitHubAccessToken")}`,
    },
    owner: repo.owner.login,
    repo: repo.name,
    issue_number: issue_number,
    body: `Hi there ${sender.login} 👋 Thanks for your first contribution!`,
    }
    );
    }
    // Configure the HTTP response sent back to GitHub
    return response
    .setStatusCode(200)
    .setHeader("Content-Type", "application/json")
    .setBody(
    isFirstTimeContributor
    ? `This is ${sender.login}'s first contribution!`
    : `${sender.login} has contributed before.`
    );
    };
  4. Save 을 클릭하고 엔드포인트를 배포합니다.

이제 환영 메시지 엔드포인트가 완전히 설정되어야 합니다. 올바르게 작동하는지 테스트하려면 리포지토리에서 새 이슈 또는 pull 요청을 엽니다. 이 작업을 처음 수행할 때는 엔드포인트가 스레드에 새 댓글을 추가하지만 이후 시도에서는 환영 메시지를 추가하지 않습니다.

엔드포인트에서 추가한 GitHub의 환영 댓글의 예시입니다.

GitHub는 리포지토리 웹훅 요청을 기록하므로 GitHub에서 로그 항목을 확인하여 모든 것이 제대로 작동하는지 확인할 수도 있습니다. 각 요청 로그에는 엔드포인트의 응답 메시지가 포함되어 있습니다.

최초 기여자에 대한 사용자 지정 엔드포인트의 응답을 보여주는 GitHub의 로그 항목

테스트를 재설정하려면 community.contributions 에서 GitHub 사용자 이름이 포함된 문서를 삭제합니다. 이렇게 하면 앱이 이전에 기여한 내용을 '잊고' 다음번 기여에서 환영합니다.

앱이 GitHub에 연결되고, 기여에 대한 정보를 저장하고, 새로운 기여자를 환영합니다. 이제 이 기능을 확장하여 리포지토리에 대한 보고서를 자동으로 분석하고 생성하겠습니다.

앱에는 매주 어떤 리포지토리를 생성해야 하는지 알 수 있는 방법이 필요합니다. 이 튜토리얼에서는 목록을 Value.

객체 배열을 포함하는 GitHubProjects 이라는 새 값을 만듭니다. 각 객체는 GitHub 리포지토리의 ownerrepo 이름을 지정합니다. 리포지토리에 대한 항목을 포함해야 합니다.

values/projects.json
[
{ "owner": "<GitHub Username>", "repo": "<Repository Name>" }
]

보고서는 일정 기간 동안 리포지토리에 기여한 내용을 요약한 문서입니다. 함수를 사용하여 리포지토리에 대한 온디맨드 보고서를 생성하겠습니다.

generateCommunityReport 이라는 새 함수를 만들고 다음 코드를 추가합니다.

functions/generateCommunityReport.js
exports = async function generateCommunityReport({ owner, repo, startDate }) {
// Look up issues and pull requests that had activity
const octokit = require("@octokit/request");
const { data: issuesWithActivity } = await octokit.request(
"GET /repos/{owner}/{repo}/issues",
{
headers: {
authorization: `token ${context.values.get("GitHubAccessToken")}`,
},
owner: owner,
repo: repo,
since: startDate,
}
);
// Look up users that contributed to the repo
const atlas = context.services.get("mongodb-atlas");
const contributors = atlas.db("community").collection("contributors");
const allContributors = await contributors
.find({
contributions: {
$elemMatch: {
date: { $gt: new Date(startDate) },
owner: owner,
repo: repo,
},
},
})
.toArray();
// Keep track of users who made their first contribution
const newContributors = allContributors.filter((c) => {
new Date(c.contributions[0].date) > new Date(startDate);
});
// Return a report with the data
return {
owner,
repo,
startDate,
issuesWithActivity,
allContributors,
newContributors,
};
};

방금 생성한 함수는 온디맨드 방식으로 리포지토리에 대한 보고서를 생성합니다. 그러나 이 점에서 아무것도 함수를 호출하지 않으며 생성된 보고서는 어디에도 저장되지 않습니다. 실제로 사용하기 위해 매주 한 번 함수를 호출하고 생성된 보고서를 연결된 클러스터에 저장하는 예약된 Atlas Trigger를 생성하겠습니다.

트리거를 생성하려면 다음을 수행합니다.

  1. 왼쪽 탐색 메뉴에서 Triggers을 클릭합니다.

  2. Add a Trigger를 클릭합니다.

  3. trigger 유형으로 Scheduled 를 선택합니다.

  4. trigger 이름 지정 generateAndSaveCommunityReports

  5. Advanced 일정 유형 선택

  6. 다음 크론 일정을 입력하여 일주일에 한 번 월요일 오전 5시(UTC)에 실행합니다.

    0 5 * * 1
  7. 트리거에 대한 새 함수를 만들고 이름을 triggers/generateAndSaveCommunityReports 으로 지정합니다.

  8. Add Dependency 을 클릭하고 moment 을 설치합니다.

  9. 다음 코드를 함수 본문에 복사합니다.

    functions/triggers/generateAndSaveCommunityReports.js
    exports = async function generateAndSaveCommunityReports() {
    const projects = context.values.get("GitHubProjects");
    const lastMonday = getLastMonday(); // e.g. "2022-02-21T05:00:00.000Z"
    // Generate a report for every tracked repo
    const reportsForLastWeek = await Promise.all(
    // Call the `generateCommunityReport` function for each project
    projects.map(async (project) => {
    return context.functions.execute("generateCommunityReport", {
    owner: project.owner,
    repo: project.repo,
    startDate: lastMonday,
    });
    })
    );
    // Save the generated reports in Atlas
    const atlas = context.services.get("mongodb-atlas");
    const reports = atlas.db("community").collection("reports");
    return await reports.insertMany(reportsForLastWeek);
    };
    // Get an ISO string for last Monday at 5AM UTC
    function getLastMonday() {
    const moment = require("moment");
    return moment(new Date().setUTCHours(5, 0, 0, 0))
    .utc()
    .day(1 - 7)
    .toISOString();
    }
  10. Save를 클릭합니다.

  11. 이 튜토리얼의 앞부분에 나온 새 엔드포인트의 기능과 일치하도록 새 기능의 인증 설정을 업데이트하세요.

이제 앱이 매주 자동으로 보고서를 생성하고 저장합니다. 그러나 보고서를 보는 사람이 없다면 보고서는 그다지 유용하지 않습니다. 새 보고서를 수신하고 최종 사용자에게 보낼 수 있는 형식의 메시지를 생성하는 데이터베이스 트리거를 생성하겠습니다.

메시지를 설정하려면 다음을 수행합니다.

  1. 왼쪽 탐색 메뉴에서 Triggers을 클릭합니다.

  2. Add a Trigger를 클릭합니다.

  3. trigger 유형을 Database 로 설정된 상태로 둡니다.

  4. 트리거의 이름을 sendCommunityReport로 지정합니다.

  5. trigger를 community.reports collection에 추가하고 Insert 이벤트를 수신 대기합니다.

  6. 트리거 함수에 전달된 변경 이벤트에 각각의 새 보고서 문서를 포함하려면 Full Document를 활성화합니다.

  7. 트리거에 대한 새 함수를 만들고 이름을 triggers/sendCommunityReport 으로 지정합니다.

  8. 다음 코드를 함수 본문에 복사합니다.

    functions/triggers/sendCommunityReport.js
    exports = async function sendCommunityReport(changeEvent) {
    // Pull out the report document from the database change event
    const report = changeEvent.fullDocument;
    // Format values from the report to include in the message
    const projectName = `${report.owner}/${report.repo}`;
    const moment = require("moment");
    const formattedDate = moment(report.startDate).utc().format("MMMM Do, YYYY");
    const numIssuesWithActivity = report.issuesWithActivity.length;
    const numContributors = report.allContributors.length;
    const numNewContributors = report.newContributors.length;
    // Create a message string that describes the data in the report
    const message = [
    `# Community contributions to ${projectName} since ${formattedDate}`,
    `Last week, there was activity on ${numIssuesWithActivity} issues and pull requests.`,
    `We had ${numContributors} people contribute, including ${numNewContributors} first time contributors.`,
    ].join("\n");
    // For this tutorial we'll just log the message, but you could use a
    // service to send it as an email or push notification instead.
    console.log(message);
    };
  9. Save 을 클릭하고 trigger를 배포합니다.

앱이 매주 보고서를 자동으로 생성, 저장하고 전송하도록 설정되어 있습니다. 모든 것이 제대로 작동하는지 확인하려면 이 보고서 흐름을 수동으로 실행하면 됩니다.

예약된 트리거 triggers/generateAndSaveCommunityReports 에 대한 함수 편집기를 연 다음 Run 버튼을 클릭합니다. 이렇게 하면 GitHubProjects 값에 나열한 모든 리포지토리에 대한 온디맨드 보고서가 생성되고 저장됩니다.

확인하려면 다음을 수행합니다.

  1. 새 보고서 문서는 community.reports 을(를) 확인하세요.

  2. 앱의 데이터베이스 trigger 로그를 확인하여 각 보고서에 대해 형식이 지정된 메시지를 찾습니다.

축하합니다! 서버리스 GitHub 기여 추적기를 성공적으로 설정하고 이 튜토리얼을 완료했습니다.

계속 개발하고 싶다면 트래커에 몇 가지 새로운 기능을 추가해 볼 수 있습니다. 예를 들어 다음과 같은 작업을 수행할 수 있습니다.

  • issue_comment 와 같은더 많은 웹훅 이벤트 유형을 처리하다 하도록 엔드포인트를 업데이트합니다. 또는 pull_request_review.

  • GitHub API의 더 많은 정보를 포함하도록 주간 보고서를 업데이트합니다.

  • Twilio 와 같은 외부 서비스에 연결 또는 SendGrid 기록하는 대신 이메일 이나 SMS를 통해 실제로 보고서를 보낼 수 있습니다.

App Services에는 앱을 강화할 수 있는 많은 서비스가 포함되어 있습니다. 이러한 서비스와 사용 방법에 대해 자세히 알아보려면 나머지 설명서를 확인하세요.

우리는 항상 문서와 튜토리얼을 개선하기 위해 노력하고 있습니다. 이 튜토리얼과 관련하여 제안 사항이 있거나 문제가 있는 경우 이 페이지 하단의 Give Feedback 를 클릭하여 튜토리얼을 평가하고 댓글을 보내주세요.

공식 MongoDB Community 포럼 은 다른 개발자를 만나고 질문하고 답변하고 최신 Atlas App Services 기능 및 릴리스에 대한 최신 정보를 얻을 수 있는 좋은 장소입니다.

다음

Atlas Application Services란 무엇인가요?