`permissions` in a job are incorrectly flagged
I ran action-validator on my current publish.yml action, and got this output:
Validation failed: ValidationState {
action_type: Some(
Workflow,
),
file_path: Some(
"./.github/workflows/publish.yml",
),
errors: [
OneOf {
code: "one_of",
detail: None,
path: "/jobs/publish-to-pypi",
title: "OneOf conditions are not met",
states: [
ValidationState {
action_type: None,
file_path: None,
errors: [
OneOf {
code: "one_of",
detail: None,
path: "/jobs/publish-to-pypi/permissions",
title: "OneOf conditions are not met",
states: [
ValidationState {
action_type: None,
file_path: None,
errors: [
Enum {
code: "enum",
detail: None,
path: "/jobs/publish-to-pypi/permissions",
title: "Enum conditions are not met",
},
WrongType {
code: "wrong_type",
detail: Some(
"The value must be string",
),
path: "/jobs/publish-to-pypi/permissions",
title: "Type of the value is wrong",
},
],
},
ValidationState {
action_type: None,
file_path: None,
errors: [
Properties {
code: "properties",
detail: Some(
"Additional property 'attestations' is not allowed",
),
path: "/jobs/publish-to-pypi/permissions",
title: "Property conditions are not met",
},
],
},
],
},
],
},
ValidationState {
action_type: None,
file_path: None,
errors: [
Properties {
code: "properties",
detail: Some(
"Additional property 'environment' is not allowed",
),
path: "/jobs/publish-to-pypi",
title: "Property conditions are not met",
},
OneOf {
code: "one_of",
detail: None,
path: "/jobs/publish-to-pypi/permissions",
title: "OneOf conditions are not met",
states: [
ValidationState {
action_type: None,
file_path: None,
errors: [
Enum {
code: "enum",
detail: None,
path: "/jobs/publish-to-pypi/permissions",
title: "Enum conditions are not met",
},
WrongType {
code: "wrong_type",
detail: Some(
"The value must be string",
),
path: "/jobs/publish-to-pypi/permissions",
title: "Type of the value is wrong",
},
],
},
ValidationState {
action_type: None,
file_path: None,
errors: [
Properties {
code: "properties",
detail: Some(
"Additional property 'attestations' is not allowed",
),
path: "/jobs/publish-to-pypi/permissions",
title: "Property conditions are not met",
},
],
},
],
},
Properties {
code: "properties",
detail: Some(
"Additional property 'runs-on' is not allowed",
),
path: "/jobs/publish-to-pypi",
title: "Property conditions are not met",
},
Properties {
code: "properties",
detail: Some(
"Additional property 'steps' is not allowed",
),
path: "/jobs/publish-to-pypi",
title: "Property conditions are not met",
},
Required {
code: "required",
detail: None,
path: "/jobs/publish-to-pypi/uses",
title: "This property is required",
},
],
},
],
},
OneOf {
code: "one_of",
detail: None,
path: "/jobs/publish-to-test-pypi",
title: "OneOf conditions are not met",
states: [
ValidationState {
action_type: None,
file_path: None,
errors: [
OneOf {
code: "one_of",
detail: None,
path: "/jobs/publish-to-test-pypi/permissions",
title: "OneOf conditions are not met",
states: [
ValidationState {
action_type: None,
file_path: None,
errors: [
Enum {
code: "enum",
detail: None,
path: "/jobs/publish-to-test-pypi/permissions",
title: "Enum conditions are not met",
},
WrongType {
code: "wrong_type",
detail: Some(
"The value must be string",
),
path: "/jobs/publish-to-test-pypi/permissions",
title: "Type of the value is wrong",
},
],
},
ValidationState {
action_type: None,
file_path: None,
errors: [
Properties {
code: "properties",
detail: Some(
"Additional property 'attestations' is not allowed",
),
path: "/jobs/publish-to-test-pypi/permissions",
title: "Property conditions are not met",
},
],
},
],
},
],
},
ValidationState {
action_type: None,
file_path: None,
errors: [
Properties {
code: "properties",
detail: Some(
"Additional property 'environment' is not allowed",
),
path: "/jobs/publish-to-test-pypi",
title: "Property conditions are not met",
},
OneOf {
code: "one_of",
detail: None,
path: "/jobs/publish-to-test-pypi/permissions",
title: "OneOf conditions are not met",
states: [
ValidationState {
action_type: None,
file_path: None,
errors: [
Enum {
code: "enum",
detail: None,
path: "/jobs/publish-to-test-pypi/permissions",
title: "Enum conditions are not met",
},
WrongType {
code: "wrong_type",
detail: Some(
"The value must be string",
),
path: "/jobs/publish-to-test-pypi/permissions",
title: "Type of the value is wrong",
},
],
},
ValidationState {
action_type: None,
file_path: None,
errors: [
Properties {
code: "properties",
detail: Some(
"Additional property 'attestations' is not allowed",
),
path: "/jobs/publish-to-test-pypi/permissions",
title: "Property conditions are not met",
},
],
},
],
},
Properties {
code: "properties",
detail: Some(
"Additional property 'runs-on' is not allowed",
),
path: "/jobs/publish-to-test-pypi",
title: "Property conditions are not met",
},
Properties {
code: "properties",
detail: Some(
"Additional property 'steps' is not allowed",
),
path: "/jobs/publish-to-test-pypi",
title: "Property conditions are not met",
},
Required {
code: "required",
detail: None,
path: "/jobs/publish-to-test-pypi/uses",
title: "This property is required",
},
],
},
],
},
],
}
It seems to object to permissions in a job:
jobs:
publish-to-test-pypi:
name: "Publish to Test PyPI"
if: ${{ github.event.action == 'publish-testpypi' }}
permissions:
id-token: write
attestations: write
Am I misunderstanding the output? Job permissions are documented: https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#jobsjob_idpermissions
If I comment out the two places I use them, validation passes.
Well, first off, well done figuring out what the JSON schema validator output is actually talking about. :grin: My first thought was that this might be a newer feature than the version of the GitHub workflow schema that's embedded, but as best as I can tell, support for permissions was added a long, long time ago.
Are you able to reduce the bug to a minimal schema that I can easily drop into the test suite? That'll save me some faffing around, and make it easier for me to find the time and energy to dive into the depths of the schema and figure out what's going on.
It looks like attestations is the issue. This passes:
name: "Publish"
on:
push:
jobs:
publish-to-pypi:
name: foo
runs-on: ubuntu
permissions:
id-token: write
steps:
- uses: pypa/gh-action-pypi-publish
This fails:
name: "Publish"
on:
push:
jobs:
publish-to-pypi:
name: foo
runs-on: ubuntu
permissions:
attestations: write
steps:
- uses: pypa/gh-action-pypi-publish
Aha! You've cracked the case. That was added to the schema more recently than what we're currently using. A schema bump will fix this; PR if you like, or I'll get around to it soonish.
👋 hey! I've hit the same issue! :D
@mpalmer I'm going to bump the schemastore submodule and make a PR!
This was fixed by #96.