diff --git a/.github/workflows/chart-ci.yml b/.github/workflows/chart-ci.yml index dfe081d..18ee948 100644 --- a/.github/workflows/chart-ci.yml +++ b/.github/workflows/chart-ci.yml @@ -1,5 +1,5 @@ +--- name: Chart CI - on: workflow_call: inputs: @@ -200,7 +200,7 @@ jobs: - name: Upload Trivy scan results to GitHub Security tab uses: github/codeql-action/upload-sarif@v4 with: - sarif_file: 'trivy-vuln-results.sarif' + sarif_file: 'trivy-vuln-results.sarif' - name: Run Trivy Vulnerability scan uses: aquasecurity/trivy-action@v0.36.0 @@ -221,7 +221,7 @@ jobs: runs-on: ubuntu-latest needs: - kubeconform - - polaris + - polaris - trivy steps: - name: Checkout @@ -302,8 +302,8 @@ jobs: name=$(git show origin/gh-pages:index.yaml | yq e '.entries | keys | .[0]' 2>/dev/null || echo " ??? ") VERSION=$(yq '.version' ${{ inputs.chart-dir }}/Chart.yaml) - - TAG_NAME="${name}-${VERSION}" + + TAG_NAME="${name}-${VERSION}" echo "TAG_NAME=$TAG_NAME" >> $GITHUB_OUTPUT echo "VERSION=$VERSION" >> $GITHUB_OUTPUT @@ -343,7 +343,7 @@ jobs: git config user.name "$GITHUB_ACTOR" git config user.email "$GITHUB_ACTOR@users.noreply.github.com" - # Get gh-pages + # Get gh-pages git fetch origin gh-pages mkdir -p .cr-index git show origin/gh-pages:index.yaml > .cr-index/index.yaml 2>/dev/null || echo "apiVersion: v1\nentries: {}" > .cr-index/index.yaml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 75a32aa..b0e0eb3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,10 +12,23 @@ on: # Allows you to run this workflow manually from the Actions tab workflow_dispatch: + inputs: + logLevel: + description: 'Log level' + required: true + default: 'warning' + type: choice + options: + - info + - warning + - debug + environment: + description: 'Environment to run tests against' + type: environment + required: true # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: - # This workflow contains a single job called "build" build: # The type of runner that the job will run on runs-on: ubuntu-latest @@ -32,5 +45,68 @@ jobs: rules: trailing-spaces: level: warning - line-length: disable # don't bother me with this rule + line-length: disable # don't bother me with this rule comments-indentation: disable # don't bother me with this rule + + tests-container-ci-with-dockle-accept: + needs: [build] + uses: "./.github/workflows/container-ci.yml" + with: + dockerfile-path: "./test/container/Dockerfile" + hadolint-ignore: "DL3008,DL3016" + image-name: aphp-busybox + image-custom-tag: test-with-dockle-accept + dockle-ignore: "CIS-DI-0010,DKL-DI-0001,CIS-DI-0001" + dockle-accept-file: + dockle-accept-key: | + PHP_SHA256, + PHPIZE_DEPS, + PHP_INI_DIR, + extra-build-args: | + KEY_TEST_1=value_test_1 + KEY_TEST_2="value test 2" + trivy-ignore-vuln-ids: | + CVE-2024-21508 + trivy-ignore-license-ids: | + WTFPL + dry-run: true + + tests-container-ci-without-dockle-accept: + needs: [build] + uses: "./.github/workflows/container-ci.yml" + with: + dockerfile-path: "./test/container/Dockerfile" + image-name: aphp-busybox + image-custom-tag: test-without-dockle-accept + dockle-ignore: "CIS-DI-0010,DKL-DI-0001,CIS-DI-0001" + extra-build-args: | + KEY_TEST_1=value_test_1 + KEY_TEST_2="value test 2" + trivy-ignore-vuln-ids: | + CVE-2024-21508 + trivy-ignore-license-ids: | + WTFPL + dry-run: true + + tests-container-ci-without-dockle-accept-without-trivyignore: + needs: build + uses: "./.github/workflows/container-ci.yml" + with: + dockerfile-path: "./test/container/Dockerfile" + image-name: aphp-busybox + image-custom-tag: test-without-dockle-accept-without-trivyignore + dockle-ignore: "CIS-DI-0010,DKL-DI-0001,CIS-DI-0001" + extra-build-args: | + KEY_TEST_1=value_test_1 + KEY_TEST_2="value test 2" + dry-run: true + + + clean-up: + needs: [tests-container-ci-without-dockle-accept-without-trivyignore, tests-container-ci-without-dockle-accept, tests-container-ci-with-dockle-accept] + # The type of runner that the job will run on + runs-on: ubuntu-latest + steps: + - name: End Test Workflow + run: | + docker images diff --git a/.github/workflows/container-ci.yml b/.github/workflows/container-ci.yml index 7c094f9..5ebb914 100644 --- a/.github/workflows/container-ci.yml +++ b/.github/workflows/container-ci.yml @@ -7,7 +7,7 @@ on: dockerfile-path: description: "Path to Dockerfile of your project" required: false - type: string + type: string default: "Dockerfile" hadolint-ignore: description: "Comma separated list of Hadolint rules to ignore (for scan only, will still be present in the generated report)" @@ -65,6 +65,12 @@ on: default: '' type: string + dry-run: + description: | + Run Jobs but donn't push image in Docker registry. + required: false + default: false + type: boolean jobs: dockerfile-lint: @@ -108,7 +114,7 @@ jobs: uses: actions/checkout@v6 with: fetch-depth: 0 - + - name: Parse build-args id: args shell: bash @@ -202,28 +208,30 @@ jobs: with: length: 7 - - name: Build Dockle report - uses: goodwithtech/dockle-action@v0.4.15 - with: - image: "${{ inputs.image-name }}:sha-${{ steps.short-sha.outputs.sha }}" - format: sarif - output: 'dockle-report.sarif' - exit-code: 0 - - - name: Upload Dockle report to GitHub Security tab - uses: github/codeql-action/upload-sarif@v4 + - name: Login to GitHub Container Registry + uses: docker/login-action@v4 with: - sarif_file: 'dockle-report.sarif' - category: code-quality + registry: ghcr.io + username: ${{github.actor}} + password: ${{secrets.GITHUB_TOKEN}} - name: Download Dockle +# if: inputs.dockle-accept-key != "" || inputs.dockle-accept-file != "" || inputs.dockle-ignore != "" run: | curl -sSL "https://github.com/goodwithtech/dockle/releases/download/v0.4.15/dockle_0.4.15_Linux-386.tar.gz" -o dockle.tar.gz tar -xzf dockle.tar.gz sudo mv dockle /usr/local/bin/dockle - name: Run dockle +# if: inputs.dockle-accept-key != "" || inputs.dockle-accept-file != "" || inputs.dockle-ignore != "" run: | + + echo "===== Docker images =====" + docker image ls + + echo "===== Inspect =====" + docker image inspect "${{ inputs.image-name }}:sha-${{ steps.short-sha.outputs.sha }}" + dockle_keys_formater(){ IFS=', ' read -r -a keys_list <<< "$VALUES" && \ formated_keys="" && \ for key in ${keys_list[@]}; do formated_keys="${formated_keys} $ARG $key" ; done && \ @@ -237,7 +245,6 @@ jobs: --format json \ "${{ inputs.image-name }}:sha-${{ steps.short-sha.outputs.sha }}" - image-scan: name: Image Scan needs: image-build @@ -382,6 +389,49 @@ jobs: print(f"ruleId fixed: {total_ruleId_fixed}") PY + - name: Patch Trivy Vulnerability SARIF rule IDs for GitHub + run: | + python3 <<'PY' + import json + import sys + from pathlib import Path + + max_len = 200 + paths = [Path("trivy-vuln-results.sarif"), Path("trivy-license-results.sarif")] + + for path in paths : + try: + with path.open("r", encoding="utf-8") as f: + sarif = json.load(f) + except FileNotFoundError: + print(f"ERROR: SARIF file not found: {path}") + sys.exit(1) + + total_id_fixed = 0 + total_ruleId_fixed = 0 + + for run in sarif.get("runs", []): + for rule in run.get("tool", {}).get("driver", {}).get("rules", []): + if isinstance(rule.get("id"), str) and len(rule["id"]) > max_len: + rule.setdefault("properties", {})["originalTrivyRuleId"] = rule["id"] + rule["id"] = rule["id"][:max_len] + total_id_fixed += 1 + + for result in run.get("results", []): + if isinstance(result.get("ruleId"), str) and len(result["ruleId"]) > max_len: + result.setdefault("properties", {})["originalTrivyRuleId"] = result["ruleId"] + result["ruleId"] = result["ruleId"][:max_len] + total_ruleId_fixed += 1 + + with path.open("w", encoding="utf-8") as f: + json.dump(sarif, f, ensure_ascii=False, indent=2) + + print("SARIF patched") + print(f"File: {path}") + print(f"id fixed: {total_id_fixed}") + print(f"ruleId fixed: {total_ruleId_fixed}") + PY + - name: Upload Trivy License report to GitHub Security tab uses: github/codeql-action/upload-sarif@v4 with: @@ -432,7 +482,7 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v6 - + - name: Download image tarball uses: actions/download-artifact@v8 with: @@ -456,5 +506,6 @@ jobs: password: ${{secrets.GITHUB_TOKEN}} - name: Push Image to GitHub Container Registry + if: ${{ !inputs.dry-run }} run: | docker push --all-tags ${{ inputs.image-name }} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 469fa0f..8de3dc0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,21 +1,21 @@ - -## How to contribute to the `aphp/ci-workflows` project - -#### **Did you find a bug?** - -* **Ensure the bug was not already reported** by searching on GitHub under [Issues](https://github.com/aphp/redcap-containers/issues). - -* If you're unable to find an open issue addressing the problem, [open a new one](https://github.com/aphp/redcap-containers/issues/new). Be sure to include a **title and clear description**, as much relevant information as possible, and a **code sample** or an **executable test case** demonstrating the expected behavior that is not occurring. - -#### **Did you write a patch that fixes a bug?** - -* Open a new GitHub pull request with the patch. - -* Ensure the PR description clearly describes the problem and solution. Include the relevant issue number if applicable. - -#### **Do you intend to add a new feature or change an existing one?** - -* Suggest your change in a dedicated issue. - -* Do not submit a PR on GitHub until you have collected positive feedback about the change. - + +## How to contribute to the `aphp/ci-workflows` project + +#### **Did you find a bug?** + +* **Ensure the bug was not already reported** by searching on GitHub under [Issues](https://github.com/aphp/redcap-containers/issues). + +* If you're unable to find an open issue addressing the problem, [open a new one](https://github.com/aphp/redcap-containers/issues/new). Be sure to include a **title and clear description**, as much relevant information as possible, and a **code sample** or an **executable test case** demonstrating the expected behavior that is not occurring. + +#### **Did you write a patch that fixes a bug?** + +* Open a new GitHub pull request with the patch. + +* Ensure the PR description clearly describes the problem and solution. Include the relevant issue number if applicable. + +#### **Do you intend to add a new feature or change an existing one?** + +* Suggest your change in a dedicated issue. + +* Do not submit a PR on GitHub until you have collected positive feedback about the change. + diff --git a/LICENSE b/LICENSE index 78cac7d..a93c433 100644 --- a/LICENSE +++ b/LICENSE @@ -1,203 +1,203 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + [2024 - 2025] [CI Workflows] © Assistance Publique – Hôpitaux de Paris. \ No newline at end of file diff --git a/README.md b/README.md index 1630024..39c15e0 100644 --- a/README.md +++ b/README.md @@ -1,341 +1,341 @@ -# APHP CI GitHub Reusable Workflows - -This repository hosts a collection of **reusable GitHub Actions workflows** for AP‑HP projects. - -The goal is to **centralize CI/CD best practices** (linting, security scans, packaging and publishing) so that each project can: - -- reuse the same, opinionated workflows, -- get consistent quality and security checks, -- keep CI configuration as small as possible. - -Current workflows mainly target: - -- **Container images** (build, scan and push to GHCR), -- **Helm charts** (lint, test, secure, document and publish). - ---- - -## Table of contents - -- [Overview](#overview) -- [Available reusable workflows](#available-reusable-workflows) - - [Container Images workflow](#container-images-workflow) - - [Helm Charts workflow](#helm-charts-workflow) -- [How to call a reusable workflow](#how-to-call-a-reusable-workflow) -- [Branching, versions and environments](#branching-versions-and-environments) -- [Contributing](#contributing) -- [License](#license) - ---- - -## Overview - -All workflows are stored under: - -```text -.github/workflows/ -``` - -You **do not copy** these YAML files into your own repositories. -Instead, your project **calls them as reusable workflows** using the `uses:` syntax described in the GitHub Actions documentation. - -This repository is meant to be used across all AP‑HP GitHub projects that need a **standard CI pipeline** for: - -- building and scanning Docker images, -- validating, scanning and releasing Helm charts. - ---- - -## Available reusable workflows - -Below is an overview of the main families of workflows currently documented. - -### Container Images workflow - -#### Description - -Provides **security and quality checks** for container images before pushing them to your project’s **GitHub Container Registry (GHCR)**. - -Typical use cases: - -- container images for applications (e.g. APIs, frontends, backends), -- base or runtime images (e.g. Jupyter EDS notebooks images), -- internal utilities or tools. - -#### Tools - -The workflow chains several tools: - -- **Hadolint** - - Linting of `Dockerfile` (style, best practices, common pitfalls). -- **Buildx** - - Docker image build (supports advanced features like build kits, multi‑arch, extra build args…). -- **Dockle** - - Image scan for misconfigurations and bad patterns. -- **Trivy** - - Vulnerability scanning of images. - - License scanning of included dependencies. -- **Docker / GHCR** - - Push of validated images to your project’s GHCR repository. - -#### Reports - -All tools that support it produce **SARIF reports**, automatically uploaded to your repository: - -- GitHub UI: `Security` tab → `Code scanning` section. -- You can browse findings by tool, severity, and impacted files. - -#### Prerequisites - -- Works **out of the box for public repositories**. -- For **private repositories**, you may need to: - - adjust **Actions permissions** so the workflow can push to your private GHCR, - - ensure the workflow can **write packages** (GHCR). - -> The exact permission model may depend on your organization policies; coordinate with your AP‑HP GitHub admins if needed. - -#### Inputs - -Inputs currently supported by the container images workflow: - -| Input | Type | Required | Default | Description | -|---------------------------:|:------:|:--------:|:------------------:|-------------| -| `dockerfile-path` | string | No | `Dockerfile` | Path to the Dockerfile of your project. | -| `hadolint-ignore` | string | No | `""` | Comma‑separated list of **Hadolint rule IDs** to ignore in **blocking** checks. Findings still appear in reports. | -| `image-name` | string | **Yes** | – | Full image name including registry and repository, e.g. `ghcr.io/aphp/my-service`. | -| `image-custom-tag` | string | No | `""` | Custom tag added **in addition** to automatically generated tags. Typical values: `x86_64-ubuntu-24.04`, `x86_64-ubuntu-24.04-dev`, `nightly`. | -| `extra-build-args` | string | No | `""` | Extra Docker build arguments, provided as `KEY=VALUE`. Usually passed as a multiline YAML scalar (one `KEY=VALUE` per line). | -| `dockle-ignore` | string | No | `""` | Comma‑separated list of **Dockle rule IDs** to ignore in **blocking** checks. | -| `dockle-accept-file` | string | No | `""` | Comma‑separated list of file names to accept in Dockle (`--accept-file`). | -| `dockle-accept-key` | string | No | `""` | Comma‑separated list of keys to accept in Dockle (`--accept-key`). | -| `trivy-ignore-vuln-ids` | string | No | `""` | List of vulnerability IDs (`CVE-…`, `GHSA-…`, `AVD-…`) to ignore for **blocking** Trivy checks. Can be comma‑separated or one per line. | -| `trivy-ignore-license-ids`| string | No | `""` | List of license identifiers (e.g. `GPL-3.0-only`, `MIT`) to ignore in **blocking** Trivy license checks. Can be comma‑separated or one per line. | - -Always refer to the workflow file in `.github/workflows/` for the most up‑to‑date list of inputs and defaults. - -#### Release management - -The workflow relies on a combination of actions and steps to handle **image tagging and publishing**: - -- During the build step, tags are computed according to **Docker Metadata Action** rules. -- If all scans pass successfully: - - the previously tagged image is pushed to your project’s GHCR repository. - -This behavior directly impacts your **release and tagging strategy**; make sure to align it with your project’s lifecycle (branching model, tags, environments). - ---- - -### Helm Charts workflow - -#### Description - -Provides **security and quality checks for Helm charts**, and automates **publishing** to a Helm repository hosted via your project’s GitHub Pages (`gh-pages` branch). - -Typical use cases: - -- Helm charts for applications like **HELIX**, **REDCap**, etc., -- any Kubernetes deployment managed via Helm within AP‑HP projects. - -#### Tools - -The Helm charts workflow is organized by job: - -- **Linting (`lint-test` job)** - - `ct lint` (Helm chart-testing), - - `kubeconform` (Kubernetes manifest validation against schemas). - -- **Security (`lint-test` job)** - - **Polaris** (configuration and security best practices), - - **Trivy** (vulnerability scanning on rendered manifests). - -- **Documentation (`generate-doc` job)** - - **helm-docs** (README / values documentation from chart), - - **Values schema JSON** generation (for validation and tooling). - -- **Publishing (`release` job)** - - **helm/chart-releaser** to package charts and update the Helm index. - -#### Reports - -Some tools (currently **Trivy**) generate **SARIF reports**, uploaded to: - -- `Security` tab → `Code scanning`. - -This allows you to track vulnerabilities and security issues directly in GitHub. - -#### Prerequisites - -To be able to **publish charts** and use the repository as a **Helm repository**, ensure: - -1. A branch named `gh-pages` exists in your repository. -2. In your repository **Settings**: - - `Code and automation / Pages` → `Branch`: select `gh-pages`. -3. In **Settings → Actions → General**: - - `Actions permissions`: set to **Allow all actions and reusable workflows**. - - `Workflow permissions`: set to **Read and write permissions**. -4. Your chart lives under a `charts` directory at the repository root: - - ```text - charts/ - mychart/ - Chart.yaml - values.yaml - templates/... - ``` - -#### Inputs - -Inputs currently supported by the Helm charts workflow: - -| Input | Type | Required | Default | Description | -|--------------------:|:------:|:--------:|:---------------------:|-------------| -| `chart-dir` | string | **Yes** | `chart` | Directory containing your Helm chart (must contain a `Chart.yaml`). | -| `chart-values` | string | No | `chart/values.yaml` | Values file used for `kubeconform`, Polaris, Trivy and `ct install` tests. | -| `kubernetes-version`| string| No | `1.24.2` | Target Kubernetes version used by kubeconform and Trivy for validations and scans. | - -Again, always check the workflow file in `.github/workflows/` for the authoritative list of inputs. - -#### Release management - -Chart releases are handled via the **Helm CR action**, with behavior depending on the branch: - -- On **`feature` branch**: - - Chart version in `Chart.yaml` is suffixed with `-snapshot`, - - A Git tag is created with this snapshot version, - - A **Release** is created containing the snapshot chart archive, - - `index.yaml` in the `gh-pages` branch is updated to reference the new **snapshot** chart. - -- On **`dev` branch**: - - Chart version in `Chart.yaml` is suffixed with `-dev`, - - A Git tag is created with this dev version, - - A **Release** is created containing the dev chart archive, - - `index.yaml` in the `gh-pages` branch is updated to reference the new **dev** chart. - -- On **`main` branch**: - - A Git tag is created with the chart version from `Chart.yaml`, - - A **Release** is created with the chart archive, marked as **latest**, - - `index.yaml` in `gh-pages` is updated to reference the new **stable** chart. - -This gives you a standard separation between **snapshot**,**dev** and **stable** releases for Helm charts. - ---- - -## How to call a reusable workflow - -To use one of these workflows from another repository: - -1. Create a workflow file in your project, e.g.: - - ```text - .github/workflows/container-ci.yml - ``` - -2. In that file, define a job that **uses** one of the workflows from this repo: - - ```yaml - name: Container CI - - on: - push: - branches: [ main, dev ] - pull_request: - - permissions: - contents: write - security-events: write - - jobs: - container-ci: - uses: aphp/ci-workflows/.github/workflows/.yml@main - with: - image-name: ghcr.io/aphp/my-service - dockerfile-path: Dockerfile - image-custom-tag: x86_64-ubuntu-24.04 - ``` - -3. For Helm charts, a similar pattern applies: - - ```yaml - name: Helm Chart CI - - on: - push: - branches: [ main, dev ] - pull_request: - - permissions: - contents: write - security-events: write - - jobs: - helm-ci: - uses: aphp/ci-workflows/.github/workflows/.yml@main - with: - chart-dir: charts/mychart - chart-values: charts/mychart/values.yaml - kubernetes-version: "1.24.2" - ``` - -> Replace `.yml` and `.yml` with the actual filenames from this repository’s `.github/workflows` directory. - -For a concrete example of usage, you can refer to a project CI configuration that calls these workflows (e.g. container image or Helm chart repositories within the AP‑HP GitHub organization). - ---- - -## Branching, versions and environments - -This repository is versioned like any other Git repository: - -- **Branches** such as `feature`, `dev` or `main` represent the maturity of workflows. -- In your consuming projects, you should: - - Prefer **tags** (once defined) for stable usage, e.g. `@v1`, - - Use the `dev` branch (`@dev`) when experimenting or adopting new features early. - -*note: `feature` name is the name of your branch created from Issue.* - -Examples: - -- Stable usage (recommended when available): - - ```yaml - uses: aphp/ci-workflows/.github/workflows/.yml@v1 - ``` - -- Development usage (bleeding edge): - - ```yaml - uses: aphp/ci-workflows/.github/workflows/.yml@dev - ``` - -Coordinate with the AP‑HP CI maintainers to know which refs are recommended for production usage. - ---- - -## Contributing - -Contributions, bug reports and improvement ideas are welcome. - -- See [`CONTRIBUTING.md`](CONTRIBUTING.md) for: - - coding standards, - - how to run tests/linters locally, - - the release workflow for this repository. -- Use **GitHub Issues** to: - - report problems with existing workflows, - - request new reusable workflows, - - ask for documentation improvements. - -Before opening a pull request: - -1. Check there is an existing issue (or open a new one) describing the change. -2. Update or add documentation for new inputs/behavior. -3. Run relevant tests or dry‑runs for the workflows you modify. - ---- - -## License - -This project is licensed under the **Apache License 2.0**. - -- See [`LICENSE`](LICENSE) for details. - -By contributing to this repository, you agree that your contributions will be licensed under the same terms. +# APHP CI GitHub Reusable Workflows + +This repository hosts a collection of **reusable GitHub Actions workflows** for AP‑HP projects. + +The goal is to **centralize CI/CD best practices** (linting, security scans, packaging and publishing) so that each project can: + +- reuse the same, opinionated workflows, +- get consistent quality and security checks, +- keep CI configuration as small as possible. + +Current workflows mainly target: + +- **Container images** (build, scan and push to GHCR), +- **Helm charts** (lint, test, secure, document and publish). + +--- + +## Table of contents + +- [Overview](#overview) +- [Available reusable workflows](#available-reusable-workflows) + - [Container Images workflow](#container-images-workflow) + - [Helm Charts workflow](#helm-charts-workflow) +- [How to call a reusable workflow](#how-to-call-a-reusable-workflow) +- [Branching, versions and environments](#branching-versions-and-environments) +- [Contributing](#contributing) +- [License](#license) + +--- + +## Overview + +All workflows are stored under: + +```text +.github/workflows/ +``` + +You **do not copy** these YAML files into your own repositories. +Instead, your project **calls them as reusable workflows** using the `uses:` syntax described in the GitHub Actions documentation. + +This repository is meant to be used across all AP‑HP GitHub projects that need a **standard CI pipeline** for: + +- building and scanning Docker images, +- validating, scanning and releasing Helm charts. + +--- + +## Available reusable workflows + +Below is an overview of the main families of workflows currently documented. + +### Container Images workflow + +#### Description + +Provides **security and quality checks** for container images before pushing them to your project’s **GitHub Container Registry (GHCR)**. + +Typical use cases: + +- container images for applications (e.g. APIs, frontends, backends), +- base or runtime images (e.g. Jupyter EDS notebooks images), +- internal utilities or tools. + +#### Tools + +The workflow chains several tools: + +- **Hadolint** + - Linting of `Dockerfile` (style, best practices, common pitfalls). +- **Buildx** + - Docker image build (supports advanced features like build kits, multi‑arch, extra build args…). +- **Dockle** + - Image scan for misconfigurations and bad patterns. +- **Trivy** + - Vulnerability scanning of images. + - License scanning of included dependencies. +- **Docker / GHCR** + - Push of validated images to your project’s GHCR repository. + +#### Reports + +All tools that support it produce **SARIF reports**, automatically uploaded to your repository: + +- GitHub UI: `Security` tab → `Code scanning` section. +- You can browse findings by tool, severity, and impacted files. + +#### Prerequisites + +- Works **out of the box for public repositories**. +- For **private repositories**, you may need to: + - adjust **Actions permissions** so the workflow can push to your private GHCR, + - ensure the workflow can **write packages** (GHCR). + +> The exact permission model may depend on your organization policies; coordinate with your AP‑HP GitHub admins if needed. + +#### Inputs + +Inputs currently supported by the container images workflow: + +| Input | Type | Required | Default | Description | +|---------------------------:|:------:|:--------:|:------------------:|-------------| +| `dockerfile-path` | string | No | `Dockerfile` | Path to the Dockerfile of your project. | +| `hadolint-ignore` | string | No | `""` | Comma‑separated list of **Hadolint rule IDs** to ignore in **blocking** checks. Findings still appear in reports. | +| `image-name` | string | **Yes** | – | Full image name including registry and repository, e.g. `ghcr.io/aphp/my-service`. | +| `image-custom-tag` | string | No | `""` | Custom tag added **in addition** to automatically generated tags. Typical values: `x86_64-ubuntu-24.04`, `x86_64-ubuntu-24.04-dev`, `nightly`. | +| `extra-build-args` | string | No | `""` | Extra Docker build arguments, provided as `KEY=VALUE`. Usually passed as a multiline YAML scalar (one `KEY=VALUE` per line). | +| `dockle-ignore` | string | No | `""` | Comma‑separated list of **Dockle rule IDs** to ignore in **blocking** checks. | +| `dockle-accept-file` | string | No | `""` | Comma‑separated list of file names to accept in Dockle (`--accept-file`). | +| `dockle-accept-key` | string | No | `""` | Comma‑separated list of keys to accept in Dockle (`--accept-key`). | +| `trivy-ignore-vuln-ids` | string | No | `""` | List of vulnerability IDs (`CVE-…`, `GHSA-…`, `AVD-…`) to ignore for **blocking** Trivy checks. Can be comma‑separated or one per line. | +| `trivy-ignore-license-ids`| string | No | `""` | List of license identifiers (e.g. `GPL-3.0-only`, `MIT`) to ignore in **blocking** Trivy license checks. Can be comma‑separated or one per line. | + +Always refer to the workflow file in `.github/workflows/` for the most up‑to‑date list of inputs and defaults. + +#### Release management + +The workflow relies on a combination of actions and steps to handle **image tagging and publishing**: + +- During the build step, tags are computed according to **Docker Metadata Action** rules. +- If all scans pass successfully: + - the previously tagged image is pushed to your project’s GHCR repository. + +This behavior directly impacts your **release and tagging strategy**; make sure to align it with your project’s lifecycle (branching model, tags, environments). + +--- + +### Helm Charts workflow + +#### Description + +Provides **security and quality checks for Helm charts**, and automates **publishing** to a Helm repository hosted via your project’s GitHub Pages (`gh-pages` branch). + +Typical use cases: + +- Helm charts for applications like **HELIX**, **REDCap**, etc., +- any Kubernetes deployment managed via Helm within AP‑HP projects. + +#### Tools + +The Helm charts workflow is organized by job: + +- **Linting (`lint-test` job)** + - `ct lint` (Helm chart-testing), + - `kubeconform` (Kubernetes manifest validation against schemas). + +- **Security (`lint-test` job)** + - **Polaris** (configuration and security best practices), + - **Trivy** (vulnerability scanning on rendered manifests). + +- **Documentation (`generate-doc` job)** + - **helm-docs** (README / values documentation from chart), + - **Values schema JSON** generation (for validation and tooling). + +- **Publishing (`release` job)** + - **helm/chart-releaser** to package charts and update the Helm index. + +#### Reports + +Some tools (currently **Trivy**) generate **SARIF reports**, uploaded to: + +- `Security` tab → `Code scanning`. + +This allows you to track vulnerabilities and security issues directly in GitHub. + +#### Prerequisites + +To be able to **publish charts** and use the repository as a **Helm repository**, ensure: + +1. A branch named `gh-pages` exists in your repository. +2. In your repository **Settings**: + - `Code and automation / Pages` → `Branch`: select `gh-pages`. +3. In **Settings → Actions → General**: + - `Actions permissions`: set to **Allow all actions and reusable workflows**. + - `Workflow permissions`: set to **Read and write permissions**. +4. Your chart lives under a `charts` directory at the repository root: + + ```text + charts/ + mychart/ + Chart.yaml + values.yaml + templates/... + ``` + +#### Inputs + +Inputs currently supported by the Helm charts workflow: + +| Input | Type | Required | Default | Description | +|--------------------:|:------:|:--------:|:---------------------:|-------------| +| `chart-dir` | string | **Yes** | `chart` | Directory containing your Helm chart (must contain a `Chart.yaml`). | +| `chart-values` | string | No | `chart/values.yaml` | Values file used for `kubeconform`, Polaris, Trivy and `ct install` tests. | +| `kubernetes-version`| string| No | `1.24.2` | Target Kubernetes version used by kubeconform and Trivy for validations and scans. | + +Again, always check the workflow file in `.github/workflows/` for the authoritative list of inputs. + +#### Release management + +Chart releases are handled via the **Helm CR action**, with behavior depending on the branch: + +- On **`feature` branch**: + - Chart version in `Chart.yaml` is suffixed with `-snapshot`, + - A Git tag is created with this snapshot version, + - A **Release** is created containing the snapshot chart archive, + - `index.yaml` in the `gh-pages` branch is updated to reference the new **snapshot** chart. + +- On **`dev` branch**: + - Chart version in `Chart.yaml` is suffixed with `-dev`, + - A Git tag is created with this dev version, + - A **Release** is created containing the dev chart archive, + - `index.yaml` in the `gh-pages` branch is updated to reference the new **dev** chart. + +- On **`main` branch**: + - A Git tag is created with the chart version from `Chart.yaml`, + - A **Release** is created with the chart archive, marked as **latest**, + - `index.yaml` in `gh-pages` is updated to reference the new **stable** chart. + +This gives you a standard separation between **snapshot**,**dev** and **stable** releases for Helm charts. + +--- + +## How to call a reusable workflow + +To use one of these workflows from another repository: + +1. Create a workflow file in your project, e.g.: + + ```text + .github/workflows/container-ci.yml + ``` + +2. In that file, define a job that **uses** one of the workflows from this repo: + + ```yaml + name: Container CI + + on: + push: + branches: [ main, dev ] + pull_request: + + permissions: + contents: write + security-events: write + + jobs: + container-ci: + uses: aphp/ci-workflows/.github/workflows/.yml@main + with: + image-name: ghcr.io/aphp/my-service + dockerfile-path: Dockerfile + image-custom-tag: x86_64-ubuntu-24.04 + ``` + +3. For Helm charts, a similar pattern applies: + + ```yaml + name: Helm Chart CI + + on: + push: + branches: [ main, dev ] + pull_request: + + permissions: + contents: write + security-events: write + + jobs: + helm-ci: + uses: aphp/ci-workflows/.github/workflows/.yml@main + with: + chart-dir: charts/mychart + chart-values: charts/mychart/values.yaml + kubernetes-version: "1.24.2" + ``` + +> Replace `.yml` and `.yml` with the actual filenames from this repository’s `.github/workflows` directory. + +For a concrete example of usage, you can refer to a project CI configuration that calls these workflows (e.g. container image or Helm chart repositories within the AP‑HP GitHub organization). + +--- + +## Branching, versions and environments + +This repository is versioned like any other Git repository: + +- **Branches** such as `feature`, `dev` or `main` represent the maturity of workflows. +- In your consuming projects, you should: + - Prefer **tags** (once defined) for stable usage, e.g. `@v1`, + - Use the `dev` branch (`@dev`) when experimenting or adopting new features early. + +*note: `feature` name is the name of your branch created from Issue.* + +Examples: + +- Stable usage (recommended when available): + + ```yaml + uses: aphp/ci-workflows/.github/workflows/.yml@v1 + ``` + +- Development usage (bleeding edge): + + ```yaml + uses: aphp/ci-workflows/.github/workflows/.yml@dev + ``` + +Coordinate with the AP‑HP CI maintainers to know which refs are recommended for production usage. + +--- + +## Contributing + +Contributions, bug reports and improvement ideas are welcome. + +- See [`CONTRIBUTING.md`](CONTRIBUTING.md) for: + - coding standards, + - how to run tests/linters locally, + - the release workflow for this repository. +- Use **GitHub Issues** to: + - report problems with existing workflows, + - request new reusable workflows, + - ask for documentation improvements. + +Before opening a pull request: + +1. Check there is an existing issue (or open a new one) describing the change. +2. Update or add documentation for new inputs/behavior. +3. Run relevant tests or dry‑runs for the workflows you modify. + +--- + +## License + +This project is licensed under the **Apache License 2.0**. + +- See [`LICENSE`](LICENSE) for details. + +By contributing to this repository, you agree that your contributions will be licensed under the same terms. diff --git a/test/container/Dockerfile b/test/container/Dockerfile new file mode 100644 index 0000000..b6c2a70 --- /dev/null +++ b/test/container/Dockerfile @@ -0,0 +1,5 @@ +ARG IMAGE=busybox + +FROM ${IMAGE} + +