diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 237b3e24..9ff085f0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -11,12 +11,17 @@ permissions: jobs: goreleaser: + outputs: + hashes: ${{ steps.binary.outputs.hashes }} + image: ${{ steps.image.outputs.name }} + digest: ${{ steps.image.outputs.digest }} runs-on: ubuntu-latest permissions: contents: write packages: write # issues: write + # id-token: write steps: - uses: actions/checkout@v4 @@ -29,7 +34,9 @@ jobs: with: go-version: stable - - uses: goreleaser/goreleaser-action@v5 + - name: Run GoReleaser + id: goreleaser + uses: goreleaser/goreleaser-action@v5 with: # either 'goreleaser' (default) or 'goreleaser-pro': distribution: goreleaser @@ -37,3 +44,110 @@ jobs: args: release --clean env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Generate binary hashes + id: binary + env: + ARTIFACTS: "${{ steps.goreleaser.outputs.artifacts }}" + run: | + set -euo pipefail + + checksum_file=$(echo "$ARTIFACTS" | jq -r '.[] | select (.type=="Checksum") | .path') + echo "hashes=$(cat $checksum_file | base64 -w0)" >> "$GITHUB_OUTPUT" + + - name: Image digest + id: image + env: + ARTIFACTS: "${{ steps.goreleaser.outputs.artifacts }}" + run: | + set -euo pipefail + image_and_digest=$(echo "$ARTIFACTS" | jq -r '.[] | select (.type=="Docker Manifest") | .path') + image=$(echo "${image_and_digest}" | cut -d'@' -f1 | cut -d':' -f1) + digest=$(echo "${image_and_digest}" | cut -d'@' -f2) + echo "name=$image" >> "$GITHUB_OUTPUT" + echo "digest=$digest" >> "$GITHUB_OUTPUT" + + binary-provenance: + needs: [goreleaser] + permissions: + actions: read # To read the workflow path. + id-token: write # To sign the provenance. + contents: write # To add assets to a release. + uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v1.9.0 + with: + base64-subjects: "${{ needs.goreleaser.outputs.hashes }}" + upload-assets: true # upload to a new release + + image-provenance: + needs: [goreleaser] + permissions: + actions: read + id-token: write + packages: write + uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v1.9.0 + with: + image: ${{ needs.goreleaser.outputs.image }} + digest: ${{ needs.goreleaser.outputs.digest }} + registry-username: ${{ github.actor }} + secrets: + registry-password: ${{ secrets.GITHUB_TOKEN }} + + verification-with-slsa-verifier: + needs: [goreleaser, binary-provenance] + runs-on: ubuntu-latest + permissions: read-all + steps: + - name: Install the verifier + uses: slsa-framework/slsa-verifier/actions/installer@v2.4.0 + + - name: Download assets + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PROVENANCE: "${{ needs.binary-provenance.outputs.provenance-name }}" + run: | + set -euo pipefail + gh -R "$GITHUB_REPOSITORY" release download "$GITHUB_REF_NAME" -p "*.tar.gz" + # gh -R "$GITHUB_REPOSITORY" release download "$GITHUB_REF_NAME" -p "*.zip" + gh -R "$GITHUB_REPOSITORY" release download "$GITHUB_REF_NAME" -p "$PROVENANCE" + + - name: Verify assets + env: + CHECKSUMS: ${{ needs.goreleaser.outputs.hashes }} + PROVENANCE: "${{ needs.binary-provenance.outputs.provenance-name }}" + run: | + set -euo pipefail + checksums=$(echo "$CHECKSUMS" | base64 -d) + while read -r line; do + fn=$(echo $line | cut -d ' ' -f2) + echo "Verifying $fn" + slsa-verifier verify-artifact --provenance-path "$PROVENANCE" \ + --source-uri "github.com/$GITHUB_REPOSITORY" \ + --source-tag "$GITHUB_REF_NAME" \ + "$fn" + done <<<"$checksums" + + verification-with-cosign: + needs: [goreleaser, image-provenance] + runs-on: ubuntu-latest + permissions: read-all + steps: + - name: Login + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Install Cosign + uses: sigstore/cosign-installer@v3 + + - name: Verify image + env: + IMAGE: ${{ needs.goreleaser.outputs.image }} + DIGEST: ${{ needs.goreleaser.outputs.digest }} + run: | + cosign verify-attestation \ + --type slsaprovenance \ + --certificate-oidc-issuer https://token.actions.githubusercontent.com \ + --certificate-identity-regexp '^https://github.com/slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@refs/tags/v[0-9]+.[0-9]+.[0-9]+$' \ + $IMAGE@$DIGEST diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 67eb8571..c1707894 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -35,12 +35,14 @@ builds: flags: - -tags=b_tiny + - -trimpath overrides: - goarch: wasm goos: js flags: - -tags=b_tiny,b_norepl + - -trimpath archives: @@ -69,6 +71,8 @@ kos: # See https://goreleaser.com/customization/ko/ - linux/amd64 - linux/arm64 +snapshot: + name_template: "{{ incpatch .Version }}-next" changelog: # See https://goreleaser.com/customization/changelog/ use: github sort: asc diff --git a/evaldo/builtins.go b/evaldo/builtins.go index b4e9feef..515ecd02 100644 --- a/evaldo/builtins.go +++ b/evaldo/builtins.go @@ -4929,12 +4929,15 @@ var builtins = map[string]*env.Builtin{ switch secondBlock := arg1.(type) { case env.Block: mergedSlice := make([]env.Object, 0) - firtArgumentValue := s1 + // Initially fill first block data + for _, v := range s1.Data { + mergedSlice = append(mergedSlice, env.ToRyeValue(v)) + } // If isAvailable is false then it is new value isAvailable := false for _, v1 := range secondBlock.Series.S { isAvailable = false - for _, v2 := range firtArgumentValue.Data { + for _, v2 := range s1.Data { if env.RyeToRaw(v1) == v2 { isAvailable = true break @@ -4942,11 +4945,17 @@ var builtins = map[string]*env.Builtin{ } // If new value then add in List if !isAvailable { - s1.Data = append(s1.Data, env.RyeToRaw(v1)) + mergedSlice = append(mergedSlice, v1) } } - mergedSlice = append(mergedSlice, s1) - return *env.NewBlock(*env.NewTSeries(mergedSlice)) + // Create list of array + unionSlice := make([]any, 0, len(mergedSlice)) + for _, value := range mergedSlice { + unionSlice = append(unionSlice, value) + } + // return List + return *env.NewList(unionSlice) + default: return MakeArgError(ps, 2, []env.Type{env.BlockType}, "union") } @@ -4979,9 +4988,29 @@ var builtins = map[string]*env.Builtin{ default: return MakeArgError(ps, 2, []env.Type{env.BlockType}, "intersect") } - // TODO-FIX1 add for list + case env.List: + switch secondBlock := arg1.(type) { + case env.Block: + commonSlice := make([]env.Object, 0) + for _, v1 := range s1.Data { + for _, v2 := range secondBlock.Series.S { + // get matching value in both blocks + if env.RyeToRaw(v2) == v1 { + commonSlice = append(commonSlice, v2) + } + } + } + intersectSlice := make([]any, 0, len(commonSlice)) + for _, value := range commonSlice { + intersectSlice = append(intersectSlice, value) + } + // return List + return *env.NewList(intersectSlice) + default: + return MakeArgError(ps, 2, []env.Type{env.BlockType}, "intersect") + } default: - return MakeArgError(ps, 1, []env.Type{env.StringType, env.BlockType}, "intersect") + return MakeArgError(ps, 1, []env.Type{env.StringType, env.BlockType, env.ListType}, "intersect") } }, }, diff --git a/tests/structures.rye b/tests/structures.rye index 62512a55..915f023f 100644 --- a/tests/structures.rye +++ b/tests/structures.rye @@ -213,6 +213,11 @@ section "Working with blocks and lists" equal { union { 8 2 } { 1 9 } |length? } 4 ; sortorder isn't deterministic so far ... think if it should be equal { union { } { 1 9 } |length? } 2 equal { union { } { } } { } + + equal { union list { 1 2 } { 1 2 3 4 } } list { 1 2 3 4 } + equal { union list { 1 2 } { 1 } } list { 1 2 } + equal { union list { 1 2 } { } } list { 1 2 } + equal { union list { } { } } list { } } group "intersection" mold\nowrap ?intersection @@ -221,6 +226,10 @@ section "Working with blocks and lists" equal { intersection { 1 3 5 6 } { 2 3 4 5 } } { 3 5 } equal { intersection { } { 2 3 4 } } { } equal { intersection { } { } } { } + + equal { intersection list { 1 3 5 6 } { 2 3 4 5 } } list { 3 5 } + equal { intersection list { } { 2 3 4 } } list { } + equal { intersection list { } { } } list { } } group "unique" mold\nowrap ?append!