ЁЯУО рдзрдбрд╛ 05 тАФ Artifacts рдЖрдгрд┐ test reports: рдбреЗрд╕реНрдХрд╛рдВрдордзреНрдпреЗ рдХрд╛рдп рдкреНрд░рд╡рд╛рд╕ рдХрд░рддреЗ
ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 12 рдкреИрдХреА рдзрдбрд╛ 05 ┬╖ рдорд╛рдЧреЗ: lesson-04-cache-parallel-matrix ┬╖ рдкреБрдвреЗ: lesson-06-secrets-oidc
ЁЯУж рдпрд╛ рдмреНрд░рдБрдЪрдордзреНрдпреЗ рдХрд╛рдп рдЖрд╣реЗ
рдзрдбреЗ 01тАУ04, рдЖрдгрд┐ рдбреЗрд╕реНрдХ рджреБрд╕рд▒реНрдпрд╛ рдХреЛрдгрд╛рд▓рд╛ рджреЗрдК рд╢рдХрддреЗ рдЕрд╢рд╛ рджреЛрди рдЧреЛрд╖реНрдЯреА: рдорд╛рдгреВрд╕ рд╡рд╛рдЪрддреЛ рддреЛ test report рдЖрдгрд┐ рдирдВрддрд░рдЪреНрдпрд╛ job рд▓рд╛ рд▓рд╛рдЧрдгрд╛рд░реЗ artifact. рдЦрд▒реНрдпрд╛ files:
- .github/workflows/ci.yml тАФ
ЁЯУО upload the report cardstep:if: always(),retention-days: 7 - .github/workflows/ship.yml тАФ
buildjobimage.tar.gzрдЬрдкреВрди рдареЗрд╡рддреЛ;pushjob рддреА рджреБрд╕рд▒реНрдпрд╛ рдорд╢реАрдирд╡рд░ download рдХрд░рддреЛ - app/package.json тАФ
npm run test:ciрдкреНрд░рдЧрддрд┐рдкреБрд╕реНрддрдХ рдЬреНрдпрд╛рдкрд╛рд╕реВрди рдмрдирддреЗ рддреЗ JUnit XML рд▓рд┐рд╣рд┐рддреЗ - .circleci/config.yml, .gitlab-ci.yml, Jenkinsfile тАФ рддреЗрдЪ рдкреНрд░рдЧрддрд┐рдкреБрд╕реНрддрдХ рдЗрддрд░ рддреАрди рдмреЛрд▓реАрдВрдордзреНрдпреЗ
ЁЯзТ 5 рд╡рд░реНрд╖рд╛рдВрдЪреНрдпрд╛ рдореБрд▓рд╛рд▓рд╛ рд╕рдордЬрд╛рд╡рд▓реНрдпрд╛рд╕рд╛рд░рдЦреЗ
рддрдкрд╛рд╕рдгреА рдбреЗрд╕реНрдХрдиреЗ тЬЕ рддреБрдордЪрд╛ рдЧреГрд╣рдкрд╛рда рддрдкрд╛рд╕реВрди рд╕рдВрдкрд╡рд▓рд╛. рддреНрдпрд╛ рдбреЗрд╕реНрдХрд╡рд░реВрди рджреЛрди рдЧреЛрд╖реНрдЯреА рдмрд╛рд╣реЗрд░ рдкрдбрддрд╛рдд.
рдкрд╣рд┐рд▓реА, рдкреНрд░рдЧрддрд┐рдкреБрд╕реНрддрдХ ЁЯУЛ: "3 рддрдкрд╛рд╕рдгреНрдпрд╛, 3 рдкрд╛рд╕". рддреЗ рдЕрд╢рд╛ рдард┐рдХрд╛рдгреА рд▓рд╛рд╡рд▓реЗ рдЬрд╛рддреЗ рдЬрд┐рдереЗ рдХреЛрдгреАрд╣реА рд╡рд╛рдЪреВ рд╢рдХреЗрд▓ тАФ рд╢рд┐рдХреНрд╖рд┐рдХрд╛, рддреБрдордЪреЗ рдкрд╛рд▓рдХ, рдкреБрдврдЪреНрдпрд╛ рдордВрдЧрд│рд╡рд╛рд░реА рдХреЛрдгрддреА рддрдкрд╛рд╕рдгреА рдмрд┐рдШрдбрд▓реА рдпрд╛рдЪрд╛ рд╡рд┐рдЪрд╛рд░ рдХрд░рдгрд╛рд░реЗ рддреБрдореНрд╣реА. CI рдордзреНрдпреЗ рддреА JUnit XML file рдЕрд╕рддреЗ. CircleCI, GitLab рдЖрдгрд┐ Jenkins рддреА рд╡рд╛рдЪреВрди рдкреНрд░рддреНрдпреЗрдХ test рд╕рд╛рдареА рдПрдХ рдУрд│ рдЕрд╕рд▓реЗрд▓реЗ table рдмрдирд╡рддрд╛рдд; GitHub Actions рддреА download рдореНрд╣рдгреВрди рдареЗрд╡рддреЗ рдЬреА рддреБрдореНрд╣реА рд╕реНрд╡рддрдГ рдЙрдШрдбрддрд╛.
рджреБрд╕рд░реА, рдкрд╛рдХреАрдЯ ЁЯУО: рдлреЛрдЯреЛрдХреЙрдкреА рдбреЗрд╕реНрдХ ЁЯН▒ рддреБрдордЪреНрдпрд╛ рдЧреГрд╣рдкрд╛рдард╛рдЪреА рдкреНрд░рдд рдХрд╛рдврддреЛ рдЖрдгрд┐ рддреА delivery рдбреЗрд╕реНрдХрдХрдбреЗ рджреНрдпрд╛рдпрдЪреА рдЕрд╕рддреЗ. рдкрдг рддреЛ рдбреЗрд╕реНрдХ рд╡реЗрдЧрд│реНрдпрд╛ рдЦреЛрд▓реАрдд рдЖрд╣реЗ тАФ CI рдордзреНрдпреЗ рдкреНрд░рддреНрдпреЗрдХ job рдирд╡реНрдпрд╛ рдорд╢реАрдирд╡рд░ рдЙрддрд░рддреЛ, рдореНрд╣рдгреВрди рддреБрдореНрд╣реА рдмрдирд╡рд▓реЗрд▓реЗ рд╕рдЧрд│реЗ job рд╕рдВрдкрддрд╛рдХреНрд╖рдгреА рдирд╛рд╣реАрд╕реЗ рд╣реЛрддреЗ. рддреБрдореНрд╣реА рддреЗ рдкрд╛рдХрд┐рдЯрд╛рдд рдареЗрд╡рддрд╛, рддреНрдпрд╛рд╡рд░ рдирд╛рд╡ рд▓рд┐рд╣рд┐рддрд╛, рдЖрдгрд┐ run рдЪреНрдпрд╛ рдХрдкреНрдкреНрдпрд╛рдд рдЯрд╛рдХрддрд╛. рдкреБрдврдЪрд╛ рдбреЗрд╕реНрдХ рддреЗ рдирд╛рд╡рд╛рдиреЗ рдЙрдЪрд▓рддреЛ. рддреЗ рдкрд╛рдХреАрдЯ рдореНрд╣рдгрдЬреЗ artifact.
рдЖрдгрд┐ рдзрдбрд╛ 04 рдордзрд▓рд╛ рддрд╛рд╕рд▓реЗрд▓реНрдпрд╛ рдкреЗрдиреНрд╕рд┐рд▓реАрдВрдЪрд╛ рдбреНрд░реЙрд╡рд░ ЁЯЧДя╕П? рддреЛ рдореНрд╣рдгрдЬреЗ cache. рд╢рд┐рдкрд╛рдпрд╛рдиреЗ рдбреНрд░реЙрд╡рд░ рд░рд┐рдХрд╛рдорд╛ рдХреЗрд▓рд╛ рддрд░ рдХреЛрдгрд╛рд▓рд╛рдЪ рддреНрдпрд╛рдЪреА рдЙрдгреАрд╡ рднрд╛рд╕рдгрд╛рд░ рдирд╛рд╣реА тАФ рддреБрдореНрд╣реА рдлрдХреНрдд рдкреБрдиреНрд╣рд╛ рддрд╛рд╕рд╛рд▓. рдкрд╛рдХреАрдЯ рд╣рд░рд╡рдгреЗ рдореНрд╣рдгрдЬреЗ deliverable рд╣рд░рд╡рдгреЗ. рддреАрдЪ рдлрд│реА, рдЕрдЧрджреА рд╡реЗрдЧрд│реЗ рдирд┐рдпрдо.
ЁЯЧ║я╕П рдЖрдХреГрддреА
flowchart LR
t["тЬЕ test job<br/>node --test тЖТ test-results.xml"]
rc["ЁЯУЛ report card<br/>artifact test-results-node22"]
human["ЁЯзСтАНЁЯПл a human downloads it<br/>gh run download"]
b["ЁЯН▒ build job<br/>docker save тЖТ image.tar.gz"]
env["ЁЯУО envelope<br/>artifact image"]
p["ЁЯЪЪ push job<br/>another machine, docker load"]
t -->|"1 upload, even on failure"| rc
rc -->|"2 read later"| human
b -->|"3 upload"| env
env -->|"4 download by name"| p
тЭУ рдХрд╛рдп
- Artifact = рдпрд╛ run рдЪрд╛ output рдЕрд╕рд▓реЗрд▓реА file (рдХрд┐рдВрд╡рд╛ folder), рдЬреА CI system рдареЗрд╡рддреЗ рдореНрд╣рдгрдЬреЗ рдорд╛рдгреВрд╕ рдХрд┐рдВрд╡рд╛ рдирдВрддрд░рдЪрд╛ job рддреА рдЖрдгреВ рд╢рдХреЗрд▓. рдирд╛рд╡ рдЕрд╕рд▓реЗрд▓реА, рдПрдХрд╛ run рд╢реА рдмрд╛рдВрдзрд▓реЗрд▓реА, рдард░рд╛рд╡реАрдХ рджрд┐рд╡рд╕ рдареЗрд╡рд▓реЗрд▓реА.
- Cache = рдкреБрдврдЪрд╛ run рдкреБрдиреНрд╣рд╛ рдмрдирд╡реВ рд╢рдХреЗрд▓ рдЕрд╢рд╛ рдЧреЛрд╖реНрдЯреАрдЪреА copy, рдлрдХреНрдд рд╡реЗрд│ рд╡рд╛рдЪрд╡рдгреНрдпрд╛рд╕рд╛рдареА рдареЗрд╡рд▓реЗрд▓реА. рддрд┐рдЪреНрдпрд╛ inputs рдЪреНрдпрд╛ hash рд╡рд░реВрди key; рдХреЛрдгрддреНрдпрд╛рд╣реА рдХреНрд╖рдгреА рдХрд╛рдвреВрди рдЯрд╛рдХрд▓реА рдЬрд╛рдК рд╢рдХрддреЗ.
- Test report = test run рдЪрд╛ machine рд▓рд╛ рд╡рд╛рдЪрддрд╛ рдпреЗрдгрд╛рд░рд╛ рд╕рд╛рд░рд╛рдВрд╢. JUnit XML рд╣рд╛ рд╕рд╛рдорд╛рдиреНрдп format рдЖрд╣реЗ тАФ рддреЛ Java рдЬрдЧрд╛рдд рд╕реБрд░реВ рдЭрд╛рд▓рд╛ рдЖрдгрд┐ рдпрд╛ рдХреЛрд░реНрд╕рдордзрд▓реА CI tools рддреЛ рд╕рдордЬрддрд╛рдд.
- Retention = artifact рдХрд┐рддреА рдХрд╛рд│ рд░рд╛рд╣рддреЗ. рдкреНрд░рдЧрддрд┐рдкреБрд╕реНрддрдХрд╛рд╕рд╛рдареА
retention-days: 7, image рдЪреНрдпрд╛ рдкрд╛рдХрд┐рдЯрд╛рд╕рд╛рдареАretention-days: 1. - Jobs рджрд░рдореНрдпрд╛рди = рдПрдХрд╛ run рдЪреЗ jobs рд╕рд╣рд╕рд╛ рд╡реЗрдЧрд╡реЗрдЧрд│реНрдпрд╛ runners рд╡рд░ рдЙрддрд░рддрд╛рдд, рдореНрд╣рдгреВрди job A рдХрдбреВрди job B рдХрдбреЗ file рджреЗрдгреНрдпрд╛рдЪрд╛ рднрд░рд╡рд╢рд╛рдЪрд╛ рдорд╛рд░реНрдЧ рдореНрд╣рдгрдЬреЗ A рдордзреНрдпреЗ upload, B рдордзреНрдпреЗ download.
ЁЯза рдкрд╛рдХреАрдЯ рд╡рд┐рд░реБрджреНрдз рдбреНрд░реЙрд╡рд░
| ЁЯУО artifact | ЁЯЧДя╕П cache | |
|---|---|---|
| рддреЗ рдХрд╛рдп рдЖрд╣реЗ | рдпрд╛ run рдЪрд╛ output | рдирдВрддрд░рдЪреНрдпрд╛ runs рд╕рд╛рдареА рд╡реЗрдЧ рд╡рд╛рдврд╡рдгрд╛рд░реЗ |
| рддреЗ рдХреЛрдг рд╡рд╛рдЪрддреЗ | рдорд╛рдгрд╕реЗ, рдирдВрддрд░рдЪреЗ jobs, рдЗрддрд░ workflows | рддреАрдЪ step, рдкреБрдврдЪреНрдпрд╛ рд╡реЗрд│реА |
| рддреЗ рдирд╛рд╣реАрд╕реЗ рдЭрд╛рд▓реЗ рддрд░ | deliverable рд╣рд░рд╡рддреЗ тАФ рдПрдХ bug | step рдлрдХреНрдд рд╕рд╛рд╡рдХрд╛рд╢ рдЪрд╛рд▓рддреЗ |
| рдУрд│рдЦ рдХрд╢рд╛рд╡рд░реВрди | рдПрдХрд╛ run рдордзрд▓реЗ рдирд╛рд╡ | inputs рд╡рд░реВрди hash рдХреЗрд▓реЗрд▓реА key |
ЁЯдФ рдХрд╛
рдкреНрд░рдЧрддрд┐рдкреБрд╕реНрддрдХрд╛рд╢рд┐рд╡рд╛рдп рд▓рд╛рд▓ run рдореНрд╣рдгрдЬреЗ log рдЪреНрдпрд╛ рдордЬрдХреБрд░рд╛рдЪреА рднрд┐рдВрдд, рдЖрдгрд┐ "рдХреЛрдгрддреА test?" рдпрд╛рдЪреЗ рдЙрддреНрддрд░ рдореНрд╣рдгрдЬреЗ scroll рдХрд░рдд рд░рд╛рд╣рдгреЗ. Artifact рд╢рд┐рд╡рд╛рдп push job рд▓рд╛ image рдкреБрдиреНрд╣рд╛ build рдХрд░рд╛рд╡реА рд▓рд╛рдЧрддреЗ тАФ рдЖрдгрд┐ рдордЧ рддреБрдореНрд╣реА push рдХрд░рддрд╛ рддреЛ рдбрдмрд╛ рддреБрдореНрд╣реА smoke-test рдХреЗрд▓реЗрд▓рд╛ рдбрдмрд╛ рдирд╕рддреЛ. Reports failures рд╡рд╛рдЪрдиреАрдп рдХрд░рддрд╛рдд; artifacts рд╣рд╕реНрддрд╛рдВрддрд░рдг рдкреНрд░рд╛рдорд╛рдгрд┐рдХ рдареЗрд╡рддрд╛рдд. Output рд╡рд┐рд░реБрджреНрдз рд╡реЗрдЧ рд╡рд╛рдврд╡рдгрд╛рд░реЗ рд╣реА рд╣реАрдЪ рд░реЗрд╖рд╛ Docker рд╢рд╛рд│реЗрдЪреНрдпрд╛ рдзрдбрд╛ 02 рдордзрд▓реНрдпрд╛ Docker layer cache рдордзреВрдирд╣реА рдЬрд╛рддреЗ: cache рд╕реНрд╡рд╛рдЧрддрд╛рд░реНрд╣ рдЖрд╣реЗ, рдкрдг рдкреБрдврдЪреЗ рдХрд╛рд╣реАрд╣реА рддреЛ рдЕрд╕рдгреНрдпрд╛рд╡рд░ рдЕрд╡рд▓рдВрдмреВрди рдЕрд╕реВ рдирдпреЗ.
ЁЯФз рдХрд╕реЗ (рдпрд╛ repo рдордзреНрдпреЗ)
рдкреНрд░рдЧрддрд┐рдкреБрд╕реНрддрдХ. Node рдЪрд╛ test runner рдПрдХрд╛рдЪ рд╡реЗрд│реА рджреЛрди reporters рд▓рд┐рд╣реВ рд╢рдХрддреЛ тАФ
рддреБрдордЪреНрдпрд╛ terminal рд╡рд░ рдорд╛рдгрд╕рд╛рд▓рд╛ рд╕реЛрдкрд╛ spec рдЖрдгрд┐ file рдордзреНрдпреЗ junit.
app/package.json рдордзреВрди:
"test:ci": "node --test --test-reporter=spec --test-reporter-destination=stdout --test-reporter=junit --test-reporter-destination=test-results.xml"
ci.yml рддреАрдЪ command рдЪрд╛рд▓рд╡рддреЗ, рдордЧ file upload рдХрд░рддреЗ тАФ tests fail рдЭрд╛рд▓реНрдпрд╛ рддрд░реАрд╣реА, рдЖрдгрд┐ рдиреЗрдордХреЗ рддреЗрд╡реНрд╣рд╛рдЪ рддреБрдореНрд╣рд╛рд▓рд╛ рддреА рд╣рд╡реА рдЕрд╕рддреЗ:
- name: ЁЯзк test
run: >
node --test
--test-reporter=spec --test-reporter-destination=stdout
--test-reporter=junit --test-reporter-destination=test-results.xml
- name: ЁЯУО upload the report card (lesson 05)
if: always() # especially when tests FAIL тАФ that's when you need the report
uses: actions/upload-artifact@v4
with:
name: test-results-node${{ matrix.node }}
path: app/test-results.xml
retention-days: 7
рджреЛрди рддрдкрд╢реАрд▓ рдерд╛рдВрдмреВрди рдкрд╛рд╣рдгреНрдпрд╛рд╕рд╛рд░рдЦреЗ. if: always() рдирд╕реЗрд▓ рддрд░ fail рд╣реЛрдгрд╛рд░реА test step job
рдерд╛рдВрдмрд╡рддреЗ рдЖрдгрд┐ upload рд╡рдЧрд│рд▓рд╛ рдЬрд╛рддреЛ тАФ report рдлрдХреНрдд рд╣рд┐рд░рд╡реНрдпрд╛ runs рд╕рд╛рдареАрдЪ рдЕрд╕реЗрд▓. рдЖрдгрд┐ artifact
рдЪреНрдпрд╛ рдирд╛рд╡рд╛рдд Node version рдЖрд╣реЗ рдХрд╛рд░рдг matrix рдЪреЗ рддреАрдирд╣реА рднрд╛рдЧ рдкреНрд░рддреНрдпреЗрдХреА рдПрдХ рдмрдирд╡рддрд╛рдд;
upload-artifact@v4 рдордзреНрдпреЗ рдПрдХ artifact рдирд╛рд╡ рдПрдХрд╛ run рдордзреНрдпреЗ рдПрдХрджрд╛рдЪ рд╡рд╛рдкрд░рддрд╛ рдпреЗрддреЗ, рдореНрд╣рдгреВрди
рд╕рд╛рдорд╛рдпрд┐рдХ рдирд╛рд╡ рдЕрд╕реЗрд▓ рддрд░ рджреБрд╕рд▒реНрдпрд╛ рдлреВрдЯрдкрдЯреНрдЯреАрдЪрд╛ upload fail рд╣реЛрдИрд▓.
рдбреЗрд╕реНрдХрд╛рдВрдордзрд▓реЗ рдкрд╛рдХреАрдЯ. ship.yml рдордзреНрдпреЗ
build job рдиреБрдХрддреАрдЪ smoke-test рдХреЗрд▓реЗрд▓реА image рдмрд╛рдВрдзрддреЛ, рдЖрдгрд┐ push job тАФ
рд╡реЗрдЧрд│реА рдорд╢реАрди тАФ рддреЗрдЪ bytes рдЙрдШрдбрддреЛ:
- name: ЁЯТ╛ keep the image for the push job (same run, different machine)
run: docker save hello-courier:${GITHUB_SHA} | gzip > image.tar.gz
- uses: actions/upload-artifact@v4
with: { name: image, path: image.tar.gz, retention-days: 1 }
steps:
- uses: actions/download-artifact@v4
with: { name: image }
- run: docker load < image.tar.gz
рдПрдХрд╛ рджрд┐рд╡рд╕рд╛рдЪреЗ retention рдкреБрд░реЗрд╕реЗ рдЖрд╣реЗ: push рдХрд╛рд╣реА рдорд┐рдирд┐рдЯрд╛рдВрдиреАрдЪ рд╣реЛрддреЛ, рдЖрдгрд┐ image рдЪреЗ
рджреАрд░реНрдШрдХрд╛рд▓реАрди рдШрд░ ECR рдЖрд╣реЗ, artifact store рдирд╛рд╣реА (рдзрдбрд╛ 07). retention-days рдирд╕реЗрд▓ рддрд░
GitHub artifacts repository рдЪреНрдпрд╛ default рдиреБрд╕рд╛рд░ рдареЗрд╡рддреЛ тАФ Settings тЖТ Actions рдордзреНрдпреЗ
рдХреЛрдгреА рдмрджрд▓рд▓реЗ рдирд╕реЗрд▓ рддрд░ 90 рджрд┐рд╡рд╕.
ЁЯФБ рд╣реЗрдЪ CircleCI рдордзреНрдпреЗ
- run:
name: ЁЯзк test
command: |
mkdir -p test-results
node --test --test-reporter=spec --test-reporter-destination=stdout \
--test-reporter=junit --test-reporter-destination=test-results/junit.xml
- store_test_results: # lesson 05: the report card, parsed
path: test-results
- store_artifacts: # тАжand the raw file, downloadable
path: test-results
store_test_results Tests tab рд▓рд╛ рдорд╛рд╣рд┐рддреА рдкреБрд░рд╡рддреЗ (рдЖрдгрд┐ CircleCI рдЪреНрдпрд╛ рд╡реЗрд│реЗрд╡рд░ рдЖрдзрд╛рд░рд┐рдд
test splitting рд▓рд╛); store_artifacts рдХрдЪреНрдЪреА XML Artifacts рдЦрд╛рд▓реА рдареЗрд╡рддреЗ.
Jobs рджрд░рдореНрдпрд╛рди CircleCI files persist_to_workspace /
attach_workspace рдиреЗ рджреЗрддреЗ (# illustrative тАФ рдЗрдереЗ рдЧрд░рдЬ рдирд╛рд╣реА, рдХрд╛рд░рдг рдпрд╛ config рдордзреНрдпреЗ build
рдЖрдгрд┐ push рдПрдХрдЪ job рд╡рд╛рдЯреВрди рдШреЗрддрд╛рдд).
ЁЯжК рд╣реЗрдЪ GitLab CI рдордзреНрдпреЗ
artifacts: # lesson 05: the report card тАФ parsed into the MR widget
when: always
reports:
junit: app/test-results.xml
paths: [app/test-results.xml]
expire_in: 1 week
reports: junit merge request рд╡рд░ test summary widget рдХрд╛рдврддреЗ
("1 failed, 2 passed"). paths: рд╢рд┐рд╡рд╛рдп file download рдХрд░рдгреНрдпрд╛рдЬреЛрдЧреА рдХрд░рддреЗ,
when: always рдореНрд╣рдгрдЬреЗ if: always(), рдЖрдгрд┐ expire_in рдореНрд╣рдгрдЬреЗ retention.
рдирдВрддрд░рдЪреНрдпрд╛ stages рдордзрд▓реНрдпрд╛ jobs рдирд╛ рдЖрдзреАрдЪреНрдпрд╛ jobs рдЪреЗ artifacts: default рдиреБрд╕рд╛рд░ рдорд┐рд│рддрд╛рдд.
ЁЯОй рд╣реЗрдЪ Jenkins рдордзреНрдпреЗ
post { always { junit 'app/test-results.xml' } } // lesson 05: the report card
junit (JUnit plugin) file рд╡рд╛рдЪреВрди build рдЪреЗ test result page рдЖрдгрд┐ trend graph рдмрдирд╡рддреЗ,
рдЖрдгрд┐ test fail рдЭрд╛рд▓реА рддрд░ build рд▓рд╛ failed рдРрд╡рдЬреА unstable рдЕрд╢реА рдЦреВрдг рдХрд░рддреЗ. рдХрдЪреНрдЪреА file
рд╕реБрджреНрдзрд╛ рдареЗрд╡рд╛рдпрдЪреА рдЕрд╕реЗрд▓ рддрд░:
archiveArtifacts artifacts: 'app/test-results.xml' // illustrative
ЁЯзк рдХрд░реВрди рдкрд╛рд╣рд╛
# 0) in your fork (lesson 03): make sure at least one тЬЕ ci run exists
gh run list --workflow ci.yml --limit 3
# 1) grab the newest run's id and download the Node 22 report card
RUN=$(gh run list --workflow ci.yml --limit 1 --json databaseId --jq '.[0].databaseId')
gh run download "$RUN" -n test-results-node22 -D report
cat report/test-results.xml # <testsuite тАж tests="3" failures="0" тАж> тАФ one <testcase> per test
# 2) produce the same file locally тАФ no CI needed
cd app && npm run test:ci && head -5 test-results.xml && cd ..
# 3) see the envelope that ship.yml builds (Actions тЖТ ЁЯУж ship тЖТ a run тЖТ Artifacts тЖТ "image")
gh run list --workflow ship.yml --limit 1
# it is tens of MB gzipped and disappears after a day тАФ that's retention-days: 1 at work
тЪая╕П рдиреЗрд╣рдореАрдЪреНрдпрд╛ рдЪреБрдХрд╛
- jobs рджрд░рдореНрдпрд╛рди files рджреЗрдгреНрдпрд╛рд╕рд╛рдареА cache рд╡рд╛рдкрд░рдгреЗ тАФ cache miss рдЭрд╛рд▓рд╛ рдХреА рдкреБрдврдЪреНрдпрд╛ job рд▓рд╛ рдЧрдкрдЪреВрдк рдХрд╛рд╣реАрдЪ рдорд┐рд│рдд рдирд╛рд╣реА; artifact рд╡рд╛рдкрд░рд╛
- upload step рд╡рд░
if: always()рд╡рд┐рд╕рд░рдгреЗ, рдореНрд╣рдгрдЬреЗ рдкреНрд░рдЧрддрд┐рдкреБрд╕реНрддрдХ рдлрдХреНрдд рдХрд╛рд╣реАрдЪ рдмрд┐рдШрдбрд▓реЗ рдирд╕рддрд╛рдирд╛рдЪ рдЕрд╕рддреЗ - default 90-рджрд┐рд╡рд╕рд╛рдВрдЪреНрдпрд╛ retention рд╕рд╣ рднрд▓рд╛рдореЛрдард╛ folder (
node_modules, build output) upload рдХрд░рдгреЗ тАФ рд▓рд╛рдЧрдгрд╛рд▒реНрдпрд╛ files рдирд┐рд╡рдбрд╛ рдЖрдгрд┐retention-daysрдард░рд╡рд╛
тПня╕П рдкреБрдвреЗ
Push job рдЖрддрд╛ AWS рд╢реА рдмреЛрд▓рдгрд╛рд░ рдЖрд╣реЗ. рддреНрдпрд╛рдиреЗ рд╢рд╛рд│реЗрдЪреА рдореБрдЦреНрдп рдХрд┐рд▓реНрд▓реА ЁЯФС рдЦрд┐рд╢рд╛рдд рдШреЗрдКрди рдлрд┐рд░реВ рдирдпреЗ тАФ рддреНрдпрд╛рдиреЗ рдмреЕрдЬ рджрд╛рдЦрд╡реВрди рдбреЗ рдкрд╛рд╕ рдШреНрдпрд╛рд╡рд╛. ЁЯкк
git checkout lesson-06-secrets-oidc