diff --git a/.github/workflows/build-bun.yml b/.github/workflows/build-bun.yml index 69e6c6c..bebc056 100644 --- a/.github/workflows/build-bun.yml +++ b/.github/workflows/build-bun.yml @@ -16,13 +16,20 @@ on: default: 'latest' artifact-name: type: string - description: 'Give generated artifact a name' + description: 'Name of the artifact to upload, default: is basename of the artifact if single file, or dirname if multiple files, followed by the OS name' required: false artifact-path: type: string description: 'Path to the generated artifact to upload' required: false default: 'dist/' + outputs: + artifact-id: + description: 'The ID of the uploaded artifact' + value: ${{ jobs.build.outputs.artifact-id }} + artifact-url: + description: 'The URL of the uploaded artifact' + value: ${{ jobs.build.outputs.artifact-url }} jobs: build: @@ -30,7 +37,9 @@ jobs: defaults: run: working-directory: ${{ inputs.working-directory }} - + outputs: + artifact-id: ${{ steps.upload-artifact.outputs.artifact-id }} + artifact-url: ${{ steps.upload-artifact.outputs.artifact-url }} steps: - uses: actions/checkout@v4 @@ -49,11 +58,36 @@ jobs: - name: Install Bun dependencies run: bun install - - name: Build with Bun - run: bun run build + - id: build + name: Build with Bun + run: | + bun run build + if [ -n "${{ inputs.artifact-path }}" ]; then + echo -e "Artifact path is set to '${{ inputs.artifact-path }}.\nIncluding :" + ARTIFACT_CONTENT="$(ls -dAp "${{ inputs.artifact-path }}")" + echo "$ARTIFACT_CONTENT" + if [ -z "${{ inputs.artifact-name }}" ]; then + artifact_path="${{ inputs.artifact-path }}" + if [ -d "$artifact_path" ]; then + echo "Artifact path is a directory, using it as is." + artifact_path="$(dirname "$artifact_path")" + elif [ -f "$artifact_path" ]; then + echo "Artifact path is a file, using it as is." + artifact_path="$artifact_path" + elif [ "$(ls -A "$artifact_path")" ]; then + echo "Artifact is multiple files, using the directory." + artifact_path="$(dirname "$artifact_path")" + fi + ARTIFACT_NAME="${artifact_path}-${{ runner.os }}" + else + ARTIFACT_NAME="${{ inputs.artifact-name }}" + fi + echo "artifact-name=${ARTIFACT_NAME}" >> $GITHUB_OUTPUT + fi - name: Upload build artifacts - if: inputs.artifact-name != '' && inputs.artifact-path != '' + if: steps.build.outputs.artifact-name != '' && inputs.artifact-path != '' + id: upload-artifact uses: actions/upload-artifact@v4 with: name: ${{ inputs.artifact-name }} diff --git a/.github/workflows/build-docker.yml b/.github/workflows/build-docker.yml index 2645c12..c20ac23 100644 --- a/.github/workflows/build-docker.yml +++ b/.github/workflows/build-docker.yml @@ -20,13 +20,27 @@ on: default: 'Dockerfile' with-artifact-name: type: string - description: 'Name of the artifact to include in the image' + description: 'Name of the artifact to include in the image, can''t be used with with-artifact-ids' required: false + with-artifact-ids: + type: string + description: 'Comma separated list of Ids of the artifact to include in the image, can''t be used with with-artifact-name' + required: false + with-artifact-unzip: + type: string + description: 'Comma separated list of ids or name of downloaded artifact that will be unzip. Default to all artifacts' + required: false + default: '*' with-artifact-path: type: string description: 'Where to place the artifacts' required: false default: 'artifacts/' + with-artifact-merge: + type: boolean + description: 'Whether to merge multiple artifacts into one folder' + required: false + default: false permissions: contents: read @@ -43,12 +57,14 @@ jobs: - uses: actions/checkout@v4 - name: Download artifact - if: inputs.with-artifact-name != '' - uses: actions/download-artifact@v4 + if: inputs.with-artifact-name != '' || inputs.with-artifact-ids != '' + uses: shiipou/download-artifact@main with: name: ${{ inputs.with-artifact-name }} + artifact-ids: ${{ inputs.with-artifact-ids }} path: ${{ inputs.working-directory }}/${{ inputs.with-artifact-path }} - + unzip: ${{ inputs.with-artifact-unzip }} + merge-multiple: ${{ inputs.with-artifact-merge }} - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 diff --git a/.github/workflows/build-flutter.yml b/.github/workflows/build-flutter.yml index 29f6359..54de3c2 100644 --- a/.github/workflows/build-flutter.yml +++ b/.github/workflows/build-flutter.yml @@ -64,6 +64,13 @@ on: UPLOAD_STORE_PASSWORD: description: 'Password for the Android keystore' required: false + outputs: + artifact-id: + description: 'The ID of the uploaded artifact' + value: ${{ jobs.build.outputs.artifact-id }} + artifact-url: + description: 'The URL of the uploaded artifact' + value: ${{ jobs.build.outputs.artifact-url }} jobs: build: @@ -71,6 +78,9 @@ jobs: run: working-directory: ${{ inputs.working-directory }} runs-on: ${{ inputs.runner }} + outputs: + artifact-id: ${{ steps.upload-artifact.outputs.artifact-id }} + artifact-url: ${{ steps.upload-artifact.outputs.artifact-url }} steps: - name: Checkout repository uses: actions/checkout@v4 diff --git a/.github/workflows/build-springboot.yml b/.github/workflows/build-springboot.yml index 5929e14..d4f601e 100644 --- a/.github/workflows/build-springboot.yml +++ b/.github/workflows/build-springboot.yml @@ -36,17 +36,24 @@ on: envs: description: 'Add extra env variable to the build, one value per line : =' required: false - + outputs: + artifact-id: + description: 'The ID of the uploaded artifact' + value: ${{ jobs.build.outputs.artifact-id }} + artifact-url: + description: 'The URL of the uploaded artifact' + value: ${{ jobs.build.outputs.artifact-url }} jobs: build: runs-on: ubuntu-latest defaults: run: working-directory: ${{ inputs.working-directory }} - + outputs: + artifact-id: ${{ steps.upload-artifact.outputs.artifact-id }} + artifact-url: ${{ steps.upload-artifact.outputs.artifact-url }} steps: - uses: actions/checkout@v4 - - run: echo "${{ inputs.envs }}" >> .env - run: echo "${{ secrets.envs }}" >> .env @@ -61,7 +68,8 @@ jobs: - name: Build with Gradle run: gradle build -x test - - name: Upload build artifacts + - id: upload-artifact + name: Upload build artifacts if: inputs.artifact-name != '' && inputs.artifact-path != '' uses: actions/upload-artifact@v4 with: diff --git a/.github/workflows/coverage-report.yml b/.github/workflows/coverage-report.yml index c63bcd5..b380f97 100644 --- a/.github/workflows/coverage-report.yml +++ b/.github/workflows/coverage-report.yml @@ -6,13 +6,22 @@ on: inputs: with-artifact-name: type: string - description: Coverage report artifact name - required: true + description: Coverage report artifact name, can't be used with with-artifact-ids + required: false + with-artifact-ids: + type: string + description: Coverage report artifact ids, can't be used with with-artifact-name + required: false with-artifact-path: type: string description: Path to the coverage report artifact required: false default: lcov.info + with-artifact-merge: + type: boolean + description: Whether to merge multiple artifacts into one folder + required: false + default: false min-lines-coverage: type: number description: Minimum percentage of lines covered @@ -63,10 +72,12 @@ jobs: - name: Setup LCOV uses: hrishikesh-kadam/setup-lcov@v1 - name: Download coverage report - uses: actions/download-artifact@v4 + uses: shiipou/download-artifact@main with: - name: ${{ inputs.artifact-name }} + name: ${{ inputs.with-artifact-name }} + artifact-ids: ${{ inputs.with-artifact-ids }} path: coverage/ + merge-multiple: ${{ inputs.with-artifact-merge }} - name: Parse coverage report id: coverage run: | @@ -77,7 +88,7 @@ jobs: echo "${BASH_REMATCH[1]}-total=${BASH_REMATCH[4]}" >> $GITHUB_OUTPUT echo "${BASH_REMATCH[1]}-percentage=${BASH_REMATCH[2]}" >> $GITHUB_OUTPUT fi - done < <(lcov --summary coverage/${{ inputs.artifact-path }}) + done < <(lcov --summary coverage/${{ inputs.with-artifact-path }}) - name: Check coverage report data if: inputs.min-lines-coverage != '' run: | diff --git a/.github/workflows/deploy-flutter.yml b/.github/workflows/deploy-flutter.yml index cd699cf..2d6d40f 100644 --- a/.github/workflows/deploy-flutter.yml +++ b/.github/workflows/deploy-flutter.yml @@ -10,12 +10,26 @@ on: required: true with-artifact-name: type: string - description: 'Identifier for the build artifact (e.g., android-aab or ios-ipa)' - required: true + description: 'Name for the build artifact to download (e.g., android-aab or ios-ipa), can''t be used with with-artifact-ids' + required: false + with-artifact-ids: + type: string + description: 'Comma separated list of ids of the builds artifact to download, can''t be used with with-artifact-name' + required: false + with-artifact-unzip: + type: string + description: 'Comma separated list of ids or name of downloaded artifact that will be unzip. Default to all artifacts' + required: false + default: '*' with-artifact-path: type: string description: 'Path to the build file to deploy (inside of the artifact)' required: true + with-artifact-merge: + type: boolean + description: 'Whenever to download multiple artifacts into one same folder' + required: false + default: false package-name: type: string description: 'The package name of the app' @@ -46,10 +60,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/download-artifact@v4 + uses: shiipou/download-artifact@main with: name: ${{ inputs.with-artifact-name }} + artifact-ids: ${{ inputs.with-artifact-ids }} + unzip: ${{ inputs.with-artifact-unzip }} path: ./artifacts/ + merge-multiple: ${{ inputs.with-artifact-merge }} - name: Setup Flutter Environment uses: subosito/flutter-action@v2.18.0 with: diff --git a/.github/workflows/generate-version-names.yml b/.github/workflows/generate-version-names.yml index 273e42a..71105a7 100644 --- a/.github/workflows/generate-version-names.yml +++ b/.github/workflows/generate-version-names.yml @@ -40,8 +40,8 @@ jobs: tags="$tags,${template//\[:version:\]/$major_minor},${template//\[:version:\]/$major}" else # For prerelease, generate only the major.minor-prerelease tag - major_minor_prerelease=$(echo "$version" | grep -oE '^[0-9]+\.[0-9]+-[^\.]+') - if [[ -n "$major_minor_prerelease" ]]; then + major_minor_prerelease=$(echo "$version" | sed -E 's/^([0-9]+)\.([0-9]+).([0-9]+)-(.+)$/\1.\2-\4/') + if [[ "$major_minor_prerelease" != "$version" ]]; then tags="$tags,${template//\[:version:\]/$major_minor_prerelease}" fi fi diff --git a/.github/workflows/test-bun.yml b/.github/workflows/test-bun.yml index 26eea54..b98c335 100644 --- a/.github/workflows/test-bun.yml +++ b/.github/workflows/test-bun.yml @@ -14,6 +14,13 @@ on: description: 'Version of Java to use' required: false default: 'latest' + outputs: + artifact-id: + description: 'The ID of the uploaded artifact' + value: ${{ jobs.build.outputs.artifact-id }} + artifact-url: + description: 'The URL of the uploaded artifact' + value: ${{ jobs.build.outputs.artifact-url }} jobs: build: @@ -21,7 +28,9 @@ jobs: defaults: run: working-directory: ${{ inputs.working-directory }} - + outputs: + artifact-id: ${{ steps.upload-artifact.outputs.artifact-id }} + artifact-url: ${{ steps.upload-artifact.outputs.artifact-url }} steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/test-flutter.yml b/.github/workflows/test-flutter.yml index bc4f004..5840fc8 100644 --- a/.github/workflows/test-flutter.yml +++ b/.github/workflows/test-flutter.yml @@ -27,6 +27,13 @@ on: description: 'Coverage report path to upload as artifact' required: false default: 'coverage/lcov.info' + outputs: + artifact-id: + description: 'The ID of the uploaded artifact' + value: ${{ jobs.test.outputs.artifact-id }} + artifact-url: + description: 'The URL of the uploaded artifact' + value: ${{ jobs.test.outputs.artifact-url }} jobs: test: @@ -34,6 +41,9 @@ jobs: defaults: run: working-directory: ${{ inputs.working-directory }} + outputs: + artifact-id: ${{ steps.upload-artifact.outputs.artifact-id }} + artifact-url: ${{ steps.upload-artifact.outputs.artifact-url }} steps: - name: Checkout repository uses: actions/checkout@v4 diff --git a/.github/workflows/test-springboot.yml b/.github/workflows/test-springboot.yml index 56b27f1..e03b375 100644 --- a/.github/workflows/test-springboot.yml +++ b/.github/workflows/test-springboot.yml @@ -36,13 +36,24 @@ on: type: string description: 'The profile of the composefile to load' required: false - + + outputs: + artifact-id: + description: 'The ID of the uploaded artifact' + value: ${{ jobs.test.outputs.artifact-id }} + artifact-url: + description: 'The URL of the uploaded artifact' + value: ${{ jobs.test.outputs.artifact-url }} + jobs: test: runs-on: ubuntu-latest defaults: run: working-directory: ${{ inputs.working-directory }} + outputs: + artifact-id: ${{ steps.upload-artifact.outputs.artifact-id }} + artifact-url: ${{ steps.upload-artifact.outputs.artifact-url }} steps: - uses: actions/checkout@v4 @@ -53,15 +64,13 @@ jobs: java-version: ${{ inputs.java-version }} distribution: ${{ inputs.java-distribution }} cache: gradle + - name: Run compose-file if: inputs.compose-file != '' run: | - docker compose up -f ${{ inputs.compose-file }} --profile ${{ $inputs.compose-profile }} -d + docker compose -f ${{ inputs.compose-file }} --profile ${{ inputs.compose-profile }} up -d + - name: Build with Gradle - env: - DATABASE_URL: postgresql://localhost:5432/app - DATABASE_USER: app - DATABASE_PASSWORD: app run: gradle test - name: Upload build artifacts @@ -70,6 +79,7 @@ jobs: with: name: ${{ inputs.artifact-name }} path: ${{ inputs.working-directory }}/${{ inputs.artifact-path }} + - name: Stop compose-file if: inputs.compose-file != '' && always() - run: docker compose down -f ${{ inputs.compose-file }} --profile ${{ $inputs.compose-profile }} + run: docker compose -f ${{ inputs.compose-file }} --profile ${{ inputs.compose-profile }} down diff --git a/.github/workflows/upsert-release.yml b/.github/workflows/upsert-release.yml index 58948bc..c02604d 100644 --- a/.github/workflows/upsert-release.yml +++ b/.github/workflows/upsert-release.yml @@ -19,12 +19,26 @@ on: default: false with-artifact-name: type: string - description: 'Identifier for the build artifact (e.g., android-aab or ios-ipa)' + description: 'Name for the build artifact to download (e.g., android-aab or ios-ipa), can''t be used with with-artifact-ids' required: false + with-artifact-ids: + type: string + description: 'Comma separated list of ids of the builds artifact to download, can''t be used with with-artifact-name' + required: false + with-artifact-unzip: + type: string + description: 'Comma separated list of ids or name of downloaded artifact that will be unzip. Default to all artifacts' + required: false + default: '*' with-artifact-path: type: string description: 'Comma separated list of file to deploy (inside of the artifact)' required: false + with-artifact-merge: + type: boolean + description: 'Whether to merge multiple artifacts into one folder' + required: false + default: false permissions: contents: write @@ -54,20 +68,17 @@ jobs: set -e - name: Download artifact - uses: actions/download-artifact@v4 + uses: shiipou/download-artifact@main with: name: ${{ inputs.with-artifact-name }} + artifact-ids: ${{ inputs.with-artifact-ids }} path: artifacts/ + unzip: ${{ inputs.with-artifact-unzip }} merge-multiple: true - name: Create release (if not exists) if: steps.check_release.outputs.exists == 'false' run: | - artifact_arg='' - if [ -n "${{ inputs.artifact-path }}" ]; then - artifact_arg="artifacts/${{ inputs.with-artifact-path }}" - fi - prerelease_args='' if ${{ inputs.prerelease }} ; then prerelease_args='--prerelease' @@ -78,8 +89,18 @@ jobs: --repo ${{ github.repository }} \ -t "v${{ inputs.version }}" \ $prerelease_args \ - -F <(echo "${{ inputs.changelog }}") \ - $artifact_arg + -F <(echo "${{ inputs.changelog }}") + + if [ -n "${{ inputs.with-artifact-path }}" ]; then + IFS=',' read -r -a artifacts <<< "${{ inputs.with-artifact-path }}" + artifacts_arg="" + echo "Artifacts to upload:" + for artifact in "${artifacts[@]}"; do + artifacts_arg+="artifacts/${artifact} " + ls -pAR artifacts/${artifacts} + done + gh release upload "v${{ inputs.version }}" $artifacts_arg --clobber --repo ${{ github.repository }} + fi - name: Update release (if already exists) if: steps.check_release.outputs.exists == 'true' @@ -87,7 +108,12 @@ jobs: echo "Release ${{ inputs.version }} already exists; updating assets..." if [ -n "${{ inputs.with-artifact-path }}" ]; then IFS=',' read -r -a artifacts <<< "${{ inputs.with-artifact-path }}" - artifacts_arg="artifacts/${artifacts[@]}" + artifacts_arg="" + echo "Artifacts to upload:" + for artifact in "${artifacts[@]}"; do + artifacts_arg="artifacts/${artifacts[@]}" + ls -pAR artifacts/${artifacts} + done gh release upload "v${{ inputs.version }}" $artifacts_arg --clobber --repo ${{ github.repository }} else echo "No artifact to upload" diff --git a/README.md b/README.md index cb235bc..e618dc9 100644 --- a/README.md +++ b/README.md @@ -82,8 +82,10 @@ Each workflow accepts specific inputs and secrets. See individual workflow files - `version`: Semantic version string - `artifact-name`: Name of the artifacts to produce - `artifact-path`: Path to files to upload as artifact -- `with-artifact-name`: Name of the artifacts to use +- `with-artifact-name`: Name of the artifacts to use, can't be used with `with-artifact-ids` +- `with-artifact-ids`: Comma separated list of Ids of the artifacts to use, can't be used with `with-artifact-name` - `with-artifact-path`: Path to files in artifact +- `with-artifact-unzip`: Which artifact to unzip during download. Comma separated list of names, Ids, true, false, or '*'. ## 📚 Examples diff --git a/docs/build-docker.md b/docs/build-docker.md index 0c453a7..041aa85 100644 --- a/docs/build-docker.md +++ b/docs/build-docker.md @@ -22,6 +22,6 @@ build-docker: working-directory: server tags: ${{ needs.generate-version-names.outputs.tags }} dockerfile: ci.Dockerfile - with-artifact-name: server + with-artifact-ids: ${{ needs.build.outputs.artifact-id }} with-artifact-path: build/libs/ ``` diff --git a/docs/build-springboot.md b/docs/build-springboot.md index 1b62fb7..9344a52 100644 --- a/docs/build-springboot.md +++ b/docs/build-springboot.md @@ -13,7 +13,7 @@ on: jobs: build: name: Build Spring Boot App - uses: shiipou/github-actions/.github/workflows/build-springboot.yml@main + uses: lenra-io/github-actions/.github/workflows/build-springboot.yml@main with: working-directory: server artifact-name: server diff --git a/docs/deploy-flutter.md b/docs/deploy-flutter.md index 2dd851c..9346b5d 100644 --- a/docs/deploy-flutter.md +++ b/docs/deploy-flutter.md @@ -5,7 +5,7 @@ It can deploy to multiple store : ```yml -deploy-playstore: + deploy-playstore: name: Deploy to PlayStore uses: lenra-io/github-actions/.github/workflows/deploy-flutter.yml@main with: @@ -27,6 +27,6 @@ deploy-playstore: secrets: appstore-username: ${{ secrets.appstore_username }} appstore-password: ${{ secrets.appstore_password }} - appstoore-apikey: ${{ secrets.appstore_apikey }} + appstore-apikey: ${{ secrets.appstore_apikey }} appstore-apiissuer: ${{ secrets.appstore_apiissuer }} ``` diff --git a/docs/test-springboot.md b/docs/test-springboot.md index e335239..3bd144d 100644 --- a/docs/test-springboot.md +++ b/docs/test-springboot.md @@ -13,7 +13,7 @@ on: jobs: test: name: Test Spring Boot App - uses: shiipou/github-actions/.github/workflows/test-springboot.yml@main + uses: lenra-io/github-actions/.github/workflows/test-springboot.yml@main with: artifact-name: coverage-report ```