build.yml 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533
  1. name: Build Check
  2. on:
  3. push:
  4. paths-ignore:
  5. - 'docs/**'
  6. - '**.md'
  7. - 'mkdocs.yml'
  8. - '.gitignore'
  9. branches:
  10. - master
  11. env:
  12. GO_VERSION: 1.16
  13. GOPATH: ${{ github.workspace }}/go
  14. WORKING_DIR: ${{ github.workspace }}/go/src/github.com/ethereum/go-ethereum
  15. jobs:
  16. build:
  17. name: 'Run tests and build on ${{ matrix.os }}'
  18. strategy:
  19. fail-fast: false
  20. matrix:
  21. # Not enable for macos as there's a consistent failure:
  22. # --- FAIL: TestUPNP_DDWRT (2.20s)
  23. # ###[error] natupnp_test.go:165: not discovered
  24. # must be sommething with Github Actions VM networking setup.
  25. # Event Ubuntu requires a workaround
  26. os: [ "ubuntu-20.04" ]
  27. env:
  28. QUORUM_IGNORE_TEST_PACKAGES: github.com/ethereum/go-ethereum/les,github.com/ethereum/go-ethereum/les/flowcontrol,github.com/ethereum/go-ethereum/mobile
  29. runs-on: ${{ matrix.os }}
  30. steps:
  31. - name: 'Setup Go ${{ env.GO_VERSION }}'
  32. uses: actions/setup-go@v1
  33. with:
  34. go-version: ${{ env.GO_VERSION }}
  35. - name: 'Check out project files'
  36. uses: actions/checkout@v2
  37. with:
  38. submodules: recursive
  39. path: ${{ env.WORKING_DIR }}
  40. - name: 'Apply workaround to fix networking in Linux'
  41. if: runner.os == 'Linux'
  42. run: |
  43. # https://github.com/actions/virtual-environments/issues/798
  44. sudo ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
  45. - name: 'Prepare environment'
  46. run: |
  47. echo "$(go env GOPATH)/bin" >> $GITHUB_PATH
  48. - name: 'Run tests and build all'
  49. working-directory: ${{ env.WORKING_DIR }}
  50. run: |
  51. make test all
  52. docker-build:
  53. name: 'Build Docker image'
  54. runs-on: ubuntu-20.04
  55. steps:
  56. - name: 'Check out project files'
  57. uses: actions/checkout@v2
  58. - name: 'Build docker image'
  59. id: build
  60. run: |
  61. output_dir=${{ runner.temp }}/docker
  62. mkdir -p $output_dir
  63. docker build -t quorumengineering/quorum:pr .
  64. docker save quorumengineering/quorum:pr > quorum-pr.tar
  65. tar cfvz $output_dir/quorum-pr.tar.gz quorum-pr.tar
  66. echo "::set-output name=output_dir::$output_dir"
  67. - name: 'Upload workflow artifact - Docker image'
  68. uses: actions/upload-artifact@v1
  69. with:
  70. name: docker-image
  71. path: ${{ steps.build.outputs.output_dir }}
  72. acceptance-tests-basic:
  73. name: Acceptance tests (${{ matrix.tag }})
  74. needs:
  75. - docker-build
  76. if: success()
  77. strategy:
  78. fail-fast: false
  79. matrix:
  80. # list of tag expression being executed in parallel
  81. # for PR, only selective tests are run.
  82. # More comprehensive suites are scheduled to run in master
  83. tag:
  84. - 'basic || basic-raft || (advanced && raft) || networks/typical::raft'
  85. - 'basic || basic-istanbul || (advanced && istanbul) || empty-block-period || networks/typical::istanbul'
  86. - 'basic || basic-istanbul || (advanced && istanbul) || empty-block-period || block-reward || networks/typical::qbft'
  87. - 'gcmode && block-sync && networks/template::raft-3plus1'
  88. - 'gcmode && block-sync && networks/template::istanbul-3plus1'
  89. - 'gcmode && block-sync && networks/template::qbft-3plus1'
  90. - 'learner-peer-management || raftdnsenable && networks/template::raft-3plus1'
  91. - 'validator-management && networks/template::qbft-3plus1'
  92. - 'validator-management && networks/template::istanbul-3plus1'
  93. - 'hybrid-validator-management-manage-besu && networks/typical-hybrid::hybrid-template-q2b1'
  94. - 'hybrid-validator-management-manage-quorum && networks/typical-hybrid::hybrid-template-q1b2'
  95. - 'qbft-transition-network && networks/template::qbft-4nodes-transition'
  96. - 'basic || basic-raft || (advanced && raft) || networks/plugins::raft'
  97. - 'basic || basic-istanbul || (advanced && istanbul) || networks/plugins::qbft'
  98. - 'basic || basic-istanbul || (advanced && istanbul) || networks/plugins::istanbul'
  99. - 'basic || basic-raft || (advanced && raft) || networks/plugins::raft-account-plugin-hashicorp-vault'
  100. - 'basic || basic-istanbul || (advanced && istanbul) || networks/plugins::qbft-account-plugin-hashicorp-vault'
  101. - 'basic || basic-istanbul || (advanced && istanbul) || networks/plugins::istanbul-account-plugin-hashicorp-vault'
  102. - 'basic-rpc-security || networks/plugins::raft-rpc-security'
  103. - 'basic-rpc-security || networks/plugins::qbft-rpc-security'
  104. - 'basic-rpc-security || networks/plugins::istanbul-rpc-security'
  105. - 'migration && networks/template::raft-4nodes'
  106. - 'migration && networks/template::istanbul-4nodes'
  107. - 'migration && networks/template::raft-4nodes-ancientdb'
  108. - 'migration && networks/template::istanbul-4nodes-ancientdb'
  109. - 'permissions-v1 && networks/template::raft-3plus1'
  110. - 'permissions-v2 && networks/template::raft-3plus1'
  111. - 'privacy-enhancements-upgrade || networks/template::raft-4nodes-pe'
  112. - 'privacy-enhancements-upgrade || networks/template::istanbul-4nodes-pe'
  113. - 'multitenancy && networks/plugins::raft-multitenancy'
  114. - 'basic || basic-raft || (advanced && raft) || networks/typical::raft-simple-mps'
  115. - 'basic || basic-istanbul || (advanced && istanbul) || networks/typical::qbft-simple-mps'
  116. - 'basic || basic-istanbul || (advanced && istanbul) || networks/typical::istanbul-simple-mps'
  117. - 'basic || networks/typical::raftmps'
  118. - 'basic || networks/typical::qbftmps'
  119. - 'basic || networks/typical::istanbulmps'
  120. - 'mps-upgrade-txtrace || networks/template::raft-4nodes-mps'
  121. - 'mps-upgrade-txtrace || networks/template::istanbul-4nodes-mps'
  122. - 'mps-mixed-network-psr-check || networks/template::raft-4nodes-mps-mixed'
  123. - 'mps-mixed-network-psr-check || networks/template::istanbul-4nodes-mps-mixed'
  124. - '(basic && !nosupport && !mps && !(spam && !raw) && !eth-api-signed && !privacy-enhancements-disabled && !graphql && !async && !extension && !storage-root && !personal-api-signed) || networks/typical-hybrid::hybrid'
  125. runs-on: ubuntu-20.04
  126. steps:
  127. - name: 'Download workflow artifact - Docker image'
  128. uses: actions/download-artifact@v1
  129. with:
  130. name: docker-image
  131. - name: 'Load Docker image'
  132. id: setup
  133. run: |
  134. tar xfvz docker-image/quorum-pr.tar.gz
  135. docker load --input quorum-pr.tar
  136. docker_env_file="${{ runner.temp }}/env.list"
  137. echo "TF_VAR_quorum_docker_image={ name = \"quorumengineering/quorum:pr\", local = true }" >> $docker_env_file
  138. echo "::set-output name=outputDir::${{ runner.temp }}"
  139. echo "::set-output name=dockerEnvFile::$docker_env_file"
  140. - name: 'Run acceptance tests'
  141. run: |
  142. cat ${{ steps.setup.outputs.dockerEnvFile }}
  143. docker run --rm \
  144. --network host \
  145. -v /var/run/docker.sock:/var/run/docker.sock \
  146. -v ${{ steps.setup.outputs.outputDir }}:${{ steps.setup.outputs.outputDir }} \
  147. --env-file ${{ steps.setup.outputs.dockerEnvFile }} \
  148. quorumengineering/acctests:latest test \
  149. -Pauto \
  150. -Dauto.outputDir=${{ steps.setup.outputs.outputDir }} \
  151. -Dtags="${{ matrix.tag }}"
  152. - name: 'Debug'
  153. run: |
  154. docker images
  155. docker ps -a
  156. acceptance-tests-extra:
  157. name: Acceptance tests (${{ matrix.tag }})
  158. needs:
  159. - docker-build
  160. if: success()
  161. strategy:
  162. fail-fast: false
  163. matrix:
  164. # list of tag expression being executed in parallel
  165. include:
  166. # privacy enhancements tests
  167. - tag: '(basic && !privacy-enhancements-disabled) || privacy-enhancements || mandatory-recipients || basic-raft || (advanced && raft) || networks/typical::raft'
  168. privacy-enhancements: true
  169. privacy-precompile: false
  170. privacy-marker-transactions: false
  171. - tag: '(basic && !privacy-enhancements-disabled) || privacy-enhancements || mandatory-recipients || basic-istanbul || (advanced && istanbul) || networks/typical::istanbul'
  172. privacy-enhancements: true
  173. privacy-precompile: false
  174. privacy-marker-transactions: false
  175. # privacy precompile/privacy marker transaction tests
  176. - tag: 'basic || basic-raft || (advanced && raft) || networks/typical::raft'
  177. privacy-enhancements: false
  178. privacy-precompile: true
  179. privacy-marker-transactions: false
  180. - tag: 'basic || basic-istanbul || (advanced && istanbul) || networks/typical::istanbul'
  181. privacy-enhancements: false
  182. privacy-precompile: true
  183. privacy-marker-transactions: false
  184. - tag: 'basic || basic-istanbul || (advanced && istanbul) || networks/typical::qbft'
  185. privacy-enhancements: false
  186. privacy-precompile: true
  187. privacy-marker-transactions: false
  188. - tag: '(multitenancy || privacy-precompile-enabled) && networks/plugins::raft-multitenancy'
  189. privacy-enhancements: false
  190. privacy-precompile: true
  191. privacy-marker-transactions: true
  192. - tag: '(basic && !privacy-precompile-disabled) || basic-raft || (advanced && raft) || networks/typical::raft-simple-mps'
  193. privacy-enhancements: false
  194. privacy-precompile: true
  195. privacy-marker-transactions: true
  196. - tag: '(basic && !privacy-precompile-disabled) || basic-istanbul || (advanced && istanbul) || networks/typical::istanbul-simple-mps'
  197. privacy-enhancements: false
  198. privacy-precompile: true
  199. privacy-marker-transactions: true
  200. - tag: '(basic && !privacy-precompile-disabled) || basic-istanbul || (advanced && istanbul) || networks/typical::qbft-simple-mps'
  201. privacy-enhancements: false
  202. privacy-precompile: true
  203. privacy-marker-transactions: true
  204. - tag: '(basic && !privacy-precompile-disabled) || networks/typical::raftmps'
  205. privacy-enhancements: false
  206. privacy-precompile: true
  207. privacy-marker-transactions: true
  208. - tag: '(basic && !privacy-precompile-disabled) || networks/typical::istanbulmps'
  209. privacy-enhancements: false
  210. privacy-precompile: true
  211. privacy-marker-transactions: true
  212. - tag: '(basic && !privacy-precompile-disabled) || networks/typical::qbftmps'
  213. privacy-enhancements: false
  214. privacy-precompile: true
  215. privacy-marker-transactions: true
  216. # privacy enhancements + privacy precompile/privacy marker transaction tests
  217. - tag: '(basic && !privacy-enhancements-disabled && !privacy-precompile-disabled) || privacy-enhancements || mandatory-recipients || privacy-precompile-enabled || basic-raft || (advanced && raft) || networks/typical::raft'
  218. privacy-enhancements: true
  219. privacy-precompile: true
  220. privacy-marker-transactions: true
  221. - tag: '(basic && !privacy-enhancements-disabled && !privacy-precompile-disabled) || privacy-enhancements || mandatory-recipients || privacy-precompile-enabled || basic-istanbul || (advanced && istanbul) || networks/typical::istanbul'
  222. privacy-enhancements: true
  223. privacy-precompile: true
  224. privacy-marker-transactions: true
  225. - tag: '(basic && !privacy-enhancements-disabled && !privacy-precompile-disabled) || privacy-enhancements || mandatory-recipients || privacy-precompile-enabled || basic-istanbul || (advanced && istanbul) || networks/typical::qbft'
  226. privacy-enhancements: true
  227. privacy-precompile: true
  228. privacy-marker-transactions: true
  229. - tag: 'privacy-precompile-compatibility && networks/template::raft-4nodes'
  230. privacy-enhancements: false
  231. privacy-precompile: true
  232. privacy-marker-transactions: false # do not enable pmts as the test will do this on the necessary nodes
  233. - tag: 'privacy-precompile-compatibility && networks/template::istanbul-4nodes'
  234. privacy-enhancements: false
  235. privacy-precompile: true
  236. privacy-marker-transactions: false # do not enable pmts as the test will do this on the necessary nodes
  237. runs-on: ubuntu-20.04
  238. steps:
  239. - name: 'Download workflow artifact - Docker image'
  240. uses: actions/download-artifact@v1
  241. with:
  242. name: docker-image
  243. - name: 'Load Docker image'
  244. id: setup
  245. run: |
  246. tar xfvz docker-image/quorum-pr.tar.gz
  247. docker load --input quorum-pr.tar
  248. docker_env_file="${{ runner.temp }}/env.list"
  249. echo "TF_VAR_quorum_docker_image={ name = \"quorumengineering/quorum:pr\", local = true }" >> $docker_env_file
  250. echo "TF_VAR_privacy_enhancements={block=0, enabled=${{ matrix.privacy-enhancements}}}" >> $docker_env_file
  251. echo "TF_VAR_privacy_precompile={block=0, enabled=${{ matrix.privacy-precompile}}}" >> $docker_env_file
  252. echo "TF_VAR_privacy_marker_transactions=${{ matrix.privacy-marker-transactions}}" >> $docker_env_file
  253. echo "::set-output name=outputDir::${{ runner.temp }}"
  254. echo "::set-output name=dockerEnvFile::$docker_env_file"
  255. - name: 'Run extra acceptance tests'
  256. run: |
  257. cat ${{ steps.setup.outputs.dockerEnvFile }}
  258. docker run --rm \
  259. --network host \
  260. -v /var/run/docker.sock:/var/run/docker.sock \
  261. -v ${{ steps.setup.outputs.outputDir }}:${{ steps.setup.outputs.outputDir }} \
  262. --env-file ${{ steps.setup.outputs.dockerEnvFile }} \
  263. quorumengineering/acctests:latest test \
  264. -Pauto \
  265. -Dauto.outputDir=${{ steps.setup.outputs.outputDir }} \
  266. -Dtags="${{ matrix.tag }}"
  267. - name: 'Debug'
  268. run: |
  269. docker images
  270. docker ps -a
  271. peeps-tests:
  272. name: Run PEEPS tests
  273. needs:
  274. - docker-build
  275. runs-on: ubuntu-20.04
  276. steps:
  277. - name: 'Checkout'
  278. uses: actions/checkout@v2
  279. - name: 'Download workflow artifact - Docker image'
  280. uses: actions/download-artifact@v1
  281. with:
  282. name: docker-image
  283. - name: 'Load Docker image'
  284. id: setup
  285. run: |
  286. tar xfvz docker-image/quorum-pr.tar.gz
  287. docker load --input quorum-pr.tar
  288. docker image tag quorumengineering/quorum:pr quorumengineering/quorum:develop
  289. docker image ls
  290. - name: Set up Java
  291. uses: actions/setup-java@v2
  292. with:
  293. distribution: 'adopt'
  294. java-version: 11
  295. check-latest: true
  296. - name: PEEPS
  297. run: |
  298. cd build
  299. ./run-peeps.sh
  300. - name: PEEPS Test Report
  301. uses: mikepenz/action-junit-report@v2
  302. if: always()
  303. with:
  304. report_paths: '**/build/test-results/*/TEST-*.xml'
  305. check_name: PEEPS test report
  306. publish-docker:
  307. name: Publish Docker Image
  308. needs:
  309. - build
  310. - acceptance-tests-basic
  311. - acceptance-tests-extra
  312. runs-on: ubuntu-20.04
  313. steps:
  314. - name: 'Checkout'
  315. uses: actions/checkout@v2
  316. - name: 'Build and publish to Docker Hub'
  317. uses: docker/build-push-action@v1
  318. with:
  319. username: ${{ secrets.DOCKER_USERNAME }}
  320. password: ${{ secrets.DOCKER_ACCESS_TOKEN }}
  321. repository: ${{ secrets.DOCKER_REPO }}
  322. tags: develop
  323. add_git_labels: true
  324. notify:
  325. if: always()
  326. name: Notify
  327. needs:
  328. - build
  329. - publish-docker
  330. runs-on: ubuntu-20.04
  331. steps:
  332. - name: 'Setup metadata'
  333. id: setup
  334. run: |
  335. gitref_path="${{ github.ref }}"
  336. gitref_path=${gitref_path/refs\/heads/tree} # for refs/heads/my-branch
  337. gitref_path=${gitref_path/refs\/tags/tree} # for refs/tags/v1.0.0
  338. gitref_path=${gitref_path#refs\/} # for refs/pull/123/merge
  339. gitref_path=${gitref_path%/merge} # for refs/pull/123/merge
  340. echo "::set-output name=gitref-path::$gitref_path"
  341. - name: 'Prepare Slack message with full info'
  342. id: status
  343. uses: actions/github-script@0.8.0
  344. with:
  345. script: |
  346. var gitref_path = "${{ steps.setup.outputs.gitref-path }}"
  347. ////////////////////////////////////
  348. // retrieve workflow run data
  349. ////////////////////////////////////
  350. console.log("get workflow run")
  351. const wf_run = await github.actions.getWorkflowRun({
  352. owner: context.repo.owner,
  353. repo: context.repo.repo,
  354. run_id: ${{ github.run_id }}
  355. })
  356. console.log(wf_run.data)
  357. console.log("get jobs for workflow run:", wf_run.data.jobs_url)
  358. const jobs_response = await github.request(wf_run.data.jobs_url)
  359. ////////////////////////////////////
  360. // build slack notification message
  361. ////////////////////////////////////
  362. // some utility functions
  363. var date_diff_func = function(start, end) {
  364. var duration = end - start
  365. // format the duration
  366. var delta = duration / 1000
  367. var days = Math.floor(delta / 86400)
  368. delta -= days * 86400
  369. var hours = Math.floor(delta / 3600) % 24
  370. delta -= hours * 3600
  371. var minutes = Math.floor(delta / 60) % 60
  372. delta -= minutes * 60
  373. var seconds = Math.floor(delta % 60)
  374. var format_func = function(v, text, check) {
  375. if (v <= 0 && check) {
  376. return ""
  377. } else {
  378. return v + text
  379. }
  380. }
  381. return format_func(days, "d", true) + format_func(hours, "h", true) + format_func(minutes, "m", true) + format_func(seconds, "s", false)
  382. }
  383. var status_icon_func = function(s) {
  384. switch (s) {
  385. case "w_success":
  386. return ":white_check_mark:"
  387. case "w_failure":
  388. return ":no_entry:"
  389. case "w_cancelled":
  390. return ":warning:"
  391. case "success":
  392. return "\u2713"
  393. case "failure":
  394. return "\u2717"
  395. default:
  396. return "\u20e0"
  397. }
  398. }
  399. // build the message
  400. var job_blocks = []
  401. var is_wf_success = true
  402. var is_wf_failure = false
  403. for (j of jobs_response.data.jobs) {
  404. console.log(j.name, ":", j.status, j.conclusion, j.started_at, j.completed_at)
  405. // ignore the current job running this script
  406. if (j.status != "completed") {
  407. continue
  408. }
  409. if (j.conclusion != "success") {
  410. is_wf_success = false
  411. }
  412. if (j.conclusion == "failure") {
  413. is_wf_failure = true
  414. }
  415. job_blocks.push({
  416. type: "section",
  417. text: {
  418. type: "mrkdwn",
  419. text: `${status_icon_func(j.conclusion)} <${j.html_url}|${j.name}> took ${date_diff_func(new Date(j.started_at), new Date(j.completed_at))}`
  420. }
  421. })
  422. }
  423. var workflow_status = "w_cancelled"
  424. if (is_wf_success) {
  425. workflow_status = "w_success"
  426. } else if (is_wf_failure) {
  427. workflow_status = "w_failure"
  428. }
  429. var context_elements = [
  430. {
  431. "type": "mrkdwn",
  432. "text": "*Repo:* <https://github.com/${{ github.repository }}|${{ github.repository }}>"
  433. },
  434. {
  435. "type": "mrkdwn",
  436. "text": `*Branch:* <https://github.com/${{ github.repository }}/${gitref_path}|${{ github.ref }}>`
  437. },
  438. {
  439. "type": "mrkdwn",
  440. "text": `*Event:* ${wf_run.data.event}`
  441. },
  442. {
  443. "type": "mrkdwn",
  444. "text": `*Commit:* <https://github.com/${{ github.repository }}/commit/${wf_run.data.head_commit.id}|${wf_run.data.head_commit.id.substr(0, 8)}>`
  445. },
  446. {
  447. "type": "mrkdwn",
  448. "text": `*Author:* ${wf_run.data.head_commit.author.name}`
  449. }
  450. ]
  451. var header_blocks = [
  452. {
  453. type: "section",
  454. text: {
  455. type: "mrkdwn",
  456. text: `${status_icon_func(workflow_status)} *${{ github.workflow }}* <${wf_run.data.html_url}|#${{ github.run_number }}> took ${date_diff_func(new Date(wf_run.data.created_at), new Date(wf_run.data.updated_at))}`
  457. }
  458. },
  459. {
  460. type: "context",
  461. elements: context_elements,
  462. },
  463. {
  464. type: "divider"
  465. }
  466. ]
  467. var slack_msg = {
  468. blocks: [].concat(header_blocks, job_blocks)
  469. }
  470. return slack_msg
  471. - name: 'Prepare Slack message with partial info'
  472. id: short_status
  473. if: failure()
  474. uses: actions/github-script@0.8.0
  475. with:
  476. script: |
  477. ////////////////////////////////////
  478. // retrieve workflow run data
  479. ////////////////////////////////////
  480. const wf_run = await github.actions.getWorkflowRun({
  481. owner: context.repo.owner,
  482. repo: context.repo.repo,
  483. run_id: ${{ github.run_id }}
  484. })
  485. var date_diff_func = function(start, end) {
  486. var duration = end - start
  487. // format the duration
  488. var delta = duration / 1000
  489. var days = Math.floor(delta / 86400)
  490. delta -= days * 86400
  491. var hours = Math.floor(delta / 3600) % 24
  492. delta -= hours * 3600
  493. var minutes = Math.floor(delta / 60) % 60
  494. delta -= minutes * 60
  495. var seconds = Math.floor(delta % 60)
  496. var format_func = function(v, text, check) {
  497. if (v <= 0 && check) {
  498. return ""
  499. } else {
  500. return v + text
  501. }
  502. }
  503. return format_func(days, "d", true) + format_func(hours, "h", true) + format_func(minutes, "m", true) + format_func(seconds, "s", false)
  504. }
  505. var slack_msg = {
  506. blocks: [
  507. {
  508. type: "section",
  509. text: {
  510. type: "mrkdwn",
  511. text: `:skull_and_crossbones: *${{ github.workflow }}* <${wf_run.data.html_url}|#${{ github.run_number }}> (took ${date_diff_func(new Date(wf_run.data.created_at), new Date(wf_run.data.updated_at))})`
  512. }
  513. }
  514. ]
  515. }
  516. return slack_msg
  517. - name: 'Send to Slack'
  518. if: always()
  519. run: |
  520. cat <<JSON > long_message.json
  521. ${{ steps.status.outputs.result }}
  522. JSON
  523. cat <<JSON > short_message.json
  524. ${{ steps.short_status.outputs.result }}
  525. JSON
  526. _post() {
  527. curl -X POST ${{ secrets.SLACK_WEBHOOK_URL }} -H "Content-type: application/json" --data "@${1}"
  528. }
  529. _post "long_message.json" || _post "short_message.json"