diff --git a/cargo-dist/src/backend/ci/github.rs b/cargo-dist/src/backend/ci/github.rs index 5b25d5f9e..f9a27647d 100644 --- a/cargo-dist/src/backend/ci/github.rs +++ b/cargo-dist/src/backend/ci/github.rs @@ -298,7 +298,7 @@ impl GithubCiInfo { } let mut root_permissions = GithubPermissionMap::new(); - root_permissions.insert("contents".to_owned(), GithubPermission::Write); + root_permissions.insert("contents".to_owned(), GithubPermission::Read); let mut publish_jobs = vec![]; if let Some(PublisherConfig { homebrew, npm, .. }) = &dist.global_publishers { @@ -491,7 +491,7 @@ impl GithubReleaseInfo { let mut release_args = vec![]; let action; // Always need to use the tag flag - release_args.push("\"${{ needs.plan.outputs.tag }}\""); + release_args.push("\"$RELEASE_TAG\""); // If using remote repos, specify the repo if github_releases_repo.is_some() { diff --git a/cargo-dist/templates/ci/github/partials/publish_github.yml.j2 b/cargo-dist/templates/ci/github/partials/publish_github.yml.j2 index 0bfbf0808..ef9b87347 100644 --- a/cargo-dist/templates/ci/github/partials/publish_github.yml.j2 +++ b/cargo-dist/templates/ci/github/partials/publish_github.yml.j2 @@ -34,13 +34,14 @@ {{%- else %}} RELEASE_COMMIT: "${{ github.sha }}" {{%- endif %}} + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | {{%- if create_release %}} # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" {{%- else %}} # If we're editing a release in place, we need to upload things ahead of time - gh release upload "${{ needs.plan.outputs.tag }}" artifacts/* + gh release upload "$RELEASE_TAG" artifacts/* {{%- endif %}} {{{ release_command|safe }}} diff --git a/cargo-dist/templates/ci/github/release.yml.j2 b/cargo-dist/templates/ci/github/release.yml.j2 index 785acdd98..35be54b64 100644 --- a/cargo-dist/templates/ci/github/release.yml.j2 +++ b/cargo-dist/templates/ci/github/release.yml.j2 @@ -95,16 +95,14 @@ jobs: outputs: val: ${{ steps.plan.outputs.manifest }} {{%- if dispatch_releases %}} - tag: ${{ (inputs.tag != 'dry-run' && inputs.tag) || '' }} - tag-flag: ${{ inputs.tag && inputs.tag != 'dry-run' && format('--tag={0}', inputs.tag) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ inputs.tag && inputs.tag != 'dry-run' }} {{%- elif release_branch %}} tag: ${{ steps.plan.outputs.tag }} - tag-flag: ${{ steps.plan.outputs.tag-flag }} + force-tag: ${{ steps.plan.outputs.force-tag }} publishing: ${{ !github.event.pull_request }} {{%- else %}} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} {{%- endif %}} env: @@ -128,25 +126,62 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + {{%- if dispatch_releases %}} + - id: tag + if: ${{ inputs.tag && inputs.tag != 'dry-run' }} + shell: bash + env: + REF_NAME: ${{ inputs.tag }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" + {{%- elif not release_branch %}} + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" + {{%- endif %}} # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist - {{%- if dispatch_releases %}} ${{ (inputs.tag && inputs.tag != 'dry-run' && format('host --steps=create --tag={0}', inputs.tag)) - {{%- elif release_branch %}} ${{ (!github.event.pull_request && 'host --steps=create --tag=timestamp --force-tag') - {{%- else %}} ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) + dist_args=() + {{%- if dispatch_releases %}} + if [[ -n "$DIST_TAG" ]]; then + dist_args+=(host --steps=create "--tag=$DIST_TAG") + else + dist_args+=(plan) + fi + {{%- elif release_branch %}} + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create --tag=timestamp --force-tag) + fi + {{%- else %}} + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi {{%- endif %}} - {{{- " || 'plan' }} --output-format=json > plan-dist-manifest.json" | safe }}} + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" {{%- if release_branch %}} - echo "tag=$(jq --raw-output ".announcement_tag" plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" - echo "tag-flag=--tag=$(jq --raw-output ".announcement_tag" plan-dist-manifest.json) --force-tag" >> "$GITHUB_OUTPUT" + tag="$(jq --raw-output ".announcement_tag" plan-dist-manifest.json)" + printf 'tag=%s\n' "$tag" >> "$GITHUB_OUTPUT" + printf 'force-tag=true\n' >> "$GITHUB_OUTPUT" {{%- endif %}} - name: "Upload dist-manifest.json" uses: {{{actions["actions/upload-artifact"] | safe }}} @@ -199,6 +234,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} {{%- if ssldotcom_windows_sign %}} SSLDOTCOM_USERNAME: ${{ secrets.SSLDOTCOM_USERNAME }} SSLDOTCOM_PASSWORD: ${{ secrets.SSLDOTCOM_PASSWORD }} @@ -316,9 +353,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" {{%- if github_attestations is defined and github_attestations and github_attestations_phase == "build-local-artifacts" %}} - name: Attest @@ -385,6 +430,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: {{{actions["actions/checkout"] | safe }}} with: @@ -424,7 +471,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json {{{ global_task.dist_args }}} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json {{{ global_task.dist_args }}} > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -483,6 +537,10 @@ jobs: {{%- endfor %}} # Determines if we should publish/announce host: + {{%- if "github" in hosting_providers and release_phase == "host" and not (github_attestations is defined and github_attestations and github_attestations_phase == "host") %}} + permissions: + "contents": "write" + {{%- endif %}} needs: - plan {{%- if build_local_artifacts %}} @@ -503,6 +561,8 @@ jobs: {{{- " }}" | safe }}} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: {{{ global_task.runner }}} outputs: val: ${{ steps.host.outputs.manifest }} @@ -540,7 +600,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -643,6 +710,10 @@ jobs: {{%- for job in user_publish_jobs %}} && (needs.custom-{{{ job.name|safe }}}.result == 'skipped' || needs.custom-{{{ job.name|safe }}}.result == 'success') {{%- endfor %}} {{{- " }}" | safe }}} runs-on: {{{ global_task.runner }}} + {{%- if "github" in hosting_providers and release_phase == "announce" and not (github_attestations is defined and github_attestations and github_attestations_phase == "announce") %}} + permissions: + "contents": "write" + {{%- endif %}} {{%- if github_attestations is defined and github_attestations and github_attestations_phase == "announce" %}} permissions: "attestations": "write" diff --git a/cargo-dist/tests/gallery/dist.rs b/cargo-dist/tests/gallery/dist.rs index c026d51aa..b9f7fb3bb 100644 --- a/cargo-dist/tests/gallery/dist.rs +++ b/cargo-dist/tests/gallery/dist.rs @@ -544,6 +544,29 @@ impl BuildAndPlanResult { impl GenerateResult { pub fn check_all(&self) -> Result { + self.check_release_tag_shell_safety()?; self.snapshot() } + + fn check_release_tag_shell_safety(&self) -> Result<()> { + let Some(github_ci_path) = self.github_ci_path.as_deref() else { + return Ok(()); + }; + let workflow = LocalAsset::load_string(github_ci_path)?; + for unsafe_pattern in [ + "format('--tag={0}'", + "needs.plan.outputs.tag-flag", + "dist ${{", + "dist build ${{", + "dist host ${{", + "gh release create \"${{ needs.plan.outputs.tag }}\"", + "gh release upload \"${{ needs.plan.outputs.tag }}\"", + ] { + assert!( + !workflow.contains(unsafe_pattern), + "generated GitHub workflow contains unsafe tag shell interpolation: {unsafe_pattern}" + ); + } + Ok(()) + } } diff --git a/cargo-dist/tests/snapshots/akaikatana_basic.snap b/cargo-dist/tests/snapshots/akaikatana_basic.snap index a97d81a49..606bd7fdf 100644 --- a/cargo-dist/tests/snapshots/akaikatana_basic.snap +++ b/cargo-dist/tests/snapshots/akaikatana_basic.snap @@ -2619,7 +2619,7 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push a git tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -2654,8 +2654,7 @@ jobs: runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -2676,14 +2675,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -2718,6 +2734,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - name: enable windows longpaths run: | @@ -2748,9 +2766,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - id: cargo-dist name: Post-build @@ -2782,6 +2808,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -2805,7 +2833,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -2823,6 +2858,8 @@ jobs: ${{ env.BUILD_MANIFEST_NAME }} # Determines if we should publish/announce host: + permissions: + "contents": "write" needs: - plan - build-local-artifacts @@ -2831,6 +2868,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -2857,7 +2896,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -2884,11 +2930,12 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* publish-homebrew-formula: needs: diff --git a/cargo-dist/tests/snapshots/akaikatana_bins.snap b/cargo-dist/tests/snapshots/akaikatana_bins.snap index 0fd517323..d344e018c 100644 --- a/cargo-dist/tests/snapshots/akaikatana_bins.snap +++ b/cargo-dist/tests/snapshots/akaikatana_bins.snap @@ -2613,7 +2613,7 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push a git tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -2648,8 +2648,7 @@ jobs: runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -2670,14 +2669,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -2712,6 +2728,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - name: enable windows longpaths run: | @@ -2742,9 +2760,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - id: cargo-dist name: Post-build @@ -2776,6 +2802,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -2799,7 +2827,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -2817,6 +2852,8 @@ jobs: ${{ env.BUILD_MANIFEST_NAME }} # Determines if we should publish/announce host: + permissions: + "contents": "write" needs: - plan - build-local-artifacts @@ -2825,6 +2862,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -2851,7 +2890,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -2878,11 +2924,12 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* publish-homebrew-formula: needs: diff --git a/cargo-dist/tests/snapshots/akaikatana_musl.snap b/cargo-dist/tests/snapshots/akaikatana_musl.snap index ece5cc1c9..abc49ca13 100644 --- a/cargo-dist/tests/snapshots/akaikatana_musl.snap +++ b/cargo-dist/tests/snapshots/akaikatana_musl.snap @@ -1926,7 +1926,7 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push a git tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -1961,8 +1961,7 @@ jobs: runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -1983,14 +1982,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -2025,6 +2041,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - name: enable windows longpaths run: | @@ -2055,9 +2073,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - id: cargo-dist name: Post-build @@ -2089,6 +2115,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -2112,7 +2140,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -2130,6 +2165,8 @@ jobs: ${{ env.BUILD_MANIFEST_NAME }} # Determines if we should publish/announce host: + permissions: + "contents": "write" needs: - plan - build-local-artifacts @@ -2138,6 +2175,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -2164,7 +2203,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -2191,11 +2237,12 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* announce: needs: diff --git a/cargo-dist/tests/snapshots/akaikatana_one_alias_among_many_binaries.snap b/cargo-dist/tests/snapshots/akaikatana_one_alias_among_many_binaries.snap index 181952b43..102d1e0db 100644 --- a/cargo-dist/tests/snapshots/akaikatana_one_alias_among_many_binaries.snap +++ b/cargo-dist/tests/snapshots/akaikatana_one_alias_among_many_binaries.snap @@ -2650,7 +2650,7 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push a git tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -2685,8 +2685,7 @@ jobs: runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -2707,14 +2706,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -2749,6 +2765,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - name: enable windows longpaths run: | @@ -2779,9 +2797,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - id: cargo-dist name: Post-build @@ -2813,6 +2839,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -2836,7 +2864,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -2854,6 +2889,8 @@ jobs: ${{ env.BUILD_MANIFEST_NAME }} # Determines if we should publish/announce host: + permissions: + "contents": "write" needs: - plan - build-local-artifacts @@ -2862,6 +2899,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -2888,7 +2927,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -2915,11 +2961,12 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* publish-homebrew-formula: needs: diff --git a/cargo-dist/tests/snapshots/akaikatana_two_bin_aliases.snap b/cargo-dist/tests/snapshots/akaikatana_two_bin_aliases.snap index 9297e84d6..fff4b14bd 100644 --- a/cargo-dist/tests/snapshots/akaikatana_two_bin_aliases.snap +++ b/cargo-dist/tests/snapshots/akaikatana_two_bin_aliases.snap @@ -2677,7 +2677,7 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push a git tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -2712,8 +2712,7 @@ jobs: runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -2734,14 +2733,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -2776,6 +2792,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - name: enable windows longpaths run: | @@ -2806,9 +2824,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - id: cargo-dist name: Post-build @@ -2840,6 +2866,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -2863,7 +2891,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -2881,6 +2916,8 @@ jobs: ${{ env.BUILD_MANIFEST_NAME }} # Determines if we should publish/announce host: + permissions: + "contents": "write" needs: - plan - build-local-artifacts @@ -2889,6 +2926,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -2915,7 +2954,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -2942,11 +2988,12 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* publish-homebrew-formula: needs: diff --git a/cargo-dist/tests/snapshots/akaikatana_updaters.snap b/cargo-dist/tests/snapshots/akaikatana_updaters.snap index 7f82c6f61..59845ea75 100644 --- a/cargo-dist/tests/snapshots/akaikatana_updaters.snap +++ b/cargo-dist/tests/snapshots/akaikatana_updaters.snap @@ -2663,7 +2663,7 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push a git tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -2698,8 +2698,7 @@ jobs: runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -2720,14 +2719,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -2762,6 +2778,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - name: enable windows longpaths run: | @@ -2792,9 +2810,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - id: cargo-dist name: Post-build @@ -2826,6 +2852,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -2849,7 +2877,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -2867,6 +2902,8 @@ jobs: ${{ env.BUILD_MANIFEST_NAME }} # Determines if we should publish/announce host: + permissions: + "contents": "write" needs: - plan - build-local-artifacts @@ -2875,6 +2912,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -2901,7 +2940,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -2928,11 +2974,12 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* publish-homebrew-formula: needs: diff --git a/cargo-dist/tests/snapshots/axolotlsay_action_commit.snap b/cargo-dist/tests/snapshots/axolotlsay_action_commit.snap index 53e7d8ec8..5c14dffca 100644 --- a/cargo-dist/tests/snapshots/axolotlsay_action_commit.snap +++ b/cargo-dist/tests/snapshots/axolotlsay_action_commit.snap @@ -4194,7 +4194,7 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push a git tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -4229,8 +4229,7 @@ jobs: runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -4249,14 +4248,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4291,6 +4307,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} permissions: "attestations": "write" "contents": "read" @@ -4327,9 +4345,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - name: Attest uses: actions/attest-build-provenance@34253426 @@ -4365,6 +4391,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@abcd1234 with: @@ -4386,7 +4414,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -4404,6 +4439,8 @@ jobs: ${{ env.BUILD_MANIFEST_NAME }} # Determines if we should publish/announce host: + permissions: + "contents": "write" needs: - plan - build-local-artifacts @@ -4412,6 +4449,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -4436,7 +4475,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4463,11 +4509,12 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* publish-homebrew-formula: needs: diff --git a/cargo-dist/tests/snapshots/axolotlsay_alias.snap b/cargo-dist/tests/snapshots/axolotlsay_alias.snap index 047bcd110..9e7196e36 100644 --- a/cargo-dist/tests/snapshots/axolotlsay_alias.snap +++ b/cargo-dist/tests/snapshots/axolotlsay_alias.snap @@ -4088,7 +4088,7 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push a git tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -4123,8 +4123,7 @@ jobs: runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -4143,14 +4142,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4185,6 +4201,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - name: enable windows longpaths run: | @@ -4213,9 +4231,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - id: cargo-dist name: Post-build @@ -4247,6 +4273,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -4268,7 +4296,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -4286,6 +4321,8 @@ jobs: ${{ env.BUILD_MANIFEST_NAME }} # Determines if we should publish/announce host: + permissions: + "contents": "write" needs: - plan - build-local-artifacts @@ -4294,6 +4331,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -4318,7 +4357,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4345,11 +4391,12 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* publish-homebrew-formula: needs: diff --git a/cargo-dist/tests/snapshots/axolotlsay_alias_ignores_missing_bins.snap b/cargo-dist/tests/snapshots/axolotlsay_alias_ignores_missing_bins.snap index 3717040ba..8d6687c2c 100644 --- a/cargo-dist/tests/snapshots/axolotlsay_alias_ignores_missing_bins.snap +++ b/cargo-dist/tests/snapshots/axolotlsay_alias_ignores_missing_bins.snap @@ -4090,7 +4090,7 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push a git tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -4125,8 +4125,7 @@ jobs: runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -4145,14 +4144,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4187,6 +4203,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - name: enable windows longpaths run: | @@ -4215,9 +4233,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - id: cargo-dist name: Post-build @@ -4249,6 +4275,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -4270,7 +4298,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -4288,6 +4323,8 @@ jobs: ${{ env.BUILD_MANIFEST_NAME }} # Determines if we should publish/announce host: + permissions: + "contents": "write" needs: - plan - build-local-artifacts @@ -4296,6 +4333,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -4320,7 +4359,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4347,11 +4393,12 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* publish-homebrew-formula: needs: diff --git a/cargo-dist/tests/snapshots/axolotlsay_attestations_announce.snap b/cargo-dist/tests/snapshots/axolotlsay_attestations_announce.snap index 3b73950b5..df9760ce7 100644 --- a/cargo-dist/tests/snapshots/axolotlsay_attestations_announce.snap +++ b/cargo-dist/tests/snapshots/axolotlsay_attestations_announce.snap @@ -4195,7 +4195,7 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push a git tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -4230,8 +4230,7 @@ jobs: runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -4250,14 +4249,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4292,6 +4308,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - name: enable windows longpaths run: | @@ -4320,9 +4338,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - id: cargo-dist name: Post-build @@ -4354,6 +4380,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -4375,7 +4403,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -4401,6 +4436,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -4426,7 +4463,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4556,8 +4600,9 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(needs.host.outputs.val).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(needs.host.outputs.val).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* diff --git a/cargo-dist/tests/snapshots/axolotlsay_attestations_filters.snap b/cargo-dist/tests/snapshots/axolotlsay_attestations_filters.snap index 75887bdee..4a330ce7d 100644 --- a/cargo-dist/tests/snapshots/axolotlsay_attestations_filters.snap +++ b/cargo-dist/tests/snapshots/axolotlsay_attestations_filters.snap @@ -4202,7 +4202,7 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push a git tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -4237,8 +4237,7 @@ jobs: runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -4257,14 +4256,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4299,6 +4315,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - name: enable windows longpaths run: | @@ -4327,9 +4345,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - id: cargo-dist name: Post-build @@ -4361,6 +4387,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -4382,7 +4410,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -4408,6 +4443,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -4436,7 +4473,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4472,11 +4516,12 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* publish-homebrew-formula: needs: diff --git a/cargo-dist/tests/snapshots/axolotlsay_attestations_host.snap b/cargo-dist/tests/snapshots/axolotlsay_attestations_host.snap index 4683607e5..d2dec1295 100644 --- a/cargo-dist/tests/snapshots/axolotlsay_attestations_host.snap +++ b/cargo-dist/tests/snapshots/axolotlsay_attestations_host.snap @@ -4195,7 +4195,7 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push a git tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -4230,8 +4230,7 @@ jobs: runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -4250,14 +4249,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4292,6 +4308,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - name: enable windows longpaths run: | @@ -4320,9 +4338,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - id: cargo-dist name: Post-build @@ -4354,6 +4380,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -4375,7 +4403,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -4401,6 +4436,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -4429,7 +4466,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4461,11 +4505,12 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* publish-homebrew-formula: needs: diff --git a/cargo-dist/tests/snapshots/axolotlsay_basic.snap b/cargo-dist/tests/snapshots/axolotlsay_basic.snap index fd3754575..03b103e9e 100644 --- a/cargo-dist/tests/snapshots/axolotlsay_basic.snap +++ b/cargo-dist/tests/snapshots/axolotlsay_basic.snap @@ -3973,7 +3973,7 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push a git tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -4008,8 +4008,7 @@ jobs: runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -4028,14 +4027,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4070,6 +4086,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - name: enable windows longpaths run: | @@ -4105,9 +4123,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - id: cargo-dist name: Post-build @@ -4139,6 +4165,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -4170,7 +4198,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -4202,6 +4237,8 @@ jobs: ${{ env.BUILD_MANIFEST_NAME }} # Determines if we should publish/announce host: + permissions: + "contents": "write" needs: - plan - build-local-artifacts @@ -4210,6 +4247,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -4234,7 +4273,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4261,11 +4307,12 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* publish-homebrew-formula: needs: diff --git a/cargo-dist/tests/snapshots/axolotlsay_basic_bins.snap b/cargo-dist/tests/snapshots/axolotlsay_basic_bins.snap index 8fc4ea868..3a5b4bad4 100644 --- a/cargo-dist/tests/snapshots/axolotlsay_basic_bins.snap +++ b/cargo-dist/tests/snapshots/axolotlsay_basic_bins.snap @@ -4327,7 +4327,7 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push a git tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -4362,8 +4362,7 @@ jobs: runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -4382,14 +4381,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4424,6 +4440,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - name: enable windows longpaths run: | @@ -4452,9 +4470,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - id: cargo-dist name: Post-build @@ -4486,6 +4512,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -4507,7 +4535,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -4525,6 +4560,8 @@ jobs: ${{ env.BUILD_MANIFEST_NAME }} # Determines if we should publish/announce host: + permissions: + "contents": "write" needs: - plan - build-local-artifacts @@ -4533,6 +4570,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -4557,7 +4596,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4584,11 +4630,12 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* publish-homebrew-formula: needs: diff --git a/cargo-dist/tests/snapshots/axolotlsay_basic_lies.snap b/cargo-dist/tests/snapshots/axolotlsay_basic_lies.snap index d72067e26..5b88e3187 100644 --- a/cargo-dist/tests/snapshots/axolotlsay_basic_lies.snap +++ b/cargo-dist/tests/snapshots/axolotlsay_basic_lies.snap @@ -4158,7 +4158,7 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push a git tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -4193,8 +4193,7 @@ jobs: runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -4213,14 +4212,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4255,6 +4271,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - name: enable windows longpaths run: | @@ -4283,9 +4301,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - id: cargo-dist name: Post-build @@ -4317,6 +4343,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -4338,7 +4366,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -4356,6 +4391,8 @@ jobs: ${{ env.BUILD_MANIFEST_NAME }} # Determines if we should publish/announce host: + permissions: + "contents": "write" needs: - plan - build-local-artifacts @@ -4364,6 +4401,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -4388,7 +4427,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4415,11 +4461,12 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* publish-homebrew-formula: needs: diff --git a/cargo-dist/tests/snapshots/axolotlsay_build_setup_steps.snap b/cargo-dist/tests/snapshots/axolotlsay_build_setup_steps.snap index 76499b387..56621d3b2 100644 --- a/cargo-dist/tests/snapshots/axolotlsay_build_setup_steps.snap +++ b/cargo-dist/tests/snapshots/axolotlsay_build_setup_steps.snap @@ -4055,7 +4055,7 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push a git tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -4090,8 +4090,7 @@ jobs: runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -4110,14 +4109,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4152,6 +4168,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - name: enable windows longpaths run: | @@ -4197,9 +4215,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - id: cargo-dist name: Post-build @@ -4231,6 +4257,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -4252,7 +4280,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -4270,6 +4305,8 @@ jobs: ${{ env.BUILD_MANIFEST_NAME }} # Determines if we should publish/announce host: + permissions: + "contents": "write" needs: - plan - build-local-artifacts @@ -4278,6 +4315,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -4302,7 +4341,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4329,11 +4375,12 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* publish-homebrew-formula: needs: diff --git a/cargo-dist/tests/snapshots/axolotlsay_checksum_blake2b.snap b/cargo-dist/tests/snapshots/axolotlsay_checksum_blake2b.snap index ccaf19dae..855db592e 100644 --- a/cargo-dist/tests/snapshots/axolotlsay_checksum_blake2b.snap +++ b/cargo-dist/tests/snapshots/axolotlsay_checksum_blake2b.snap @@ -1905,7 +1905,7 @@ download_binary_and_run_installer "$@" || exit 1 name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push a git tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -1940,8 +1940,7 @@ jobs: runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -1960,14 +1959,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -2002,6 +2018,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - name: enable windows longpaths run: | @@ -2030,9 +2048,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - id: cargo-dist name: Post-build @@ -2064,6 +2090,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -2085,7 +2113,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -2103,6 +2138,8 @@ jobs: ${{ env.BUILD_MANIFEST_NAME }} # Determines if we should publish/announce host: + permissions: + "contents": "write" needs: - plan - build-local-artifacts @@ -2111,6 +2148,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -2135,7 +2174,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -2162,11 +2208,12 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* announce: needs: diff --git a/cargo-dist/tests/snapshots/axolotlsay_checksum_blake2s.snap b/cargo-dist/tests/snapshots/axolotlsay_checksum_blake2s.snap index 687216c54..5c6dffebc 100644 --- a/cargo-dist/tests/snapshots/axolotlsay_checksum_blake2s.snap +++ b/cargo-dist/tests/snapshots/axolotlsay_checksum_blake2s.snap @@ -1905,7 +1905,7 @@ download_binary_and_run_installer "$@" || exit 1 name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push a git tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -1940,8 +1940,7 @@ jobs: runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -1960,14 +1959,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -2002,6 +2018,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - name: enable windows longpaths run: | @@ -2030,9 +2048,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - id: cargo-dist name: Post-build @@ -2064,6 +2090,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -2085,7 +2113,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -2103,6 +2138,8 @@ jobs: ${{ env.BUILD_MANIFEST_NAME }} # Determines if we should publish/announce host: + permissions: + "contents": "write" needs: - plan - build-local-artifacts @@ -2111,6 +2148,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -2135,7 +2174,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -2162,11 +2208,12 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* announce: needs: diff --git a/cargo-dist/tests/snapshots/axolotlsay_checksum_sha3_256.snap b/cargo-dist/tests/snapshots/axolotlsay_checksum_sha3_256.snap index 4bd412056..6c82f5a25 100644 --- a/cargo-dist/tests/snapshots/axolotlsay_checksum_sha3_256.snap +++ b/cargo-dist/tests/snapshots/axolotlsay_checksum_sha3_256.snap @@ -1905,7 +1905,7 @@ download_binary_and_run_installer "$@" || exit 1 name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push a git tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -1940,8 +1940,7 @@ jobs: runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -1960,14 +1959,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -2002,6 +2018,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - name: enable windows longpaths run: | @@ -2030,9 +2048,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - id: cargo-dist name: Post-build @@ -2064,6 +2090,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -2085,7 +2113,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -2103,6 +2138,8 @@ jobs: ${{ env.BUILD_MANIFEST_NAME }} # Determines if we should publish/announce host: + permissions: + "contents": "write" needs: - plan - build-local-artifacts @@ -2111,6 +2148,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -2135,7 +2174,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -2162,11 +2208,12 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* announce: needs: diff --git a/cargo-dist/tests/snapshots/axolotlsay_checksum_sha3_512.snap b/cargo-dist/tests/snapshots/axolotlsay_checksum_sha3_512.snap index c6abc2c42..1d8737515 100644 --- a/cargo-dist/tests/snapshots/axolotlsay_checksum_sha3_512.snap +++ b/cargo-dist/tests/snapshots/axolotlsay_checksum_sha3_512.snap @@ -1905,7 +1905,7 @@ download_binary_and_run_installer "$@" || exit 1 name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push a git tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -1940,8 +1940,7 @@ jobs: runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -1960,14 +1959,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -2002,6 +2018,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - name: enable windows longpaths run: | @@ -2030,9 +2048,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - id: cargo-dist name: Post-build @@ -2064,6 +2090,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -2085,7 +2113,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -2103,6 +2138,8 @@ jobs: ${{ env.BUILD_MANIFEST_NAME }} # Determines if we should publish/announce host: + permissions: + "contents": "write" needs: - plan - build-local-artifacts @@ -2111,6 +2148,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -2135,7 +2174,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -2162,11 +2208,12 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* announce: needs: diff --git a/cargo-dist/tests/snapshots/axolotlsay_cross1.snap b/cargo-dist/tests/snapshots/axolotlsay_cross1.snap index 4604d0a68..03df702b0 100644 --- a/cargo-dist/tests/snapshots/axolotlsay_cross1.snap +++ b/cargo-dist/tests/snapshots/axolotlsay_cross1.snap @@ -2742,7 +2742,7 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push a git tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -2777,8 +2777,7 @@ jobs: runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -2797,14 +2796,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -2839,6 +2855,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - name: enable windows longpaths run: | @@ -2867,9 +2885,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - id: cargo-dist name: Post-build @@ -2901,6 +2927,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -2922,7 +2950,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -2940,6 +2975,8 @@ jobs: ${{ env.BUILD_MANIFEST_NAME }} # Determines if we should publish/announce host: + permissions: + "contents": "write" needs: - plan - build-local-artifacts @@ -2948,6 +2985,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -2972,7 +3011,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -2999,11 +3045,12 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* announce: needs: diff --git a/cargo-dist/tests/snapshots/axolotlsay_cross2.snap b/cargo-dist/tests/snapshots/axolotlsay_cross2.snap index ae43c6dca..87d9f2cfa 100644 --- a/cargo-dist/tests/snapshots/axolotlsay_cross2.snap +++ b/cargo-dist/tests/snapshots/axolotlsay_cross2.snap @@ -2346,7 +2346,7 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push a git tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -2381,8 +2381,7 @@ jobs: runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -2401,14 +2400,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -2443,6 +2459,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - name: enable windows longpaths run: | @@ -2471,9 +2489,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - id: cargo-dist name: Post-build @@ -2505,6 +2531,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -2526,7 +2554,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -2544,6 +2579,8 @@ jobs: ${{ env.BUILD_MANIFEST_NAME }} # Determines if we should publish/announce host: + permissions: + "contents": "write" needs: - plan - build-local-artifacts @@ -2552,6 +2589,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -2576,7 +2615,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -2603,11 +2649,12 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* announce: needs: diff --git a/cargo-dist/tests/snapshots/axolotlsay_custom_formula.snap b/cargo-dist/tests/snapshots/axolotlsay_custom_formula.snap index cbfb770e1..272ef2a80 100644 --- a/cargo-dist/tests/snapshots/axolotlsay_custom_formula.snap +++ b/cargo-dist/tests/snapshots/axolotlsay_custom_formula.snap @@ -413,7 +413,7 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push to "production" on: @@ -433,7 +433,7 @@ jobs: outputs: val: ${{ steps.plan.outputs.manifest }} tag: ${{ steps.plan.outputs.tag }} - tag-flag: ${{ steps.plan.outputs.tag-flag }} + force-tag: ${{ steps.plan.outputs.force-tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -458,13 +458,24 @@ jobs: # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && 'host --steps=create --tag=timestamp --force-tag') || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create --tag=timestamp --force-tag) + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" - echo "tag=$(jq --raw-output ".announcement_tag" plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" - echo "tag-flag=--tag=$(jq --raw-output ".announcement_tag" plan-dist-manifest.json) --force-tag" >> "$GITHUB_OUTPUT" + tag="$(jq --raw-output ".announcement_tag" plan-dist-manifest.json)" + printf 'tag=%s\n' "$tag" >> "$GITHUB_OUTPUT" + printf 'force-tag=true\n' >> "$GITHUB_OUTPUT" - name: "Upload dist-manifest.json" uses: actions/upload-artifact@v7 with: @@ -496,6 +507,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - name: enable windows longpaths run: | @@ -528,9 +541,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - id: cargo-dist name: Post-build @@ -562,6 +583,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -583,7 +606,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -601,6 +631,8 @@ jobs: ${{ env.BUILD_MANIFEST_NAME }} # Determines if we should publish/announce host: + permissions: + "contents": "write" needs: - plan - build-local-artifacts @@ -609,6 +641,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -633,7 +667,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -660,11 +701,12 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* publish-homebrew-formula: needs: diff --git a/cargo-dist/tests/snapshots/axolotlsay_custom_github_runners.snap b/cargo-dist/tests/snapshots/axolotlsay_custom_github_runners.snap index a13875ece..9427f5f0c 100644 --- a/cargo-dist/tests/snapshots/axolotlsay_custom_github_runners.snap +++ b/cargo-dist/tests/snapshots/axolotlsay_custom_github_runners.snap @@ -337,7 +337,7 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push a git tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -372,8 +372,7 @@ jobs: runs-on: "buildjet-8vcpu-ubuntu-2204" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -392,14 +391,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -434,6 +450,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - name: enable windows longpaths run: | @@ -462,9 +480,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - id: cargo-dist name: Post-build @@ -496,6 +522,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -517,7 +545,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -535,6 +570,8 @@ jobs: ${{ env.BUILD_MANIFEST_NAME }} # Determines if we should publish/announce host: + permissions: + "contents": "write" needs: - plan - build-local-artifacts @@ -543,6 +580,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "buildjet-8vcpu-ubuntu-2204" outputs: val: ${{ steps.host.outputs.manifest }} @@ -567,7 +606,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -594,11 +640,12 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* announce: needs: diff --git a/cargo-dist/tests/snapshots/axolotlsay_disable_source_tarball.snap b/cargo-dist/tests/snapshots/axolotlsay_disable_source_tarball.snap index 0f636304e..82a4e9bf9 100644 --- a/cargo-dist/tests/snapshots/axolotlsay_disable_source_tarball.snap +++ b/cargo-dist/tests/snapshots/axolotlsay_disable_source_tarball.snap @@ -4043,7 +4043,7 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) axolotlsay-n name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push a git tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -4078,8 +4078,7 @@ jobs: runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -4098,14 +4097,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4140,6 +4156,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - name: enable windows longpaths run: | @@ -4168,9 +4186,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - id: cargo-dist name: Post-build @@ -4202,6 +4228,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -4223,7 +4251,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -4241,6 +4276,8 @@ jobs: ${{ env.BUILD_MANIFEST_NAME }} # Determines if we should publish/announce host: + permissions: + "contents": "write" needs: - plan - build-local-artifacts @@ -4249,6 +4286,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -4273,7 +4312,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4300,11 +4346,12 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* publish-homebrew-formula: needs: diff --git a/cargo-dist/tests/snapshots/axolotlsay_dispatch.snap b/cargo-dist/tests/snapshots/axolotlsay_dispatch.snap index b86b80d6a..6bd5a637f 100644 --- a/cargo-dist/tests/snapshots/axolotlsay_dispatch.snap +++ b/cargo-dist/tests/snapshots/axolotlsay_dispatch.snap @@ -335,7 +335,7 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you workflow_dispatch with a tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -374,8 +374,7 @@ jobs: runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ (inputs.tag != 'dry-run' && inputs.tag) || '' }} - tag-flag: ${{ inputs.tag && inputs.tag != 'dry-run' && format('--tag={0}', inputs.tag) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ inputs.tag && inputs.tag != 'dry-run' }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -394,14 +393,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ inputs.tag && inputs.tag != 'dry-run' }} + shell: bash + env: + REF_NAME: ${{ inputs.tag }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (inputs.tag && inputs.tag != 'dry-run' && format('host --steps=create --tag={0}', inputs.tag)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_args+=(host --steps=create "--tag=$DIST_TAG") + else + dist_args+=(plan) + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -436,6 +452,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - name: enable windows longpaths run: | @@ -464,9 +482,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - id: cargo-dist name: Post-build @@ -498,6 +524,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -519,7 +547,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -537,6 +572,8 @@ jobs: ${{ env.BUILD_MANIFEST_NAME }} # Determines if we should publish/announce host: + permissions: + "contents": "write" needs: - plan - build-local-artifacts @@ -545,6 +582,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -569,7 +608,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -596,11 +642,12 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* announce: needs: diff --git a/cargo-dist/tests/snapshots/axolotlsay_dist_url_override.snap b/cargo-dist/tests/snapshots/axolotlsay_dist_url_override.snap index 759ecafc7..7ad9aa950 100644 --- a/cargo-dist/tests/snapshots/axolotlsay_dist_url_override.snap +++ b/cargo-dist/tests/snapshots/axolotlsay_dist_url_override.snap @@ -2534,7 +2534,7 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push a git tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -2569,8 +2569,7 @@ jobs: runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -2589,14 +2588,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -2631,6 +2647,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - name: enable windows longpaths run: | @@ -2659,9 +2677,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - id: cargo-dist name: Post-build @@ -2693,6 +2719,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -2714,7 +2742,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -2732,6 +2767,8 @@ jobs: ${{ env.BUILD_MANIFEST_NAME }} # Determines if we should publish/announce host: + permissions: + "contents": "write" needs: - plan - build-local-artifacts @@ -2740,6 +2777,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -2764,7 +2803,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -2791,11 +2837,12 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* announce: needs: diff --git a/cargo-dist/tests/snapshots/axolotlsay_edit_existing.snap b/cargo-dist/tests/snapshots/axolotlsay_edit_existing.snap index 75da3e5ad..0d883b218 100644 --- a/cargo-dist/tests/snapshots/axolotlsay_edit_existing.snap +++ b/cargo-dist/tests/snapshots/axolotlsay_edit_existing.snap @@ -3977,7 +3977,7 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push a git tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -4012,8 +4012,7 @@ jobs: runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -4032,14 +4031,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4074,6 +4090,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - name: enable windows longpaths run: | @@ -4102,9 +4120,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - id: cargo-dist name: Post-build @@ -4136,6 +4162,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -4157,7 +4185,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -4175,6 +4210,8 @@ jobs: ${{ env.BUILD_MANIFEST_NAME }} # Determines if we should publish/announce host: + permissions: + "contents": "write" needs: - plan - build-local-artifacts @@ -4183,6 +4220,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -4207,7 +4246,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4232,11 +4278,12 @@ jobs: env: PRERELEASE_FLAG: "${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease && '--prerelease' || '' }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # If we're editing a release in place, we need to upload things ahead of time - gh release upload "${{ needs.plan.outputs.tag }}" artifacts/* + gh release upload "$RELEASE_TAG" artifacts/* - gh release edit "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --draft=false + gh release edit "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --draft=false publish-homebrew-formula: needs: diff --git a/cargo-dist/tests/snapshots/axolotlsay_generic_workspace_basic.snap b/cargo-dist/tests/snapshots/axolotlsay_generic_workspace_basic.snap index 773d38a4d..1a4ab7fbb 100644 --- a/cargo-dist/tests/snapshots/axolotlsay_generic_workspace_basic.snap +++ b/cargo-dist/tests/snapshots/axolotlsay_generic_workspace_basic.snap @@ -5088,7 +5088,7 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push a git tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -5123,8 +5123,7 @@ jobs: runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -5143,14 +5142,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -5185,6 +5201,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - name: enable windows longpaths run: | @@ -5217,9 +5235,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - id: cargo-dist name: Post-build @@ -5251,6 +5277,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -5272,7 +5300,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -5290,6 +5325,8 @@ jobs: ${{ env.BUILD_MANIFEST_NAME }} # Determines if we should publish/announce host: + permissions: + "contents": "write" needs: - plan - build-local-artifacts @@ -5298,6 +5335,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -5322,7 +5361,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -5349,11 +5395,12 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* publish-homebrew-formula: needs: diff --git a/cargo-dist/tests/snapshots/axolotlsay_homebrew_linux_only.snap b/cargo-dist/tests/snapshots/axolotlsay_homebrew_linux_only.snap index 46015438e..bafbb3e0f 100644 --- a/cargo-dist/tests/snapshots/axolotlsay_homebrew_linux_only.snap +++ b/cargo-dist/tests/snapshots/axolotlsay_homebrew_linux_only.snap @@ -219,7 +219,7 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push a git tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -254,8 +254,7 @@ jobs: runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -274,14 +273,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -316,6 +332,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - name: enable windows longpaths run: | @@ -344,9 +362,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - id: cargo-dist name: Post-build @@ -378,6 +404,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -399,7 +427,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -417,6 +452,8 @@ jobs: ${{ env.BUILD_MANIFEST_NAME }} # Determines if we should publish/announce host: + permissions: + "contents": "write" needs: - plan - build-local-artifacts @@ -425,6 +462,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -449,7 +488,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -476,11 +522,12 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* publish-homebrew-formula: needs: diff --git a/cargo-dist/tests/snapshots/axolotlsay_homebrew_macos_x86_64_only.snap b/cargo-dist/tests/snapshots/axolotlsay_homebrew_macos_x86_64_only.snap index 29490e97b..5663918f3 100644 --- a/cargo-dist/tests/snapshots/axolotlsay_homebrew_macos_x86_64_only.snap +++ b/cargo-dist/tests/snapshots/axolotlsay_homebrew_macos_x86_64_only.snap @@ -222,7 +222,7 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push a git tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -257,8 +257,7 @@ jobs: runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -277,14 +276,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -319,6 +335,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - name: enable windows longpaths run: | @@ -347,9 +365,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - id: cargo-dist name: Post-build @@ -381,6 +407,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -402,7 +430,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -420,6 +455,8 @@ jobs: ${{ env.BUILD_MANIFEST_NAME }} # Determines if we should publish/announce host: + permissions: + "contents": "write" needs: - plan - build-local-artifacts @@ -428,6 +465,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -452,7 +491,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -479,11 +525,12 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* publish-homebrew-formula: needs: diff --git a/cargo-dist/tests/snapshots/axolotlsay_homebrew_packages.snap b/cargo-dist/tests/snapshots/axolotlsay_homebrew_packages.snap index 02f66b7f6..892cb054e 100644 --- a/cargo-dist/tests/snapshots/axolotlsay_homebrew_packages.snap +++ b/cargo-dist/tests/snapshots/axolotlsay_homebrew_packages.snap @@ -4057,7 +4057,7 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push a git tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -4092,8 +4092,7 @@ jobs: runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -4112,14 +4111,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4154,6 +4170,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - name: enable windows longpaths run: | @@ -4182,9 +4200,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - id: cargo-dist name: Post-build @@ -4216,6 +4242,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -4237,7 +4265,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -4255,6 +4290,8 @@ jobs: ${{ env.BUILD_MANIFEST_NAME }} # Determines if we should publish/announce host: + permissions: + "contents": "write" needs: - plan - build-local-artifacts @@ -4263,6 +4300,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -4287,7 +4326,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4314,11 +4360,12 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* publish-homebrew-formula: needs: diff --git a/cargo-dist/tests/snapshots/axolotlsay_musl.snap b/cargo-dist/tests/snapshots/axolotlsay_musl.snap index 84d61853b..0c0981376 100644 --- a/cargo-dist/tests/snapshots/axolotlsay_musl.snap +++ b/cargo-dist/tests/snapshots/axolotlsay_musl.snap @@ -3276,7 +3276,7 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push a git tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -3311,8 +3311,7 @@ jobs: runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -3331,14 +3330,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -3373,6 +3389,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - name: enable windows longpaths run: | @@ -3401,9 +3419,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - id: cargo-dist name: Post-build @@ -3435,6 +3461,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -3456,7 +3484,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -3474,6 +3509,8 @@ jobs: ${{ env.BUILD_MANIFEST_NAME }} # Determines if we should publish/announce host: + permissions: + "contents": "write" needs: - plan - build-local-artifacts @@ -3482,6 +3519,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -3506,7 +3545,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -3533,11 +3579,12 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* announce: needs: diff --git a/cargo-dist/tests/snapshots/axolotlsay_musl_no_gnu.snap b/cargo-dist/tests/snapshots/axolotlsay_musl_no_gnu.snap index 73ee9da13..edf16d294 100644 --- a/cargo-dist/tests/snapshots/axolotlsay_musl_no_gnu.snap +++ b/cargo-dist/tests/snapshots/axolotlsay_musl_no_gnu.snap @@ -3198,7 +3198,7 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push a git tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -3233,8 +3233,7 @@ jobs: runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -3253,14 +3252,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -3295,6 +3311,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - name: enable windows longpaths run: | @@ -3323,9 +3341,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - id: cargo-dist name: Post-build @@ -3357,6 +3383,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -3378,7 +3406,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -3396,6 +3431,8 @@ jobs: ${{ env.BUILD_MANIFEST_NAME }} # Determines if we should publish/announce host: + permissions: + "contents": "write" needs: - plan - build-local-artifacts @@ -3404,6 +3441,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -3428,7 +3467,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -3455,11 +3501,12 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* announce: needs: diff --git a/cargo-dist/tests/snapshots/axolotlsay_no_homebrew_publish.snap b/cargo-dist/tests/snapshots/axolotlsay_no_homebrew_publish.snap index f73dcb021..182a8f771 100644 --- a/cargo-dist/tests/snapshots/axolotlsay_no_homebrew_publish.snap +++ b/cargo-dist/tests/snapshots/axolotlsay_no_homebrew_publish.snap @@ -3977,7 +3977,7 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push a git tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -4012,8 +4012,7 @@ jobs: runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -4032,14 +4031,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4074,6 +4090,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - name: enable windows longpaths run: | @@ -4106,9 +4124,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - id: cargo-dist name: Post-build @@ -4140,6 +4166,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -4161,7 +4189,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -4179,6 +4214,8 @@ jobs: ${{ env.BUILD_MANIFEST_NAME }} # Determines if we should publish/announce host: + permissions: + "contents": "write" needs: - plan - build-local-artifacts @@ -4187,6 +4224,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -4211,7 +4250,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4238,11 +4284,12 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* announce: needs: diff --git a/cargo-dist/tests/snapshots/axolotlsay_no_locals.snap b/cargo-dist/tests/snapshots/axolotlsay_no_locals.snap index 1a28f0e42..c2c125f96 100644 --- a/cargo-dist/tests/snapshots/axolotlsay_no_locals.snap +++ b/cargo-dist/tests/snapshots/axolotlsay_no_locals.snap @@ -335,7 +335,7 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push a git tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -370,8 +370,7 @@ jobs: runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -390,14 +389,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -415,6 +431,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -436,7 +454,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -454,6 +479,8 @@ jobs: ${{ env.BUILD_MANIFEST_NAME }} # Determines if we should publish/announce host: + permissions: + "contents": "write" needs: - plan - build-global-artifacts @@ -461,6 +488,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -485,7 +514,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -516,11 +552,12 @@ jobs: # We need to ensure `gh` uses the token that can auth # to the external repo instead of the runner token. GH_TOKEN: ${{ secrets.GH_RELEASES_TOKEN }} + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --repo "$REPO" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --repo "$REPO" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* announce: needs: diff --git a/cargo-dist/tests/snapshots/axolotlsay_no_locals_but_custom.snap b/cargo-dist/tests/snapshots/axolotlsay_no_locals_but_custom.snap index 60175c087..fed094ee5 100644 --- a/cargo-dist/tests/snapshots/axolotlsay_no_locals_but_custom.snap +++ b/cargo-dist/tests/snapshots/axolotlsay_no_locals_but_custom.snap @@ -335,7 +335,7 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push to "production" on: @@ -355,7 +355,7 @@ jobs: outputs: val: ${{ steps.plan.outputs.manifest }} tag: ${{ steps.plan.outputs.tag }} - tag-flag: ${{ steps.plan.outputs.tag-flag }} + force-tag: ${{ steps.plan.outputs.force-tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -380,13 +380,24 @@ jobs: # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && 'host --steps=create --tag=timestamp --force-tag') || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create --tag=timestamp --force-tag) + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" - echo "tag=$(jq --raw-output ".announcement_tag" plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" - echo "tag-flag=--tag=$(jq --raw-output ".announcement_tag" plan-dist-manifest.json) --force-tag" >> "$GITHUB_OUTPUT" + tag="$(jq --raw-output ".announcement_tag" plan-dist-manifest.json)" + printf 'tag=%s\n' "$tag" >> "$GITHUB_OUTPUT" + printf 'force-tag=true\n' >> "$GITHUB_OUTPUT" - name: "Upload dist-manifest.json" uses: actions/upload-artifact@v7 with: @@ -413,6 +424,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -434,7 +447,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -452,6 +472,8 @@ jobs: ${{ env.BUILD_MANIFEST_NAME }} # Determines if we should publish/announce host: + permissions: + "contents": "write" needs: - plan - custom-local-artifacts @@ -460,6 +482,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.custom-local-artifacts.result == 'skipped' || needs.custom-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -484,7 +508,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -511,11 +542,12 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* announce: needs: diff --git a/cargo-dist/tests/snapshots/axolotlsay_several_aliases.snap b/cargo-dist/tests/snapshots/axolotlsay_several_aliases.snap index bddec44f0..b63752e5d 100644 --- a/cargo-dist/tests/snapshots/axolotlsay_several_aliases.snap +++ b/cargo-dist/tests/snapshots/axolotlsay_several_aliases.snap @@ -4094,7 +4094,7 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push a git tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -4129,8 +4129,7 @@ jobs: runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -4149,14 +4148,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4191,6 +4207,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - name: enable windows longpaths run: | @@ -4219,9 +4237,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - id: cargo-dist name: Post-build @@ -4253,6 +4279,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -4274,7 +4302,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -4292,6 +4327,8 @@ jobs: ${{ env.BUILD_MANIFEST_NAME }} # Determines if we should publish/announce host: + permissions: + "contents": "write" needs: - plan - build-local-artifacts @@ -4300,6 +4337,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -4324,7 +4363,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4351,11 +4397,12 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* publish-homebrew-formula: needs: diff --git a/cargo-dist/tests/snapshots/axolotlsay_simple_and_order1.snap b/cargo-dist/tests/snapshots/axolotlsay_simple_and_order1.snap index 2180bb198..e2719129f 100644 --- a/cargo-dist/tests/snapshots/axolotlsay_simple_and_order1.snap +++ b/cargo-dist/tests/snapshots/axolotlsay_simple_and_order1.snap @@ -4312,7 +4312,7 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push a git tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -4347,8 +4347,7 @@ jobs: runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -4367,14 +4366,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4409,6 +4425,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - name: enable windows longpaths run: | @@ -4437,9 +4455,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - id: cargo-dist name: Post-build @@ -4471,6 +4497,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -4492,7 +4520,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -4510,6 +4545,8 @@ jobs: ${{ env.BUILD_MANIFEST_NAME }} # Determines if we should publish/announce host: + permissions: + "contents": "write" needs: - plan - build-local-artifacts @@ -4518,6 +4555,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -4542,7 +4581,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4569,11 +4615,12 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* publish-homebrew-formula: needs: diff --git a/cargo-dist/tests/snapshots/axolotlsay_simple_and_order2.snap b/cargo-dist/tests/snapshots/axolotlsay_simple_and_order2.snap index 4bfa4d168..26fa3301e 100644 --- a/cargo-dist/tests/snapshots/axolotlsay_simple_and_order2.snap +++ b/cargo-dist/tests/snapshots/axolotlsay_simple_and_order2.snap @@ -4312,7 +4312,7 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push a git tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -4347,8 +4347,7 @@ jobs: runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -4367,14 +4366,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4409,6 +4425,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - name: enable windows longpaths run: | @@ -4437,9 +4455,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - id: cargo-dist name: Post-build @@ -4471,6 +4497,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -4492,7 +4520,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -4510,6 +4545,8 @@ jobs: ${{ env.BUILD_MANIFEST_NAME }} # Determines if we should publish/announce host: + permissions: + "contents": "write" needs: - plan - build-local-artifacts @@ -4518,6 +4555,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -4542,7 +4581,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4569,11 +4615,12 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* publish-homebrew-formula: needs: diff --git a/cargo-dist/tests/snapshots/axolotlsay_simple_and_order_no_github.snap b/cargo-dist/tests/snapshots/axolotlsay_simple_and_order_no_github.snap index 7dc8e830b..5ef22407e 100644 --- a/cargo-dist/tests/snapshots/axolotlsay_simple_and_order_no_github.snap +++ b/cargo-dist/tests/snapshots/axolotlsay_simple_and_order_no_github.snap @@ -4306,7 +4306,7 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push a git tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -4341,8 +4341,7 @@ jobs: runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -4361,14 +4360,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4403,6 +4419,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - name: enable windows longpaths run: | @@ -4431,9 +4449,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - id: cargo-dist name: Post-build @@ -4465,6 +4491,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -4486,7 +4514,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -4504,6 +4539,8 @@ jobs: ${{ env.BUILD_MANIFEST_NAME }} # Determines if we should publish/announce host: + permissions: + "contents": "write" needs: - plan - build-local-artifacts @@ -4512,6 +4549,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -4536,7 +4575,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4563,11 +4609,12 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* publish-homebrew-formula: needs: diff --git a/cargo-dist/tests/snapshots/axolotlsay_simple_only.snap b/cargo-dist/tests/snapshots/axolotlsay_simple_only.snap index e62f5f4a4..f90b379c7 100644 --- a/cargo-dist/tests/snapshots/axolotlsay_simple_only.snap +++ b/cargo-dist/tests/snapshots/axolotlsay_simple_only.snap @@ -4308,7 +4308,7 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push a git tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -4343,8 +4343,7 @@ jobs: runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -4363,14 +4362,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4405,6 +4421,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - name: enable windows longpaths run: | @@ -4433,9 +4451,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - id: cargo-dist name: Post-build @@ -4467,6 +4493,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -4488,7 +4516,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -4506,6 +4541,8 @@ jobs: ${{ env.BUILD_MANIFEST_NAME }} # Determines if we should publish/announce host: + permissions: + "contents": "write" needs: - plan - build-local-artifacts @@ -4514,6 +4551,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -4538,7 +4577,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4565,11 +4611,12 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* publish-homebrew-formula: needs: diff --git a/cargo-dist/tests/snapshots/axolotlsay_ssldotcom_windows_sign.snap b/cargo-dist/tests/snapshots/axolotlsay_ssldotcom_windows_sign.snap index 0614dde21..48c240154 100644 --- a/cargo-dist/tests/snapshots/axolotlsay_ssldotcom_windows_sign.snap +++ b/cargo-dist/tests/snapshots/axolotlsay_ssldotcom_windows_sign.snap @@ -2612,7 +2612,7 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push a git tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -2647,8 +2647,7 @@ jobs: runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -2667,14 +2666,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -2709,6 +2725,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} SSLDOTCOM_USERNAME: ${{ secrets.SSLDOTCOM_USERNAME }} SSLDOTCOM_PASSWORD: ${{ secrets.SSLDOTCOM_PASSWORD }} SSLDOTCOM_CREDENTIAL_ID: ${{ secrets.SSLDOTCOM_CREDENTIAL_ID }} @@ -2741,9 +2759,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - id: cargo-dist name: Post-build @@ -2775,6 +2801,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -2796,7 +2824,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -2814,6 +2849,8 @@ jobs: ${{ env.BUILD_MANIFEST_NAME }} # Determines if we should publish/announce host: + permissions: + "contents": "write" needs: - plan - build-local-artifacts @@ -2822,6 +2859,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -2846,7 +2885,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -2873,11 +2919,12 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* announce: needs: diff --git a/cargo-dist/tests/snapshots/axolotlsay_ssldotcom_windows_sign_prod.snap b/cargo-dist/tests/snapshots/axolotlsay_ssldotcom_windows_sign_prod.snap index 0614dde21..48c240154 100644 --- a/cargo-dist/tests/snapshots/axolotlsay_ssldotcom_windows_sign_prod.snap +++ b/cargo-dist/tests/snapshots/axolotlsay_ssldotcom_windows_sign_prod.snap @@ -2612,7 +2612,7 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push a git tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -2647,8 +2647,7 @@ jobs: runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -2667,14 +2666,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -2709,6 +2725,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} SSLDOTCOM_USERNAME: ${{ secrets.SSLDOTCOM_USERNAME }} SSLDOTCOM_PASSWORD: ${{ secrets.SSLDOTCOM_PASSWORD }} SSLDOTCOM_CREDENTIAL_ID: ${{ secrets.SSLDOTCOM_CREDENTIAL_ID }} @@ -2741,9 +2759,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - id: cargo-dist name: Post-build @@ -2775,6 +2801,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -2796,7 +2824,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -2814,6 +2849,8 @@ jobs: ${{ env.BUILD_MANIFEST_NAME }} # Determines if we should publish/announce host: + permissions: + "contents": "write" needs: - plan - build-local-artifacts @@ -2822,6 +2859,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -2846,7 +2885,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -2873,11 +2919,12 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* announce: needs: diff --git a/cargo-dist/tests/snapshots/axolotlsay_tag_namespace.snap b/cargo-dist/tests/snapshots/axolotlsay_tag_namespace.snap index 70b62d5d7..ac68eb1b2 100644 --- a/cargo-dist/tests/snapshots/axolotlsay_tag_namespace.snap +++ b/cargo-dist/tests/snapshots/axolotlsay_tag_namespace.snap @@ -335,7 +335,7 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push a git tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -370,8 +370,7 @@ jobs: runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -390,14 +389,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -432,6 +448,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - name: enable windows longpaths run: | @@ -460,9 +478,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - id: cargo-dist name: Post-build @@ -494,6 +520,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -515,7 +543,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -533,6 +568,8 @@ jobs: ${{ env.BUILD_MANIFEST_NAME }} # Determines if we should publish/announce host: + permissions: + "contents": "write" needs: - plan - build-local-artifacts @@ -541,6 +578,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -565,7 +604,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -592,11 +638,12 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* announce: needs: diff --git a/cargo-dist/tests/snapshots/axolotlsay_updaters.snap b/cargo-dist/tests/snapshots/axolotlsay_updaters.snap index 099e63f73..220b0062c 100644 --- a/cargo-dist/tests/snapshots/axolotlsay_updaters.snap +++ b/cargo-dist/tests/snapshots/axolotlsay_updaters.snap @@ -4099,7 +4099,7 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push a git tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -4134,8 +4134,7 @@ jobs: runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -4154,14 +4153,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4196,6 +4212,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - name: enable windows longpaths run: | @@ -4224,9 +4242,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - id: cargo-dist name: Post-build @@ -4258,6 +4284,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -4279,7 +4307,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -4297,6 +4332,8 @@ jobs: ${{ env.BUILD_MANIFEST_NAME }} # Determines if we should publish/announce host: + permissions: + "contents": "write" needs: - plan - build-local-artifacts @@ -4305,6 +4342,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -4329,7 +4368,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4356,11 +4402,12 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* publish-homebrew-formula: needs: diff --git a/cargo-dist/tests/snapshots/axolotlsay_user_global_build_job.snap b/cargo-dist/tests/snapshots/axolotlsay_user_global_build_job.snap index 307a34618..741387a04 100644 --- a/cargo-dist/tests/snapshots/axolotlsay_user_global_build_job.snap +++ b/cargo-dist/tests/snapshots/axolotlsay_user_global_build_job.snap @@ -3977,7 +3977,7 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push a git tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -4012,8 +4012,7 @@ jobs: runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -4032,14 +4031,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4074,6 +4090,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - name: enable windows longpaths run: | @@ -4102,9 +4120,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - id: cargo-dist name: Post-build @@ -4136,6 +4162,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -4157,7 +4185,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -4193,6 +4228,8 @@ jobs: secrets: inherit # Determines if we should publish/announce host: + permissions: + "contents": "write" needs: - plan - build-local-artifacts @@ -4203,6 +4240,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.custom-my-plan-job-1.result == 'skipped' || needs.custom-my-plan-job-1.result == 'success') && (needs.custom-my-plan-job-2.result == 'skipped' || needs.custom-my-plan-job-2.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -4227,7 +4266,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4254,11 +4300,12 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* publish-homebrew-formula: needs: diff --git a/cargo-dist/tests/snapshots/axolotlsay_user_host_job.snap b/cargo-dist/tests/snapshots/axolotlsay_user_host_job.snap index 6cd17d4a0..d8e1f83fb 100644 --- a/cargo-dist/tests/snapshots/axolotlsay_user_host_job.snap +++ b/cargo-dist/tests/snapshots/axolotlsay_user_host_job.snap @@ -3977,7 +3977,7 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push a git tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -4012,8 +4012,7 @@ jobs: runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -4032,14 +4031,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4074,6 +4090,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - name: enable windows longpaths run: | @@ -4102,9 +4120,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - id: cargo-dist name: Post-build @@ -4136,6 +4162,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -4157,7 +4185,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -4175,6 +4210,8 @@ jobs: ${{ env.BUILD_MANIFEST_NAME }} # Determines if we should publish/announce host: + permissions: + "contents": "write" needs: - plan - build-local-artifacts @@ -4183,6 +4220,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -4207,7 +4246,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4234,11 +4280,12 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* custom-my-plan-job-1: needs: diff --git a/cargo-dist/tests/snapshots/axolotlsay_user_local_build_job.snap b/cargo-dist/tests/snapshots/axolotlsay_user_local_build_job.snap index 195276142..4e1aef302 100644 --- a/cargo-dist/tests/snapshots/axolotlsay_user_local_build_job.snap +++ b/cargo-dist/tests/snapshots/axolotlsay_user_local_build_job.snap @@ -3977,7 +3977,7 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push a git tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -4012,8 +4012,7 @@ jobs: runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -4032,14 +4031,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4074,6 +4090,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - name: enable windows longpaths run: | @@ -4102,9 +4120,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - id: cargo-dist name: Post-build @@ -4156,6 +4182,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -4177,7 +4205,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -4195,6 +4230,8 @@ jobs: ${{ env.BUILD_MANIFEST_NAME }} # Determines if we should publish/announce host: + permissions: + "contents": "write" needs: - plan - build-local-artifacts @@ -4205,6 +4242,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') && (needs.custom-my-plan-job-1.result == 'skipped' || needs.custom-my-plan-job-1.result == 'success') && (needs.custom-my-plan-job-2.result == 'skipped' || needs.custom-my-plan-job-2.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -4229,7 +4268,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4256,11 +4302,12 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* publish-homebrew-formula: needs: diff --git a/cargo-dist/tests/snapshots/axolotlsay_user_plan_job.snap b/cargo-dist/tests/snapshots/axolotlsay_user_plan_job.snap index dd8a1d9fa..3d57524ce 100644 --- a/cargo-dist/tests/snapshots/axolotlsay_user_plan_job.snap +++ b/cargo-dist/tests/snapshots/axolotlsay_user_plan_job.snap @@ -3977,7 +3977,7 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push a git tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -4012,8 +4012,7 @@ jobs: runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -4032,14 +4031,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4084,6 +4100,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - name: enable windows longpaths run: | @@ -4116,9 +4134,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - id: cargo-dist name: Post-build @@ -4150,6 +4176,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -4171,7 +4199,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -4189,6 +4224,8 @@ jobs: ${{ env.BUILD_MANIFEST_NAME }} # Determines if we should publish/announce host: + permissions: + "contents": "write" needs: - plan - build-local-artifacts @@ -4197,6 +4234,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -4221,7 +4260,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4248,11 +4294,12 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* publish-homebrew-formula: needs: diff --git a/cargo-dist/tests/snapshots/axolotlsay_user_publish_job.snap b/cargo-dist/tests/snapshots/axolotlsay_user_publish_job.snap index 158152faf..d597fe35a 100644 --- a/cargo-dist/tests/snapshots/axolotlsay_user_publish_job.snap +++ b/cargo-dist/tests/snapshots/axolotlsay_user_publish_job.snap @@ -3977,7 +3977,7 @@ CENSORED (see https://github.com/axodotdev/cargo-dist/issues/1477) source.tar.g name: Release permissions: - "contents": "write" + "contents": "read" # This task will run whenever you push a git tag that looks like a version # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. @@ -4012,8 +4012,7 @@ jobs: runs-on: "ubuntu-22.04" outputs: val: ${{ steps.plan.outputs.manifest }} - tag: ${{ !github.event.pull_request && github.ref_name || '' }} - tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + tag: ${{ steps.tag.outputs.tag }} publishing: ${{ !github.event.pull_request }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -4032,14 +4031,31 @@ jobs: with: name: cargo-dist-cache path: ~/.cargo/bin/dist + - id: tag + if: ${{ !github.event.pull_request }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + run: | + printf 'tag=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT" # sure would be cool if github gave us proper conditionals... # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible # functionality based on whether this is a pull_request, and whether it's from a fork. # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* # but also really annoying to build CI around when it needs secrets to work right.) - id: plan + shell: bash + env: + IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }} + DIST_TAG: ${{ steps.tag.outputs.tag }} run: | - dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + dist_args=() + if [[ "$IS_PULL_REQUEST" == "true" ]]; then + dist_args+=(plan) + else + dist_args+=(host --steps=create "--tag=$DIST_TAG") + fi + dist "${dist_args[@]}" --output-format=json > plan-dist-manifest.json echo "dist ran successfully" cat plan-dist-manifest.json echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4074,6 +4090,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - name: enable windows longpaths run: | @@ -4102,9 +4120,17 @@ jobs: run: | ${{ matrix.packages_install }} - name: Build artifacts + shell: bash run: | # Actually do builds and make zips and whatnot - dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json echo "dist ran successfully" - id: cargo-dist name: Post-build @@ -4136,6 +4162,8 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} steps: - uses: actions/checkout@v6 with: @@ -4157,7 +4185,14 @@ jobs: - id: cargo-dist shell: bash run: | - dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist build "${dist_tag_args[@]}" --output-format=json "--artifacts=global" > dist-manifest.json echo "dist ran successfully" # Parse out what we just built and upload it to scratch storage @@ -4175,6 +4210,8 @@ jobs: ${{ env.BUILD_MANIFEST_NAME }} # Determines if we should publish/announce host: + permissions: + "contents": "write" needs: - plan - build-local-artifacts @@ -4183,6 +4220,8 @@ jobs: if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DIST_TAG: ${{ needs.plan.outputs.tag }} + DIST_FORCE_TAG: ${{ needs.plan.outputs.force-tag }} runs-on: "ubuntu-22.04" outputs: val: ${{ steps.host.outputs.manifest }} @@ -4207,7 +4246,14 @@ jobs: - id: host shell: bash run: | - dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + dist_tag_args=() + if [[ -n "$DIST_TAG" ]]; then + dist_tag_args+=("--tag=$DIST_TAG") + fi + if [[ "$DIST_FORCE_TAG" == "true" ]]; then + dist_tag_args+=(--force-tag) + fi + dist host "${dist_tag_args[@]}" --steps=upload --steps=release --output-format=json > dist-manifest.json echo "artifacts uploaded and released successfully" cat dist-manifest.json echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" @@ -4234,11 +4280,12 @@ jobs: ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" RELEASE_COMMIT: "${{ github.sha }}" + RELEASE_TAG: ${{ needs.plan.outputs.tag }} run: | # Write and read notes from a file to avoid quoting breaking things - echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + printf '%s' "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" - gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* + gh release create "$RELEASE_TAG" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* publish-homebrew-formula: needs: