├── README.md ├── automatic-releases ├── .github │ └── workflows │ │ ├── pre-release.yml │ │ └── tagged-release.yml └── README.md ├── github_python_slack ├── .github │ └── workflows │ │ └── crawler.yml ├── requirements.txt └── run.py ├── github_slack_notification └── .github │ └── workflows │ └── slack.yml ├── self-hosted-gitHub-actions-runner ├── .github │ └── workflows │ │ └── blank.yml ├── README.md └── docker-compose.yml └── ssh-server-github-action ├── .github └── workflows │ └── demo.yml └── README.md /README.md: -------------------------------------------------------------------------------- 1 | # github-actions-tutorial 2 | 3 | 這邊文章會紀錄一些搭配 github actions 的小玩具 :smile: 4 | 5 | * [Youtube Tutorial - github actions 教學 - part1](https://youtu.be/a-EiC_Ll3EM) 6 | 7 | * [自動更新 github profile](https://github.com/twtrubiks/twtrubiks) 8 | 9 | * [Youtube Tutorial - github actions 搭配 slack 教學 - part2](https://youtu.be/Se5UZipBnBI) - [文章快速連結](https://github.com/twtrubiks/github-actions-tutorial/blob/main/github_slack_notification/.github/workflows/slack.yml) 10 | 11 | * [Youtube Tutorial - github actions 搭配 python 教學 - part3](https://youtu.be/VRgW1lcIg_A) - [文章快速連結](https://github.com/twtrubiks/github-actions-tutorial/blob/main/github_python_slack) 12 | 13 | * [Youtube Tutorial - github actions 搭配 automatic-releases 教學](https://youtu.be/pCnGcLj_3Lg) - [文章快速連結](https://github.com/twtrubiks/github-actions-tutorial/blob/main/automatic-releases) 14 | 15 | * Self-Hosted GitHub Actions Runner 教學 - [文章快速連結](https://github.com/twtrubiks/github-actions-tutorial/blob/main/self-hosted-gitHub-actions-runner) 16 | 17 | * 透過 github action 遠端 ssh server 教學 - [文章快速連結](https://github.com/twtrubiks/github-actions-tutorial/tree/main/ssh-server-github-action) -------------------------------------------------------------------------------- /automatic-releases/.github/workflows/pre-release.yml: -------------------------------------------------------------------------------- 1 | name: "pre-release" 2 | 3 | on: 4 | push: 5 | branches: 6 | - "main" 7 | 8 | jobs: 9 | pre-release: 10 | name: "Pre Release" 11 | runs-on: "ubuntu-latest" 12 | 13 | steps: 14 | # ... 15 | - name: "Build & test" 16 | run: | 17 | echo "done!" 18 | 19 | - uses: "marvinpinto/action-automatic-releases@latest" 20 | with: 21 | repo_token: "${{ secrets.GITHUB_TOKEN }}" 22 | automatic_release_tag: "latest" 23 | prerelease: true 24 | title: "Development Build" -------------------------------------------------------------------------------- /automatic-releases/.github/workflows/tagged-release.yml: -------------------------------------------------------------------------------- 1 | name: "tagged-release" 2 | 3 | on: 4 | push: 5 | tags: 6 | - "v*" 7 | 8 | jobs: 9 | tagged-release: 10 | name: "Tagged Release" 11 | runs-on: "ubuntu-latest" 12 | 13 | steps: 14 | # ... 15 | - name: "Build & test" 16 | run: | 17 | echo "done!" 18 | 19 | - uses: "marvinpinto/action-automatic-releases@latest" 20 | with: 21 | repo_token: "${{ secrets.GITHUB_TOKEN }}" 22 | prerelease: false -------------------------------------------------------------------------------- /automatic-releases/README.md: -------------------------------------------------------------------------------- 1 | # github actions 搭配 automatic-releases 教學 2 | 3 | * [Youtube Tutorial - github actions 搭配 automatic-releases 教學](https://youtu.be/pCnGcLj_3Lg) 4 | 5 | 官方文件可參考 [https://github.com/marketplace/actions/automatic-releases](https://github.com/marketplace/actions/automatic-releases) 6 | 7 | 底下主要有兩個分別是 [pre-release.yml](https://github.com/twtrubiks/github-actions-tutorial/blob/main/automatic-releases/.github/workflows/pre-release.yml) 和 [tagged-release.yml](https://github.com/twtrubiks/github-actions-tutorial/blob/main/automatic-releases/.github/workflows/tagged-release.yml), 8 | 9 | [pre-release.yml](https://github.com/twtrubiks/github-actions-tutorial/blob/main/automatic-releases/.github/workflows/pre-release.yml) 10 | 11 | 當你 push main(master) 分支時, 會自動幫你產生一個 pre-release 的頁面 12 | 13 | ![alt tag](https://i.imgur.com/VHx9jze.png) 14 | 15 | [tagged-release.yml](https://github.com/twtrubiks/github-actions-tutorial/blob/main/automatic-releases/.github/workflows/tagged-release.yml) 16 | 17 | 當你下 push tag 時, 18 | 19 | ```cmd 20 | ❯ git tag v1.0.1 21 | ❯ git push origin v1.0.1 22 | ``` 23 | 24 | 會自動幫你產生一個 release 頁面, 25 | 26 | 非常建議搭配 [規格化 commit](https://github.com/twtrubiks/python-notes/tree/master/commitizen_pre_commit_tutorial) 一起始用, 27 | 28 | 因為這樣就會自動幫你整理成漂亮的格式 29 | 30 | ![alt tag](https://i.imgur.com/smiHnlG.png) 31 | -------------------------------------------------------------------------------- /github_python_slack/.github/workflows/crawler.yml: -------------------------------------------------------------------------------- 1 | # This is a basic workflow to help you get started with Actions 2 | 3 | name: crawler 4 | 5 | # Controls when the action will run. 6 | on: 7 | # Triggers the workflow on push or pull request events but only for the master branch 8 | 9 | schedule: 10 | - cron: '0 */8 * * *' 11 | 12 | # Allows you to run this workflow manually from the Actions tab 13 | workflow_dispatch: 14 | 15 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 16 | jobs: 17 | # This workflow contains a single job called "build" 18 | build: 19 | # The type of runner that the job will run on 20 | runs-on: ubuntu-latest 21 | 22 | steps: 23 | - uses: actions/checkout@v2 24 | - uses: actions/setup-python@v2 25 | with: 26 | python-version: '3.x' # Version range or exact version of a Python version to use, using SemVer's version range syntax 27 | architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified 28 | 29 | - name: Install dependencies 30 | run: | 31 | if [ -f requirements.txt ]; then pip install -r requirements.txt; fi 32 | 33 | - name: Run Python Crawler 34 | run: python run.py 35 | env: 36 | SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} 37 | CHANNEL_ACCESS_TOKEN: ${{ secrets.CHANNEL_ACCESS_TOKEN }} 38 | LINE_GROUP_ID: ${{ secrets.LINE_GROUP_ID }} 39 | LINE_USER_ID: ${{ secrets.LINE_USER_ID }} 40 | -------------------------------------------------------------------------------- /github_python_slack/requirements.txt: -------------------------------------------------------------------------------- 1 | beautifulsoup4 2 | requests 3 | line-bot-sdk -------------------------------------------------------------------------------- /github_python_slack/run.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import json 3 | import os 4 | from bs4 import BeautifulSoup 5 | from linebot.models import TextSendMessage 6 | from linebot import ( 7 | LineBotApi, WebhookHandler 8 | ) 9 | 10 | class SlackNotification: 11 | def __init__(self, context, slack_webhook): 12 | self.context = context 13 | self.slack_webhook = slack_webhook 14 | 15 | def push(self): 16 | slack_data = { 17 | "username": "NotificationBot", 18 | "icon_emoji": ":satellite:", 19 | "channel" : "#random", 20 | "attachments": [ 21 | { 22 | "color": "#a633ee", 23 | "fields": [ 24 | { 25 | "title": "New Incoming Message :zap:", 26 | "value": self.context, 27 | "short": "false", 28 | } 29 | ] 30 | } 31 | ] 32 | } 33 | headers = {'Content-Type': "application/json"} 34 | response = requests.post(self.slack_webhook, data=json.dumps(slack_data), headers=headers) 35 | if response.status_code != 200: 36 | raise Exception(response.status_code, response.text) 37 | 38 | class LineNotification: 39 | def __init__(self, Channel_Access_Token, context): 40 | self.line_bot_api = LineBotApi(Channel_Access_Token) 41 | self.context = context 42 | 43 | def push(self, target): 44 | self.line_bot_api.push_message(target, TextSendMessage(text=self.context)) 45 | 46 | class WebCrawler: 47 | def __init__(self): 48 | self.rs = requests.session() 49 | self.urls = [ 50 | ('道瓊指數','https://invest.cnyes.com/index/GI/DJI'), # DJI 51 | ('S&P 500','https://invest.cnyes.com/index/GI/SPX'), # SPX 52 | ('美國那斯達克綜合指數','https://invest.cnyes.com/index/GI/IXIC'),# NASDAQ 53 | ('費城半導體','https://invest.cnyes.com/index/GI/SOX'),# 費城半導體 54 | ] 55 | self.result = [] 56 | 57 | def fetch(self): 58 | for url in self.urls: 59 | res = self.rs.get(url[1], verify=False) 60 | soup = BeautifulSoup(res.text, 'html.parser') 61 | info_price = soup.select('.jsx-2941083017.info-price')[0].text 62 | info_net = soup.select('.jsx-2941083017.change-net')[0].text 63 | info_percent = soup.select('.jsx-2941083017.change-percent')[0].text 64 | 65 | if '+' in info_net: 66 | info = '{}▲ {}▲'.format(info_net, info_percent) 67 | info = info.replace('+', '') 68 | else: 69 | info = '{}▼ {}▼'.format(info_net, info_percent) 70 | info = info.replace('-', '') 71 | 72 | self.result.append('{}\n{}\n{}'.format(url[0], info_price, info)) 73 | 74 | def push(self, slack_webhook, line_token): 75 | result = '\n\n'.join(self.result) 76 | 77 | slack = SlackNotification(result, slack_webhook) 78 | slack.push() 79 | 80 | try: 81 | msg = LineNotification(line_token, result) 82 | # target = os.getenv('LINE_USER_ID') 83 | target = os.getenv('LINE_GROUP_ID') 84 | msg.push(target) 85 | except Exception as e: 86 | print(e) 87 | 88 | if __name__ == '__main__': 89 | crawler = WebCrawler() 90 | crawler.fetch() 91 | crawler.push(os.getenv('SLACK_WEBHOOK'), os.getenv('CHANNEL_ACCESS_TOKEN')) -------------------------------------------------------------------------------- /github_slack_notification/.github/workflows/slack.yml: -------------------------------------------------------------------------------- 1 | # This is a basic workflow to help you get started with Actions 2 | 3 | name: slack 4 | 5 | # Controls when the action will run. 6 | on: 7 | # Triggers the workflow on push or pull request events but only for the master branch 8 | push: 9 | 10 | # Allows you to run this workflow manually from the Actions tab 11 | workflow_dispatch: 12 | 13 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 14 | jobs: 15 | slackNotification: 16 | name: Slack Notification 17 | runs-on: ubuntu-latest 18 | steps: 19 | - name: checkout 20 | uses: actions/checkout@v2 21 | 22 | - name: Slack Notification 23 | uses: rtCamp/action-slack-notify@v2 24 | env: 25 | SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} 26 | SLACK_COLOR: '#3278BD' 27 | SLACK_CHANNEL: random 28 | SLACK_USERNAME: GITHUB_BOT 29 | -------------------------------------------------------------------------------- /self-hosted-gitHub-actions-runner/.github/workflows/blank.yml: -------------------------------------------------------------------------------- 1 | # This is a basic workflow to help you get started with Actions 2 | 3 | name: CI 4 | 5 | # Controls when the action will run. 6 | on: 7 | # Triggers the workflow on push or pull request events but only for the master branch 8 | # push: 9 | # branches: [ master ] 10 | # pull_request: 11 | # branches: [ master ] 12 | 13 | # Allows you to run this workflow manually from the Actions tab 14 | workflow_dispatch: 15 | 16 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 17 | jobs: 18 | # This workflow contains a single job called "build" 19 | build: 20 | # The type of runner that the job will run on 21 | runs-on: self-hosted 22 | 23 | # Steps represent a sequence of tasks that will be executed as part of the job 24 | steps: 25 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 26 | - uses: actions/checkout@v4 27 | 28 | # Runs a single command using the runners shell 29 | - name: Run a one-line script 30 | run: echo Hello, world! 31 | 32 | # Runs a set of commands using the runners shell 33 | - name: Run a multi-line script 34 | run: | 35 | echo Add other actions to build, 36 | echo test, and deploy your project. 37 | date 38 | 39 | - name: Run docker ps 40 | run: docker ps 41 | 42 | - name: Run docker nginx 43 | run: docker run --name nginx_test -d nginx:1.27.1 -------------------------------------------------------------------------------- /self-hosted-gitHub-actions-runner/README.md: -------------------------------------------------------------------------------- 1 | # Self-Hosted GitHub Actions Runner 教學 2 | 3 | 這邊教大家怎麼用自己建立的機器 (Runner) 跑 GitHub Actions, 4 | 5 | 之前的範例都是用 github 提供的 Runner (但通常這個有一些限制, 像是超過要付費之類的), 6 | 7 | 首先, 先建立一個 repo, 然後準備一台機器(用本機或是線上的機器都可以), 8 | 9 | ![alt tag](https://i.imgur.com/sXuhJRY.png) 10 | 11 | 註冊建立 Runner 12 | 13 | (簡單說就是我們建立的機器會主動和 github 連線, 當它問 github 發現有任務要執行的時候, 就會執行任務), 14 | 15 | 到這邊選則對應的機器, 無腦複製貼上(基本上都 enter 即可), 這邊會有你的 repo 的 token, 16 | 17 | ![alt tag](https://i.imgur.com/xivQyYO.png) 18 | 19 | 最後貼上 `./run.sh` 就可以順利建立 Runner 了 20 | 21 | ![alt tag](https://i.imgur.com/cjW34RH.png) 22 | 23 | 建立一個簡單的 [workflows/blank.yml](https://github.com/twtrubiks/github-actions-tutorial/blob/main/self-hosted-gitHub-actions-runner/.github/workflows/blank.yml), 記得要改成 `self-hosted` 24 | 25 | ```yml 26 | # This is a basic workflow to help you get started with Actions 27 | 28 | name: CI 29 | 30 | # Controls when the action will run. 31 | on: 32 | # Triggers the workflow on push or pull request events but only for the master branch 33 | # push: 34 | # branches: [ master ] 35 | # pull_request: 36 | # branches: [ master ] 37 | 38 | # Allows you to run this workflow manually from the Actions tab 39 | workflow_dispatch: 40 | 41 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 42 | jobs: 43 | # This workflow contains a single job called "build" 44 | build: 45 | # The type of runner that the job will run on 46 | runs-on: self-hosted 47 | 48 | # Steps represent a sequence of tasks that will be executed as part of the job 49 | steps: 50 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 51 | - uses: actions/checkout@v4 52 | 53 | # Runs a single command using the runners shell 54 | - name: Run a one-line script 55 | run: echo Hello, world! 56 | 57 | # Runs a set of commands using the runners shell 58 | - name: Run a multi-line script 59 | run: | 60 | echo Add other actions to build, 61 | echo test, and deploy your project. 62 | date 63 | 64 | #- name: Run docker ps 65 | # run: docker ps 66 | 67 | #- name: Run docker nginx 68 | # run: docker run --name nginx_test -d nginx:1.27.1 69 | 70 | ``` 71 | 72 | 然後回到 github action 上, 去跑跑看, 你會發現指定的 Runner 有反應了, 73 | 74 | 你也可以去看你自己建立的 Runner, 會有 log 的 75 | 76 | ![alt tag](https://i.imgur.com/VlTVWdt.png) 77 | 78 | 如果你的 Runner 中斷, 然後你重新執行指令可能會出現以下的錯誤 79 | 80 | ```text 81 | Cannot configure the runner because it is already configured. To reconfigure the runner, run 'config.cmd remove' or './config.sh remove' first 82 | ``` 83 | 84 | 請執行 `./config.sh remove` 然後填入你的 repo 的 token 即可. 85 | 86 | # Docker Github Actions Runner 87 | 88 | 接著來介紹一個 Docker 建立 Github Actions Runner 的版本 89 | 90 | docker in docker 的概念. 91 | 92 | [Docker Github Actions Runner](https://github.com/myoung34/docker-github-actions-runner) 93 | 94 | 安裝建立的流程可參考 [Usage](https://github.com/myoung34/docker-github-actions-runner/wiki/Usage) 95 | 96 | 準備一台機器(用本機或是線上的機器都可以), 97 | 98 | ## 事前準備 99 | 100 | 設定 Token 101 | 102 | ![alt tag](https://i.imgur.com/5Sdgo4h.png) 103 | 104 | github 必須開權限 105 | 106 | ![alt tag](https://i.imgur.com/pEQTmBQ.png) 107 | 108 | ```text 109 | repo (all) 110 | admin:org (all) (mandatory for organization-wide runner) 111 | admin:enterprise (all) (mandatory for enterprise-wide runner) 112 | admin:public_key - read:public_key 113 | admin:repo_hook - read:repo_hook 114 | admin:org_hook 115 | notifications 116 | workflow 117 | ``` 118 | 119 | 複製你的 Token. 120 | 121 | 有很多的安裝方法, 這邊介紹幾個給大家 122 | 123 | ## Systemd 124 | 125 | 如果不懂 Systemd, 可參考 [systemctl教學](https://github.com/twtrubiks/linux-note/tree/master/systemctl-tutorial) 126 | 127 | 建立一個 `ephemeral-github-actions-runner.service` 128 | 129 | ```service 130 | [Unit] 131 | Description=Ephemeral GitHub Actions Runner Container 132 | After=docker.service 133 | Requires=docker.service 134 | [Service] 135 | TimeoutStartSec=0 136 | Restart=always 137 | ExecStartPre=-/usr/bin/docker stop %N 138 | ExecStartPre=-/usr/bin/docker rm %N 139 | ExecStartPre=-/usr/bin/docker pull myoung34/github-runner:latest 140 | ExecStart=/usr/bin/docker run --rm \ 141 | --env-file /etc/ephemeral-github-actions-runner.env \ 142 | -e RUNNER_NAME=%H \ 143 | -v /var/run/docker.sock:/var/run/docker.sock \ 144 | --name %N \ 145 | myoung34/github-runner:latest 146 | [Install] 147 | WantedBy=multi-user.target 148 | ``` 149 | 150 | 然後建立需要的環境變數 `ephemeral-github-actions-runner.env` 151 | 152 | ```env 153 | # Install with: 154 | # sudo install -m 600 ephemeral-github-actions-runner.env /etc/ 155 | RUNNER_SCOPE=repo 156 | REPO_URL=https://github.com/your-org/your-repo 157 | # Alternate for org scope: 158 | #RUNNER_SCOPE=org 159 | #ORG_NAME=your-org 160 | LABELS=any-custom-labels-go-here 161 | ACCESS_TOKEN=foo-access-token 162 | RUNNER_WORKDIR=/tmp/runner/work 163 | DISABLE_AUTO_UPDATE=1 164 | EPHEMERAL=1 165 | ``` 166 | 167 | ACCESS_TOKEN 就是貼上前面取得的 Token 168 | 169 | 最後執行以下的指令 170 | 171 | ```cmd 172 | # Install with: 173 | # sudo install -m 644 ephemeral-github-actions-runner.service /etc/systemd/system/ 174 | # sudo systemctl daemon-reload 175 | # sudo systemctl enable ephemeral-github-actions-runner 176 | # Run with: 177 | # sudo systemctl start ephemeral-github-actions-runner 178 | # Stop with: 179 | # sudo systemctl stop ephemeral-github-actions-runner 180 | # See live logs with: 181 | # journalctl -f -u ephemeral-github-actions-runner.service --no-hostname --no-tail 182 | ``` 183 | 184 | 查看 log 確認是否正確執行. 185 | 186 | ## docker compose 版本 187 | 188 | 這個應該是最快的, 直接 `docker compose up -d` 收工. 189 | 190 | ![alt tag](https://i.imgur.com/u3pctlC.png) 191 | 192 | [docker-compose.yml](docker-compose.yml) 193 | 194 | ```yml 195 | services: 196 | worker: 197 | image: myoung34/github-runner:latest 198 | restart: always 199 | environment: 200 | REPO_URL: https://github.com/xxxxxx 201 | RUNNER_NAME: example-name 202 | RUNNER_WORKDIR: /tmp/runner/work 203 | # RUNNER_GROUP: my-group 204 | RUNNER_SCOPE: 'repo' 205 | # RUNNER_TOKEN: someGithubTokenHere # This token is short lived 206 | ACCESS_TOKEN: Token 207 | LABELS: linux,x64,gpu 208 | DISABLE_AUTO_UPDATE: 1 209 | EPHEMERAL: 1 210 | security_opt: 211 | # needed on SELinux systems to allow docker container to manage other docker containers 212 | - label:disable 213 | volumes: 214 | - '/var/run/docker.sock:/var/run/docker.sock' 215 | - '/tmp/runner:/tmp/runner' 216 | # note: a quirk of docker-in-docker is that this path 217 | # needs to be the same path on host and inside the container, 218 | # docker mgmt cmds run outside of docker but expect the paths from within 219 | ``` 220 | 221 | 這是 docker-in-docker 的概念, 也就是說你在本機執行的 `docker ps` 222 | 223 | 和在 docker(runner) 裡面執行 `docker ps` 看到的東西會是一樣的, 224 | 225 | 也就是相通, 超酷 😀 226 | 227 | 可以直接在 workflow 裡面加一個啟動 docker 的指令觀察看看. 228 | 229 | 另外建議大家 google 一下 `/var/run/docker.sock` 在 docker 中是什麼意義. -------------------------------------------------------------------------------- /self-hosted-gitHub-actions-runner/docker-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | worker: 3 | image: myoung34/github-runner:latest 4 | restart: always 5 | environment: 6 | REPO_URL: https://github.com/xxxxxx 7 | RUNNER_NAME: example-name 8 | RUNNER_WORKDIR: /tmp/runner/work 9 | # RUNNER_GROUP: my-group 10 | RUNNER_SCOPE: 'repo' 11 | # RUNNER_TOKEN: someGithubTokenHere # This token is short lived 12 | ACCESS_TOKEN: Token 13 | LABELS: linux,x64,gpu 14 | DISABLE_AUTO_UPDATE: 1 15 | EPHEMERAL: 1 16 | security_opt: 17 | # needed on SELinux systems to allow docker container to manage other docker containers 18 | - label:disable 19 | volumes: 20 | - '/var/run/docker.sock:/var/run/docker.sock' 21 | - '/tmp/runner:/tmp/runner' 22 | # note: a quirk of docker-in-docker is that this path 23 | # needs to be the same path on host and inside the container, 24 | # docker mgmt cmds run outside of docker but expect the paths from within -------------------------------------------------------------------------------- /ssh-server-github-action/.github/workflows/demo.yml: -------------------------------------------------------------------------------- 1 | name: demo 2 | on: 3 | # push: 4 | # branches: [ main ] 5 | workflow_dispatch: 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: executing remote ssh commands using ssh key 12 | uses: appleboy/ssh-action@v1.2.0 13 | with: 14 | host: ${{ secrets.SSH_HOST }} 15 | username: ${{ secrets.SSH_USER }} 16 | key: ${{ secrets.SSH_PRIVATE_KEY }} 17 | port: ${{ secrets.SSH_PORT }} 18 | script: | 19 | pwd 20 | ls 21 | -------------------------------------------------------------------------------- /ssh-server-github-action/README.md: -------------------------------------------------------------------------------- 1 | # 透過 github action 遠端 ssh server 2 | 3 | ssh-action-tutorial (注意 .github 資料夾) 4 | 5 | 這篇文章是使用 PRIVATE_KEY 的方式, 還有其他方式可參考 [ssh-action](https://github.com/appleboy/ssh-action) 6 | 7 | 使用方法, 8 | 9 | 先在遠端 目標server(你要 ssh 的server) 執行以下的指令 10 | 11 | ```cmd 12 | ssh-keygen -t rsa -b 4096 -C "github-actions" 13 | ``` 14 | 15 | 接著 在遠端 目標server(你要 ssh 的server) 執行以下的指令 16 | 17 | ```cmd 18 | cat ~/.ssh/id_rsa_github_actions.pub >> ~/.ssh/authorized_keys 19 | ``` 20 | 21 | 之後設定 yaml 即可, 可參考 [workflows/demo.yml](https://github.com/twtrubiks/github-actions-tutorial/blob/main/ssh-server-github-action/.github/workflows/demo.yml) 22 | 23 | 需要設定幾個參數, 24 | 25 | SSH_HOST 目標server(你要 ssh 的server) ip 26 | 27 | SSH_USER 目標server(你要 ssh 的server) 使用者 28 | 29 | SSH_PRIVATE_KEY 貼上我們建立出來的 PRIVATE_KEY `~/.ssh/id_rsa_github_actions` 30 | 31 | SSH_PORT 目標server(你要 ssh 的server) port 32 | 33 | ![alt tag](https://i.imgur.com/wapDARQ.png) 34 | 35 | 之後就可以簡單測試一下 :blush: :blush: 36 | 37 | 這邊說明一下 ssh 的流程, 38 | 39 | | 流程說明 | | | 40 | |----------------|----------------|---------| 41 | | | 正常 | 遠端 | 42 | | 一般 ssh | 留下私人的key | 放 .pub | 43 | | github action | 環境變數貼上 PRIVATE_KEY | 放 .pub | 44 | 45 | 仔細思考, 其實就是流程反過來而已, 因為我們沒辦法進去 github action 那台機器設定, 46 | 47 | 所以變成我們自己先設定好 ssh key, 再將 private key 貼到 github action 中的環境變數, 48 | 49 | 只要把想法想成我們的本機現在是 github action 那台機器就會比較了解了 :smiley: 50 | --------------------------------------------------------------------------------