{"id":3322,"date":"2024-01-01T22:44:44","date_gmt":"2024-01-01T13:44:44","guid":{"rendered":"http:\/\/43.203.250.216\/?p=3322"},"modified":"2025-10-01T16:25:51","modified_gmt":"2025-10-01T07:25:51","slug":"github-release%ec%97%90-%eb%b0%94%ec%9d%b4%eb%84%88%eb%a6%ac-%ec%b2%a8%eb%b6%80-%ec%9e%90%eb%8f%99%ed%99%94","status":"publish","type":"post","link":"https:\/\/litcoder.com\/?p=3322","title":{"rendered":"GitHub release\uc5d0 \ubc14\uc774\ub108\ub9ac \ucca8\ubd80 \uc790\ub3d9\ud654"},"content":{"rendered":"\n<p>GitHub\uc5d0\uc11c release\ub97c \uc0dd\uc131\ud558\uba74 source code\uc758 snapshot\uc774 zip\uacfc tar.gz\ub85c \uc800\uc7a5\ub41c\ub2e4. \uc5ec\uae30\uc5d0 \ucd94\uac00\ud574\uc11c \ucef4\ud30c\uc77c\ub41c \uacb0\uacfc\uac00 \uc790\ub3d9\uc73c\ub85c \ucd94\uac00\ud558\ub3c4\ub85d \ud55c\ub2e4\uba74, \uac04\ub2e8\ud788 source code\uc640 \uc5f0\uacc4\ub41c \ubc14\uc774\ub108\ub9ac\ub3c4 \ud568\uaed8 \ubc30\ud3ec\ud560 \uc218 \uc788\uc744 \uac83\uc774\ub2e4.<\/p>\n\n\n\n<p>\uc774 \uae00\uc5d0\uc11c\ub294 \uc548\ub4dc\ub85c\uc774\ub4dc \ud504\ub85c\uc81d\ud2b8\ub97c \uac00\uc815\ud574\uc11c release\ub97c \uc0dd\uc131\ud560 \ub54c \uc548\ub4dc\ub85c\uc774\ub4dc APK\ub97c \ube4c\ub4dc\ud558\uace0 source code\uc640 \ud568\uaed8 \ubc30\ud3ec\ud558\ub294 \uac04\ub2e8\ud55c workflow\ub97c \uc124\uba85\ud55c\ub2e4.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\uc804\uccb4 \ucf54\ub4dc <\/h2>\n\n\n\n<script src=\"https:\/\/gist.github.com\/litcoder\/4c18ab4fc2b0134defae109199479bb7.js\">\n<\/script>\n\n\n\n<h2 class=\"wp-block-heading\">Event trigger<\/h2>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"yaml\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">on:\n  release:\n    types: [published]<\/pre>\n\n\n\n<p>Release\uc5d0\uc11c\ub9cc \ub3d9\uc791\ud558\ubbc0\ub85c event trigger\ub294 release &#8211; published\uc774\ub2e4. \uc774 event\ub294 web\uc0c1\uc5d0\uc11c \uc0c8\ub85c\uc6b4 release package\ub97c publish \ud560\ub54c trigger \ub41c\ub2e4.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\ud658\uacbd\ubcc0\uc218<\/h2>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"yaml\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">env:\n  TAG: ${{ github.ref_name }}\n  ASSET_FILE_PATH: \".\/prebuilt-${{ github.ref_name }}.zip\"<\/pre>\n\n\n\n<p>Release package\ub97c \uc0dd\uc131\ud560 \ub54c \ub123\ub294 version\uc758 \uc774\ub984\uc740 <strong>github.ref_name<\/strong>\uc73c\ub85c \ucc38\uc870 \ub41c\ub2e4. \ucca8\ubd80\ub418\ub294 \ud30c\uc77c\uc758 \uc774\ub984\uc740 prebuilt-&lt;version_tag>.zip\uc73c\ub85c \uc124\uc815\ud55c\ub2e4. \ucc38\uace0\ub85c GitHub\uc5d0\uc11c\ub294 release\uc5d0 \ucd94\uac00\ub418\ub294 \uc18c\uc2a4\ucf54\ub4dc\uc678\uc758 \ud30c\uc77c\ub4e4\uc744 &#8220;Asset&#8221;\uc774\ub77c \ubd80\ub978\ub2e4.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\ube4c\ub4dc \uc218\ud589 \ubc0f Asset \uc0dd\uc131<\/h2>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"yaml\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">    # Checkout source code and build Android APKs.\n    - name: Checkout\n      uses: actions\/checkout@v3\n    - name: Setup JDK 17\n      uses: actions\/setup-java@v3\n      with:\n        java-version: '17'\n        distribution: 'temurin'\n        cache: gradle\n    - name: Build Android APK and zip\n      run: |\n        sh .\/gradlew assemble\n        zip ${{ env.ASSET_FILE_PATH }} \\\n          .\/app\/build\/outputs\/apk\/debug\/app-debug.apk \\\n          .\/app\/build\/outputs\/apk\/release\/app-release*.apk<\/pre>\n\n\n\n<p>Android build\ub97c \uc704\ud55c JAVA\ub97c \uc124\uc815\ud558\uace0 Gradle\uc758 <strong>assemble<\/strong> target\uc744 \uc124\uc815\ud558\uc5ec APK file\uc5d0 \ub300\ud55c \ube4c\ub4dc\ub97c \uc218\ud589\ud55c\ub2e4. Assemble\uc740 debug\uc640 release\uc6a9 \ub450\uac1c\uc758 apk\ub97c \uc131\uc131\ud558\ubbc0\ub85c \uc774\ub4e4\uc744 \ud558\ub098\uc758 zip\ud30c\uc77c\ub85c \ub9cc\ub4e4\uc5b4\uc11c <strong>prebuilt-&lt;version_tag&gt;.zip<\/strong>\uc5d0 \ucd94\uac00\ud55c\ub2e4.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Release\uc5d0 Asset  \ucd94\uac00<\/h2>\n\n\n\n<p>Release\uc5d0 asset\uc744 \ucd94\uac00\ud574\uc8fc\ub294 GitHub action\uc740 \ubcf4\uc774\uc9c8 \uc54a\ub294\ub2e4. \uadf8\ub798\uc11c GitHub script\ub97c \uc774\uc6a9\ud574\uc11c release\uc5d0 asset\uc744 \ucd94\uac00\ud558\ub294 \ub3d9\uc791\uc744 \ub2e4\uc74c\uacfc \uac19\uc774 \uc815\uc758\ud588\ub2e4. \uc774\ub294 \ub450 \uac1c\uc758 \ub3d9\uc791\uc73c\ub85c \uc774\ub8e8\uc5b4\uc9c0\ub294\ub370 \ud558\ub098\ub294 \uc8fc\uc5b4\uc9c4 tag\ub85c release \uc815\ubcf4\ub97c \ucc3e\uc544\uc624\ub294 \uac83\uc774\uace0, \ub2e4\ub978 \ud558\ub098\ub294 \uac00\uc838\uc628 release \uc815\ubcf4\uc5d0 \ud30c\uc77c\uc744 \uc5c5\ub85c\ub4dc\ud558\ub294 \uac83\uc774\ub2e4.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\ub3d9\uc791 1. Tag\ub85c release \uac00\uc838\uc624\uae30<\/h3>\n\n\n\n<p>GitHub script project\uc758 <a href=\"https:\/\/github.com\/actions\/github-script\/blob\/main\/README.md\" data-type=\"link\" data-id=\"https:\/\/github.com\/actions\/github-script\/blob\/main\/README.md\">README.md<\/a>\uc5d0 \ub530\ub974\uba74 GitHub script\uc0c1\uc5d0\uc11c <strong>github<\/strong>\uac1d\uccb4\ub294 \uc0ac\uc804\uc778\uc99d\ub41c(pre-authenticated) Octokit client\ub77c\uace0 \ud55c\ub2e4. \ub530\ub77c\uc11c \uc0c8\ub86d\uac8c instance\ub97c \ub9cc\ub4e4\uc9c0 \uc54a\uace0 \ubc14\ub85c Octokit\uc758 API\ub97c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4. <a href=\"https:\/\/octokit.github.io\/rest.js\/v20\" data-type=\"link\" data-id=\"https:\/\/octokit.github.io\/rest.js\/v20\">getReleaseByTag()<\/a>\uc5d0 tag\ub97c \ub118\uaca8\uc8fc\uba74 \ud1b5\ud574 release\uc5d0 \ub300\ud55c \uac1d\uccb4\uac00 \ubc18\ud658\ub41c\ub2e4. \uadf8 \uc911\uc5d0 release\ub97c \uad6c\ubd84\ud558\uae30 \uc704\ud55c ID\ub9cc \uc0ac\uc6a9\ud55c\ub2e4.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"yaml\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">    \/\/ Get a release for given tag.\n    const release = await github.rest.repos.getReleaseByTag({\n       owner: context.repo.owner,\n       repo: context.repo.repo,\n       tag: process.env.TAG\n    });\n    const release_id = release.data.id;\n    console.log(\"Release id for the tag \" + process.env.TAG + \": \" + release_id);<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">\ub3d9\uc791 2. Release\uc5d0 \ud30c\uc77c \uc5c5\ub85c\ub4dc \ud558\uae30<\/h3>\n\n\n\n<p>\uc55e\uc758 \uacfc\uc815\uc5d0\uc11c \ub9cc\ub4e0 \uc5c5\ub85c\ub4dc\ud560 zip\ud30c\uc77c\uacfc release\ub97c \uad6c\ubd84\ud560 ID \uc815\ubcf4\ub97c <a href=\"https:\/\/octokit.github.io\/rest.js\/v20\" data-type=\"link\" data-id=\"https:\/\/octokit.github.io\/rest.js\/v20\">uploadReleaseAsset()<\/a>\uc5d0 \ub118\uaca8 \uc8fc\uba74 \ud574\ub2f9 \ud30c\uc77c\uc774 asset\uc73c\ub85c \ub4f1\ub85d\ub41c\ub2e4.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"yaml\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">    \/\/ Upload release assets.\n    const fs = require(\"fs\");\n    const filename = process.env.ASSET_FILE_PATH.replace(\/^.*[\\\\\/]\/, \"\");\n    var uploaded = await github.rest.repos.uploadReleaseAsset({\n       owner: context.repo.owner,\n       repo: context.repo.repo,\n       release_id: release_id,\n       name: filename,\n       data: await fs.readFileSync(process.env.ASSET_FILE_PATH),\n    });\n    console.log(\n       process.env.ASSET_FILE_PATH\n       + \" has been uploaded as \" + filename\n       + \" to the release \" + process.env.TAG);<\/pre>\n\n\n\n<p><strong>\uc8fc\uc758:<\/strong> upload \ub3d9\uc791\uc740 release\ub97c \uc218\uc815\ud558\ub294 \uac83\uc774\ubbc0\ub85c workflow\uac00 repository\uc5d0 \ub300\ud55c write permission\uc774 \uc788\uc5b4\uc57c \ud558\ubbc0\ub85c settings \ud56d\ubaa9\uc5d0\uc11c \uc5d0\uc11c write permission\uc774 \ud5c8\uac00\ub418\uc5b4 \uc788\ub294\uc9c0 \ud655\uc778\ud55c\ub2e4. \uc774 \ubd80\ubd84\uc774 \uc548\ub418\uc5b4 \uc788\ub2e4\uba74 403 error\uac00 \ub0a0 \uac83\uc774\ub2e4.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"620\" height=\"332\" src=\"https:\/\/litcoder.com\/wp-content\/uploads\/2024\/01\/github_workflow_write_perm.png\" alt=\"\" class=\"wp-image-3368\" srcset=\"https:\/\/litcoder.com\/wp-content\/uploads\/2024\/01\/github_workflow_write_perm.png 620w, https:\/\/litcoder.com\/wp-content\/uploads\/2024\/01\/github_workflow_write_perm-300x161.png 300w\" sizes=\"auto, (max-width: 620px) 100vw, 620px\" \/><\/figure>\n<\/div>\n\n\n<h2 class=\"wp-block-heading\">Release workflow \uc2e4\ud589<\/h2>\n\n\n\n<p>GitHub repo\uc758 Code \ud0ed\uc5d0\uc11c Tags -> Releases -> Tag -> Draft a new release\ub97c \uc120\ud0dd\ud55c \ud6c4 Choose a tag\ub97c \ub20c\ub7ec\uc11c \ub098\uc624\ub294 \uc785\ub825\ucc3d\uc5d0 \uc0c8\ub85c \uc0dd\uc131\ud560 version tag\ub97c \uc785\ub825\ud574 Create new tag\ub97c \uc120\ud0dd\ud55c \ub2e4\uc74c Publish release \ubc84\ud2bc\uc744 \ub204\ub978\ub2e4.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"395\" height=\"287\" src=\"https:\/\/litcoder.com\/wp-content\/uploads\/2024\/01\/github_workflow_create_tag.png\" alt=\"\" class=\"wp-image-3369\" style=\"width:319px;height:auto\" srcset=\"https:\/\/litcoder.com\/wp-content\/uploads\/2024\/01\/github_workflow_create_tag.png 395w, https:\/\/litcoder.com\/wp-content\/uploads\/2024\/01\/github_workflow_create_tag-300x218.png 300w\" sizes=\"auto, (max-width: 395px) 100vw, 395px\" \/><\/figure>\n<\/div>\n\n\n<p>\uc774 \ub54c \ub9cc\ub4e4\uc5b4\uc9c0\ub294 release\uc5d0\ub294 \uc18c\uc2a4\ucf54\ub4dc\ub9cc \ub4e4\uc5b4 \uc788\uc9c0\ub9cc, \uc815\uc0c1\uc801\uc73c\ub85c \ub3d9\uc791\ud588\ub2e4\uba74 Actions tab\uc5d0 release workflow\uac00 \ub4f1\ub85d\ub418\uc5b4 \uc218\ud589\ub418\ub294 \uac83\uc774 \ubcf4\uc77c \uac83\uc774\ub2e4. Workflow\uac00 \uc815\uc0c1 \uc885\ub8cc\ub41c \ud6c4 \ud574\ub2f9 release\ub85c \ub2e4\uc2dc \uac00\ubcf4\uba74 asset\uc774 \ub4f1\ub85d\ub418\uc5b4 \uc788\ub294 \uac83\uc744 \ubcfc \uc218 \uc788\ub2e4.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"911\" height=\"323\" src=\"https:\/\/litcoder.com\/wp-content\/uploads\/2024\/01\/github_workflow_release_attached-e1704114929383.png\" alt=\"\" class=\"wp-image-3370\" srcset=\"https:\/\/litcoder.com\/wp-content\/uploads\/2024\/01\/github_workflow_release_attached-e1704114929383.png 911w, https:\/\/litcoder.com\/wp-content\/uploads\/2024\/01\/github_workflow_release_attached-e1704114929383-300x106.png 300w, https:\/\/litcoder.com\/wp-content\/uploads\/2024\/01\/github_workflow_release_attached-e1704114929383-768x272.png 768w, https:\/\/litcoder.com\/wp-content\/uploads\/2024\/01\/github_workflow_release_attached-e1704114929383-624x221.png 624w\" sizes=\"auto, (max-width: 911px) 100vw, 911px\" \/><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>GitHub\uc5d0\uc11c release\ub97c \uc0dd\uc131\ud558\uba74 source code\uc758 snapshot\uc774 zip\uacfc tar.gz\ub85c \uc800\uc7a5\ub41c\ub2e4. \uc5ec\uae30\uc5d0 \ucd94\uac00\ud574\uc11c \ucef4\ud30c\uc77c\ub41c \uacb0\uacfc\uac00 \uc790\ub3d9\uc73c\ub85c \ucd94\uac00\ud558\ub3c4\ub85d \ud55c\ub2e4\uba74, \uac04\ub2e8\ud788 source code\uc640 \uc5f0\uacc4\ub41c \ubc14\uc774\ub108\ub9ac\ub3c4 \ud568\uaed8 \ubc30\ud3ec\ud560 \uc218 \uc788\uc744 \uac83\uc774\ub2e4. \uc774 \uae00\uc5d0\uc11c\ub294 \uc548\ub4dc\ub85c\uc774\ub4dc \ud504\ub85c\uc81d\ud2b8\ub97c \uac00\uc815\ud574\uc11c release\ub97c \uc0dd\uc131\ud560 \ub54c \uc548\ub4dc\ub85c\uc774\ub4dc APK\ub97c \ube4c\ub4dc\ud558\uace0 source code\uc640 \ud568\uaed8 \ubc30\ud3ec\ud558\ub294 \uac04\ub2e8\ud55c workflow\ub97c \uc124\uba85\ud55c\ub2e4. \uc804\uccb4 \ucf54\ub4dc Event trigger Release\uc5d0\uc11c\ub9cc \ub3d9\uc791\ud558\ubbc0\ub85c event trigger\ub294 release &#8211; published\uc774\ub2e4. [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[2,4],"tags":[11,54,321,320,319],"class_list":["post-3322","post","type-post","status-publish","format-standard","hentry","category-android","category-linux","tag-android","tag-github","tag-ocktokit","tag-release","tag-workflow"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/litcoder.com\/index.php?rest_route=\/wp\/v2\/posts\/3322","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/litcoder.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/litcoder.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/litcoder.com\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/litcoder.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3322"}],"version-history":[{"count":11,"href":"https:\/\/litcoder.com\/index.php?rest_route=\/wp\/v2\/posts\/3322\/revisions"}],"predecessor-version":[{"id":3674,"href":"https:\/\/litcoder.com\/index.php?rest_route=\/wp\/v2\/posts\/3322\/revisions\/3674"}],"wp:attachment":[{"href":"https:\/\/litcoder.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3322"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/litcoder.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3322"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/litcoder.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3322"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}