From fa87b9f71fd28399eabb4628d7a13dd47e60f4a2 Mon Sep 17 00:00:00 2001 From: fewensa <37804932+fewensa@users.noreply.github.com> Date: Fri, 13 Oct 2023 14:00:37 +0800 Subject: [PATCH] Migrate from old actoins repository (#4) * add smart vercel * add editorconfig * migrate actoins to .github --- .editorconfig | 12 + {actions => .github/actions}/README.md | 0 .github/actions/smart-vercel/README.md | 232 ++++++++++++++++++ .github/actions/smart-vercel/action.yml | 305 ++++++++++++++++++++++++ 4 files changed, 549 insertions(+) create mode 100644 .editorconfig rename {actions => .github/actions}/README.md (100%) create mode 100644 .github/actions/smart-vercel/README.md create mode 100644 .github/actions/smart-vercel/action.yml diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..24df5de --- /dev/null +++ b/.editorconfig @@ -0,0 +1,12 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +indent_style = space +indent_size = 4 +trim_trailing_whitespace = true + +[*.{yml,yaml}] +indent_size = 2 diff --git a/actions/README.md b/.github/actions/README.md similarity index 100% rename from actions/README.md rename to .github/actions/README.md diff --git a/.github/actions/smart-vercel/README.md b/.github/actions/smart-vercel/README.md new file mode 100644 index 0000000..8b7d28c --- /dev/null +++ b/.github/actions/smart-vercel/README.md @@ -0,0 +1,232 @@ +smart-vercel +=== + + +## Deploy staging environment + +``` +- uses: ./.github/actions/smart-vercel + name: Deploy to Vercel + id: smart-vercel + with: + vercel_token: ${{ secrets.VERCEL_TOKEN }} + vercel_group: ${{ env.VERCEL_GROUP }} + preview_output: true +``` + + +## Deploy production environment + +``` +- uses: ./.github/actions/smart-vercel + name: Deploy to Vercel + id: smart-vercel + with: + vercel_token: ${{ secrets.VERCEL_TOKEN }} + vercel_group: ${{ env.VERCEL_GROUP }} + preview_output: true + prod_mode: true +``` + +## Deploy use custom build command + +``` +- uses: ./.github/actions/smart-vercel + name: Deploy to Vercel + id: smart-vercel + with: + vercel_token: ${{ secrets.VERCEL_TOKEN }} + vercel_group: ${{ env.VERCEL_GROUP }} + preview_output: true + script_build: yarn build:dev +``` + +## Deploy use custom script + +``` +- uses: actions/setup-ruby@v1 + with: + ruby-version: '2.6' + +- uses: actions/setup-node@v2 + with: + node-version: '14' + +- name: Build + run: | + gem install bundler + bundle install + bundle exec middleman build --clean --verbose + +- uses: ./.github/actions/smart-vercel + name: Deploy to Vercel + id: smart-vercel + with: + vercel_token: ${{ secrets.VERCEL_TOKEN }} + vercel_group: ${{ env.VERCEL_GROUP }} + preview_output: true + script_run: false + prod_mode: true +``` + +## Use Vercel deploy (Not build in Github Actions) + +``` +- uses: ./.github/actions/smart-vercel + name: Deploy to Vercel + id: smart-vercel + with: + vercel_token: ${{ secrets.VERCEL_TOKEN }} + vercel_group: ${{ env.VERCEL_GROUP }} + preview_output: true + script_run: false + dist_path: . +``` + + +## Special dist path + +``` +- uses: ./.github/actions/smart-vercel + name: Deploy to Vercel + id: smart-vercel + with: + vercel_token: ${{ secrets.VERCEL_TOKEN }} + vercel_group: ${{ env.VERCEL_GROUP }} + preview_output: true + dist_path: build +``` + +## Special project name + +``` +- uses: ./.github/actions/smart-vercel + name: Deploy to Vercel + id: smart-vercel + with: + vercel_token: ${{ secrets.VERCEL_TOKEN }} + vercel_group: ${{ env.VERCEL_GROUP }} + preview_output: true + project_name: your-project-name +``` + +## Set alias domain + +``` +- uses: ./.github/actions/smart-vercel + name: Deploy to Vercel + id: smart-vercel + with: + vercel_token: ${{ secrets.VERCEL_TOKEN }} + vercel_group: ${{ env.VERCEL_GROUP }} + preview_output: true + alias_domain: domain-prefix # this will be bind domain-prefix.vercel.app to your deployment +``` + +``` +- uses: ./.github/actions/smart-vercel + name: Deploy to Vercel + id: smart-vercel + with: + vercel_token: ${{ secrets.VERCEL_TOKEN }} + vercel_group: ${{ env.VERCEL_GROUP }} + preview_output: true + alias_domain: | + domain-prefix # domain-prefix.vercel.app + prefix-b.vercel.app # prefix-b.vercel.app + your.custom.com # your.custom.com +``` + +``` +- uses: ./.github/actions/smart-vercel + name: Deploy to Vercel + id: smart-vercel + with: + vercel_token: ${{ secrets.VERCEL_TOKEN }} + vercel_group: ${{ env.VERCEL_GROUP }} + preview_output: true + alias_domain: | + domain-prefix,prefix-b.vercel.app,your.custom.com +``` + +## Use cache + +> The cache feature only work when `script_run: true` this value default is true + +enable cache. cache yarn + +``` +- uses: ./.github/actions/smart-vercel + name: Deploy to Vercel + id: smart-vercel + with: + vercel_token: ${{ secrets.VERCEL_TOKEN }} + vercel_group: ${{ env.VERCEL_GROUP }} + preview_output: true + enable_cache: true +``` + +use npm, cache + +``` +- uses: ./.github/actions/smart-vercel + name: Deploy to Vercel + id: smart-vercel + with: + vercel_token: ${{ secrets.VERCEL_TOKEN }} + vercel_group: ${{ env.VERCEL_GROUP }} + preview_output: true + enable_cache: true + cache_type: npm +``` + +custom cache key and cache path + +``` +- uses: ./.github/actions/smart-vercel + name: Deploy to Vercel + id: smart-vercel + with: + vercel_token: ${{ secrets.VERCEL_TOKEN }} + vercel_group: ${{ env.VERCEL_GROUP }} + preview_output: true + enable_cache: true + cache_key: ${{ runner.os }}-${{ hashFiles('**/package-lock.json') }} + cache_path: '**/node_modules' +``` + +## Notify with pr comment + +> Please you known, this will be post a comment to pull request, so this only works when trigger by pull request. + +``` +on: + pull_request: +``` + +``` +- uses: ./.github/actions/smart-vercel + name: Deploy to Vercel + id: smart-vercel + with: + vercel_token: ${{ secrets.VERCEL_TOKEN }} + vercel_group: ${{ env.VERCEL_GROUP }} + preview_output: true + enable_notify_comment: true +``` + +## Notify with slach channel + + +``` +- uses: ./.github/actions/smart-vercel + name: Deploy to Vercel + id: smart-vercel + with: + vercel_token: ${{ secrets.VERCEL_TOKEN }} + vercel_group: ${{ env.VERCEL_GROUP }} + preview_output: true + enable_notify_slack: true + slack_channel: your-channel-name + slack_webhook: ${{ secrets.SLACK_INCOMING_WEBHOOK_URL }} +``` diff --git a/.github/actions/smart-vercel/action.yml b/.github/actions/smart-vercel/action.yml new file mode 100644 index 0000000..96d4993 --- /dev/null +++ b/.github/actions/smart-vercel/action.yml @@ -0,0 +1,305 @@ +name: 'Smart Vercel' + +description: 'Smart build and deploy to Vercel' + +inputs: + node_version: + description: 'Nodejs version' + required: false + default: '18' + enable_cache: + description: 'Enable cache' + required: false + default: 'false' + cache_key: + description: 'Cache key' + required: false + default: 'none' + cache_path: + description: 'Cache path' + required: false + default: '**/node_modules' + cache_type: + description: 'Cache type, npm/yarn default yarn' + required: false + default: 'yarn' + script_run: + description: 'Run build script' + required: false + default: 'true' + script_install: + description: 'Install dependencies script' + required: false + default: 'yarn install' + script_build: + description: 'Build project script' + required: false + default: 'yarn build' + workdir: + description: 'Workdir' + required: false + default: '.' + project_name: + description: 'The name of project in Vercel' + required: false + vercel_group: + description: 'Vercel group account' + required: false + vercel_token: + description: 'Vercel token' + required: true + preview_output: + description: 'Output preview markdown' + required: false + prod_mode: + description: 'Production mode' + required: false + dist_path: + description: 'Dist output path' + required: false + default: 'build' + env_ci: + description: 'ENV CI' + required: false + default: 'false' + alias_domain: + description: 'Alias domain name for vercel.app' + required: false + enable_notify_comment: + description: 'Enable notify comment for pull request' + required: false + default: 'false' + enable_notify_slack: + description: 'Enable notify slack channel' + required: false + default: 'false' + slack_channel: + description: 'Slack channel name' + required: false + default: 'none' + slack_webhook: + description: 'Slack webhook' + required: false + default: 'none' + +outputs: + PREVIEW_OUTPUT: + description: "Vercel deploy output" + value: ${{ steps.deploy_vercel.outputs.PREVIEW_OUTPUT }} + PREVIEW_LINK: + description: "Vercel deploy preview link" + value: ${{ steps.deploy_vercel.outputs.PREVIEW_LINK }} + +runs: + using: "composite" + steps: + - name: Setup NodeJS + uses: actions/setup-node@v2 + if: ${{ inputs.script_run == 'true' }} + with: + node-version: ${{ inputs.node_version }} + + - name: Cache yarn + uses: actions/cache@v3 + if: ${{ (inputs.script_run == 'true') && (inputs.enable_cache == 'true') && (inputs.cache_key == 'none') && (inputs.cache_type == 'yarn') }} + with: + path: ${{ inputs.cache_path }} + key: ${{ runner.os }}-${{ hashFiles('**/yarn.lock') }} + + - name: Cache npm + uses: actions/cache@v3 + if: ${{ (inputs.script_run == 'true') && (inputs.enable_cache == 'true') && (inputs.cache_key == 'none') && (inputs.cache_type == 'npm') }} + with: + path: ${{ inputs.cache_path }} + key: ${{ runner.os }}-${{ hashFiles('**/package-lock.json') }} + + - name: Cache custom + uses: actions/cache@v3 + if: ${{ (inputs.script_run == 'true') && (inputs.enable_cache == 'true') && (inputs.cache_key != 'none') }} + with: + path: ${{ inputs.cache_path }} + key: ${{ inputs.cache_key }} + + - name: Install dependencies + shell: bash + if: ${{ inputs.script_run == 'true' }} + run: | + cd ${{ inputs.workdir }} + ${{ inputs.script_install }} + + - name: Build project + shell: bash + if: ${{ inputs.script_run == 'true' }} + run: | + cd ${{ inputs.workdir }} + export CI=${{ inputs.env_ci }} + ${{ inputs.script_build }} + + - name: Current dir name + shell: bash + id: dir-name + run: | + DIR_NAME=$(basename "$PWD") + echo '' + echo "::set-output name=DIR_NAME::$DIR_NAME" + + - name: Repo name + shell: bash + id: repo-name + run: | + PROJECT_NAME=${{ inputs.project_name }} + REPO_NAME=${PROJECT_NAME:-${GITHUB_REPOSITORY#*/}} + echo '' + echo "::set-output name=REPO_NAME::$REPO_NAME" + + - name: Prepare vercel cli + shell: bash + run: | + npm uninstall -g vercel || exit 0 + npm i -g vercel@25.2.3 + vercel --version + + - name: Deploy to Vercel + shell: bash + id: deploy_vercel + run: | + set -xe + cd ${{ inputs.workdir }} + DIR_NAME=${{ steps.dir-name.outputs.DIR_NAME }} + REPO_NAME=${{ steps.repo-name.outputs.REPO_NAME }} + VERCEL_TOKEN=${{ inputs.vercel_token }} + VERCEL_GROUP=${{ inputs.vercel_group }} + PREVIEW_OUTPUT=${{ inputs.preview_output }} + PROD_MODE=${{ inputs.prod_mode }} + DIST_PATH=${{ inputs.dist_path }} + + INPUT_ALIAS_DOMAIN='${{ inputs.alias_domain }}' + ALL_ALIAS_DOMAIN=$(echo "${INPUT_ALIAS_DOMAIN}" | sed ":a;$!N;s/\n/ /g;ba" | sed "s/,/ /g") + DOMAIN_IDENTIFY_KEYWORD=. + + if [ "${DIST_PATH}" == "." ]; then + cd .. + if [ "${DIR_NAME}" != "${REPO_NAME}" ]; then + cp -r ${DIR_NAME} ${REPO_NAME} + fi + else + mv ${DIST_PATH} ${REPO_NAME} + fi + + PATH_VERCEL_JSON=./vercel.json + if [ -f "${PATH_VERCEL_JSON}" ]; then + mv ${PATH_VERCEL_JSON} ${REPO_NAME}/ + fi + + cd ${REPO_NAME} + + VERCEL="vercel ${VERCEL_TOKEN:+--token $VERCEL_TOKEN} ${VERCEL_GROUP:+--scope $VERCEL_GROUP}" + + ${VERCEL} link --confirm + + ${VERCEL} ${PROD_MODE:+--prod} deploy | tee deploy.log + + DEPLOYMENT_URL=$(cat deploy.log) + + for DOMAIN in ${ALL_ALIAS_DOMAIN} + do + if test "${DOMAIN#*$DOMAIN_IDENTIFY_KEYWORD}" != "${DOMAIN}" + then + echo "alias with custom domain: ${DOMAIN}" + ${VERCEL} alias ${DEPLOYMENT_URL} ${DOMAIN} + else + echo "alias with bundle domain: ${DOMAIN}.vercel.app" + ${VERCEL} alias ${DEPLOYMENT_URL} ${DOMAIN}.vercel.app + fi + done + + content="${DEPLOYMENT_URL//'%'/'%25'}" + content="${content//$'\n'/'%0A'}" + content="${content//$'\r'/'%0D'}" + PREVIEW_LINK="${content}" + + for DOMAIN in ${ALL_ALIAS_DOMAIN} + do + if test "${DOMAIN#*\*}" != "${DOMAIN}"; then + continue + fi + if test "${DOMAIN#*$DOMAIN_IDENTIFY_KEYWORD}" != "${DOMAIN}" + then + PREVIEW_LINK="${PREVIEW_LINK} https://${DOMAIN}" + else + PREVIEW_LINK="${PREVIEW_LINK} https://${DOMAIN}.vercel.app" + fi + done + + rm -rf deploy.log + + echo '' + + if [ -n "${PREVIEW_OUTPUT}" ]; then + EVENT_NAME=${{ github.event_name }} + SHA=${GITHUB_SHA::7} + if [ "${EVENT_NAME}" == "pull_request" ]; then + SHA=${{ github.event.pull_request.head.sha }} + SHA=${SHA::7} + fi + COMMIT="Commit: [${SHA}](${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/commit/${SHA})" + PREVIEW="Preview: ${PREVIEW_LINK}" + + echo '\---' >> comment.md + echo $COMMIT >> comment.md + echo $PREVIEW >> comment.md + echo '' >> comment.md + + content=$(cat comment.md) + content="${content//'%'/'%25'}" + content="${content//$'\n'/'%0A'}" + content="${content//$'\r'/'%0D'}" + PREVIEW_OUTPUT=${content} + + rm -rf comment.md + + echo "::set-output name=PREVIEW_OUTPUT::$PREVIEW_OUTPUT" + else + echo "::set-output name=PREVIEW_OUTPUT::$PREVIEW_LINK" + fi + + echo '' + echo "::set-output name=PREVIEW_LINK::$PREVIEW_LINK" + + - name: Restore dir name + shell: bash + if: always() + run: | + set -xe + + DIR_NAME=${{ steps.dir-name.outputs.DIR_NAME }} + REPO_NAME=${{ steps.repo-name.outputs.REPO_NAME }} + DIST_PATH=${{ inputs.dist_path }} + + if [ "${DIST_PATH}" == "." ]; then + cd .. + if [ "${DIR_NAME}" != "${REPO_NAME}" ]; then + rm -rf ${DIR_NAME} + mv ${REPO_NAME} ${DIR_NAME} + fi + cd ${DIR_NAME} + fi + + - name: Comment deploy ouput + uses: marocchino/sticky-pull-request-comment@v2 + if: ${{ inputs.enable_notify_comment == 'true' }} + with: + append: true + message: ${{ steps.deploy_vercel.outputs.PREVIEW_OUTPUT }} + + - name: Slack Notification + uses: rtCamp/action-slack-notify@v2 + if: ${{ (inputs.enable_notify_slack == 'true') && (inputs.slack_channel != 'none') && (inputs.slack_webhook != 'none') }} + env: + SLACK_CHANNEL: ${{ inputs.slack_channel }} + SLACK_COLOR: ${{ job.status }} + SLACK_ICON: https://avatars.githubusercontent.com/u/14985020?s=48&v=4 + SLACK_MESSAGE: '${{ steps.deploy_vercel.outputs.PREVIEW_LINK }}' + SLACK_TITLE: Preview + SLACK_USERNAME: Vercel + SLACK_WEBHOOK: ${{ inputs.slack_webhook }}